Ответ 1
как насчет этого...
$original = new DateTime("now", new DateTimeZone('UTC'));
$timezoneName = timezone_name_from_abbr("", 3*3600, false);
$modified = $original->setTimezone(new DateTimezone($timezoneName));
Использование javascript Я знаю, что часовой пояс моих пользователей - UTC +3.
Теперь я хочу создать объект DateTime с этими знаниями:
$usersNow = new DateTime('now', new DateTimeZone("+3"));
Я получаю как респондент:
'Unknown or bad timezone (+2)'
Что я делаю неправильно? Как я могу исправить?
как насчет этого...
$original = new DateTime("now", new DateTimeZone('UTC'));
$timezoneName = timezone_name_from_abbr("", 3*3600, false);
$modified = $original->setTimezone(new DateTimezone($timezoneName));
Ты сказал:
Использование javascript Я знаю, что часовой пояс моих пользователей - UTC +3.
Вероятно, вы сделали что-то вроде этого:
var offset = new Date().getTimezoneOffset();
Это возвращает текущее смещение от UTC в минутах, положительные значения падают к западу от UTC. Он не возвращает часовой пояс!
Часовой пояс не является смещением. Часовой пояс имеет смещение. Он может иметь несколько разных смещений. Часто есть два смещения: один для стандартного времени и один для летнего времени. Одно числовое значение не может представлять это отдельно.
"America/New_York"
UTC-5
UTC-4
Помимо двух смещений, также завернутых в этот часовой пояс, указаны даты и время перехода между двумя смещениями, чтобы вы знали, когда они применяются. Там также исторический отчет о том, как смещения и переходы могут со временем меняться.
См. также "Часовой пояс!= Смещение" в wiki.
В примере вашего примера вы, вероятно, получили значение -180
из javascript, представляющее текущее смещение UTC + 3. Но это только смещение для этого конкретного момента времени! Если вы следуете minaz answer, вы получите часовой пояс, который делает предположение, что UTC + 3 всегда является правильным смещением. Это будет работать, если в реальном времени есть что-то вроде "Africa/Nairobi"
, который никогда ничего не использовал, кроме UTC + 3. Но для всех, кого вы знаете, ваш пользователь может находиться в "Europe/Istanbul"
, который использует UTC + 3 летом и UTC + 2 зимой.
Начиная с PHP 5.5.10, DateTimeZone принимает смещение как "+3":
Насколько я могу судить по документам DateTimeZone, вам необходимо пройти действительный часовой пояс, и вот valid. Проверьте others, что-то там может вам помочь.
Пробовал ли вы это
http://php.net/manual/en/function.strtotime.php
<?php
echo strtotime("now"), "\n";
echo strtotime("10 September 2000"), "\n";
echo strtotime("+5 hours");
echo strtotime("+1 day"), "\n";
echo strtotime("+1 week"), "\n";
echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";
echo strtotime("next Thursday"), "\n";
echo strtotime("last Monday"), "\n";
?>
Для тех, кто сталкивается с этим, я столкнулся с одной и той же проблемой, поэтому в конце я расширил класс DateTime и переопределил метод __construct()
, чтобы принять смещение (в минутах) вместо часового пояса.
Оттуда мой пользовательский __construct()
определяет, что такое смещение в часах и минутах (например, -660 = +11: 00), а затем использует parent::__construct()
для передачи моей даты, настраиваемого для включения моего смещения, обратно к исходной дате.
Поскольку я всегда занимаюсь временем UTC в своем приложении, мой класс также изменяет время UTC, вычитая смещение, поэтому передача Midnight UTC и смещение -660 покажет мне 11am
Мое решение подробно описано здесь: fooobar.com/questions/192375/...
DateTimeZone требует, чтобы часовой пояс не был нарушен
Это позволяет Мэтью ответить еще на шаг, чтобы изменить часовой пояс даты на любое целочисленное смещение.
public static function applyHourOffset(DateTime $dateTime, int $hourOffset):DateTime
{
$dateWithTimezone = clone $dateTime;
$sign = $hourOffset < 0 ? '-' : '+';
$timezone = new DateTimeZone($sign . abs($hourOffset));
$dateWithTimezone->setTimezone($timezone);
return $dateWithTimezone;
}
Примечание: у меня был разрыв в производстве из-за принятого ответа.
Я был обращен к решению благодаря ссылке Джои Ривера. Как то, что говорили здесь другие, часовой пояс не является смещением, вам нужен действительный часовой пояс.
Это то, что я использую для себя
$singapore_time = new DateTime("now", new DateTimeZone('Asia/Singapore'));
var_dump( $singapore_time );
Я сам нашел гораздо более удобным работать с форматом ГГГ-ММ-ДД ЧЧ: ММ. Пример.
$original = new DateTime("2017-05-29 13:14", new DateTimeZone('Asia/Singapore'));
Современный ответ:
$usersNow = new DateTime('now', new DateTimeZone('+0300'));
Документация: