php: установка часового пояса по смещению UTC - PullRequest
29 голосов
/ 02 сентября 2011

Используя javascript, я знаю, что часовой пояс моих пользователей - UTC +3.

Теперь я хочу создать объект DateTime с такими знаниями:

$usersNow = new DateTime('now', new DateTimeZone("+3"));

получаю в качестве ответа:

'Unknown or bad timezone (+2)'

Что я делаю не так? Как я могу исправить?

Ответы [ 10 ]

35 голосов
/ 02 сентября 2011

как насчет этого ...

$original = new DateTime("now", new DateTimeZone('UTC'));
$timezoneName = timezone_name_from_abbr("", 3*3600, false);
$modified = $original->setTimezone(new DateTimezone($timezoneName));
10 голосов
/ 14 мая 2014

Вы сказали:

Используя javascript, я знаю, что часовой пояс моих пользователей - UTC + 3.

Возможно, вы запустили что-то вроде этого:

var offset = new Date().getTimezoneOffset();

Возвращает текущее смещение *1011* от 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 зимой.

5 голосов
/ 15 июня 2016

Начиная с PHP 5.5.10, DateTimeZone принимает смещение наподобие «+3»:

https://3v4l.org/NUGSv

4 голосов
/ 05 декабря 2017

Современный ответ:

$usersNow = new DateTime('now', new DateTimeZone('+0300'));

Документация:

http://php.net/manual/en/datetimezone.construct.php

1 голос
/ 10 марта 2016

Для всех, кто сталкивался с этим, я столкнулся с той же проблемой, поэтому в итоге я расширил класс DateTime и переопределил метод __construct(), чтобы принять смещение (в минутах) вместо часового пояса.

Оттуда мой пользовательский __construct() определяет смещение в часах и минутах (например, -660 = +11: 00), а затем использует parent::__construct(), чтобы передать мою дату, отформатированный, чтобы включить мое смещение, обратно висходный DateTime.

Поскольку я всегда имею дело с временем UTC в своем приложении, мой класс также изменяет время UTC, вычитая смещение, поэтому прохождение полуночи UTC и смещения -660 покажет мне 11 часов утра.1008 *

Мое решение подробно здесь: https://stackoverflow.com/a/35916440/2301484

1 голос
/ 02 сентября 2011

Вы пробовали это

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";
    ?>
1 голос
/ 02 сентября 2011

Насколько я могу судить по документам на DateTimeZone , вам нужно передать действительный часовой пояс, а вот действительные .Проверьте другие , что-то там может вам помочь.

0 голосов
/ 29 мая 2017

Я был направлен на решение благодаря ссылке Джои Риверы.Как и то, что здесь говорили другие, часовой пояс не является смещением, вам нужен действительный часовой пояс.

Это то, что я использую для себя

$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'));
0 голосов
/ 17 ноября 2016

Этот ответ делает ответ Мэтью еще на шаг, чтобы изменить часовой пояс даты на любое целочисленное смещение.

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;
}

Примечание: у меня произошел сбой в производстве из-за принятого ответа.

0 голосов
/ 02 сентября 2011

DateTimeZone требует часовой пояс, а не offest

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...