Подтвердить что ты не робот

Php: установка часового пояса по смещению UTC

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

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

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

Я получаю как респондент:

'Unknown or bad timezone (+2)'

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

4b9b3361

Ответ 1

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

$original = new DateTime("now", new DateTimeZone('UTC'));
$timezoneName = timezone_name_from_abbr("", 3*3600, false);
$modified = $original->setTimezone(new DateTimezone($timezoneName));

Ответ 2

Ты сказал:

Использование 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 зимой.

Ответ 3

Начиная с PHP 5.5.10, DateTimeZone принимает смещение как "+3":

https://3v4l.org/NUGSv

Ответ 4

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

Ответ 5

Пробовал ли вы это

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";
    ?>

Ответ 6

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

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

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

Мое решение подробно описано здесь: fooobar.com/questions/192375/...

Ответ 7

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

Ответ 8

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

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

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

Ответ 9

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

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

$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'));