Используя 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
Помимо двух смещений, также завернутых в этот часовой пояс, указаны даты и время перехода между двумя смещениями, поэтому вы знаете, когда они применяются. Существует также исторический отчет о том, как смещения и переходы могут со временем меняться.
См. Также «Часовой пояс! = Смещение» в вики-метке часового пояса .
В примере вашего примера вы, вероятно, получили значение -180
из javascript, представляющее текущее смещение UTC + 3. Но это только смещение для этого конкретного момента времени! Если вы ответите на запрос Minaz , вы получите часовой пояс, который делает предположение, что UTC + 3 всегда является правильным смещением. Это будет работать, если в реальном времени есть что-то вроде "Africa/Nairobi"
которая никогда не использовала ничего, кроме UTC + 3. Но для всех, кого вы знаете, ваш пользователь может быть в "Europe/Istanbul"
, который использует UTC + 3 летом и UTC + 2 зимой.
Начиная с PHP 5.5.10, DateTimeZone принимает смещение как «+3»:
Насколько я могу судить по документам на DateTimeZone , вам необходимо пройти действительный часовой пояс, и вот действительные . Проверьте других , что-то там может вам помочь.
вы пробовали это
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()
чтобы передать мою дату, настраиваемый для включения моего смещения, назад к исходной DateTime.
Поскольку я всегда имею дело с временем UTC в своем приложении, мой класс также изменяет время UTC, вычитая смещение, поэтому передача Midnight UTC и смещение -660 покажут мне 11 утра
Мое решение подробно описано здесь: https://stackoverflow.com/a/35916440/2301484
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'));
Документация: