Как преобразовать прошедшее, настоящее и будущее время в формате UTC в местный часовой пояс; Вносить изменения и конвертировать обратно в UTC - PullRequest
0 голосов
/ 30 мая 2019

Я использую сторонний REST API с PHP cURL, из которого я получаю поле даты в формате (то есть 2019-03-09T08: 00: 00Z), который находится в часовом поясе браузера по умолчанию. Я хочу отредактировать эту дату и вернуть ее на сторонний сервер в формате UTC.

После помещения его на сервер в стороннем графическом интерфейсе отобразится моя дата, измените ее в качестве часового пояса моего пользователя по умолчанию, который называется "Америка / Нью-Йорк".

Я написал функцию, которая работает большую часть времени, за исключением пересечения дат Spring-Forward и Fall-Back. Для тестирования я использую следующие даты SpringForward и Fall-Back в 2019 году.

Официальное изменение времени было 10 марта 2019 года - переход на летнее время начался Когда местное стандартное время должно было достичь Воскресенье, 10 марта 2019 года, 2:00:00 утра. Часы были переведены на 1 час вперед Воскресенье, 10 марта 2019 года, 3:00:00 по местному летнему времени вместо

Официальное изменение времени будет 3 ноября 2019 г. - Заканчивается переход на летнее время Когда местное летнее время приближается Воскресенье, 3 ноября 2019 года, 2:00:00 утра часы повернут назад на 1 час Воскресенье, 3 ноября 2019 года, 1:00:00 по местному стандартному времени.

Проблема (ы):

  1. Функция обнаруживает изменение времени в Spring-Forward в 7:00 утра вместо 2:00 AM
  2. Функция обнаруживает изменение времени в режиме возврата в 6:00 вместо 2:00

Кто-нибудь может дать мне представление о том, что я делаю неправильно?

Тест PHP-кода

    // Create some dates that cross the Spring-Forward that occurred March 10, 2019 at 2:00 AM
    $date_1a = "2019-03-09T01:59:59Z";
    $date_1b = "2019-03-10T02:00:00Z";
    $date_1c = "2019-03-10T06:59:59Z";
    $date_1d = "2019-03-10T07:00:00Z";
    // Create some dates that cross the Fall-Back that will occur on  November 3, 2019 at 2:00 AM
    $date_2a = "2019-11-03T01:59:59Z";
    $date_2b = "2019-11-03T02:00:00Z";
    $date_2c = "2019-11-03T05:59:59Z";
    $date_2d = "2019-11-04T06:00:00Z";

    // Display the original date retrieved from GET
    echo 'Original Date 1a = ' . $date_1a . '<br/>';
    echo 'Original Date 1b = ' . $date_1b . ' - Change not happening at 2:00 AM' . '<br/>';
    echo 'Original Date 1c = ' . $date_1c . '<br/>';
    echo 'Original Date 1d = ' . $date_1d . ' - Change happens at 7:00 AM not 2:00 AM' . '<br/>';

    echo 'Original Date 2a = ' . $date_2a . '<br/>';
    echo 'Original Date 2b = ' . $date_2b . ' - Change not happening at 2:00 AM' . '<br/>';
    echo 'Original Date 2c = ' . $date_2c . '<br/>';
    echo 'Original Date 2d = ' . $date_2d . ' - Change happens at 6:00 AM not 2:00 AM' . '<br/>';

    // Get the timezone offsets based on the dates
    $offset1a = get_timezone_offset($date_1a, 'UTC','America/New_York');
    $offset1b = get_timezone_offset($date_1b, 'UTC','America/New_York');
    $offset1c = get_timezone_offset($date_1c, 'UTC','America/New_York');
    $offset1d = get_timezone_offset($date_1d, 'UTC','America/New_York');

    $offset2a = get_timezone_offset($date_2a, 'UTC','America/New_York');
    $offset2b = get_timezone_offset($date_2b, 'UTC','America/New_York');
    $offset2c = get_timezone_offset($date_2c, 'UTC','America/New_York');
    $offset2d = get_timezone_offset($date_2d, 'UTC','America/New_York');

    // Display the Offsets in seconds
    echo 'Date 1a offset in seconds = ' . $offset1a . ' - 01:59:59 AM' . '<br/>';
    echo 'Date 1b offset in seconds = ' . $offset1b . ' - Change not happening at 2:00 AM should be -14400' . '<br/>';
    echo 'Date 1c offset in seconds = ' . $offset1c . ' - 06:59:59 AM' . '<br/>';
    echo 'Date 1d offset in seconds = ' . $offset1d . ' - Change happens at 7:00 AM not 2:00 AM' . '<br/>';

    echo 'Date 2a offset in seconds = ' . $offset2a . ' - 01:59:59 AM' . '<br/>';
    echo 'Date 2b offset in seconds = ' . $offset2b . ' - Change not happening at 2:00 AM should be -18000' . '<br/>';
    echo 'Date 2c offset in seconds = ' . $offset2c . ' - 05:59:59 AM' . '<br/>';
    echo 'Date 2d offset in seconds = ' . $offset2d . ' - Change happens at 6:00 AM not 2:00 AM' . '<br/>';

    // Convert Adjusted Dates to seconds
    $time1a = strtotime($date_1a)-$offset1a;
    $time1b = strtotime($date_1b)-$offset1b;
    $time1c = strtotime($date_1c)-$offset1c;
    $time1d = strtotime($date_1d)-$offset1d;

    $time2a = strtotime($date_2a)-$offset2a;
    $time2b = strtotime($date_2b)-$offset2b;
    $time2c = strtotime($date_2c)-$offset2c;
    $time2d = strtotime($date_2d)-$offset2d;

    // Create New Date Objects
    $dt1a = new DateTime("@$time1a");
    $dt1b = new DateTime("@$time1b");
    $dt1c = new DateTime("@$time1c");
    $dt1d = new DateTime("@$time1d");

    $dt2a = new DateTime("@$time2a");
    $dt2b = new DateTime("@$time2b");
    $dt2c = new DateTime("@$time2c");
    $dt2d = new DateTime("@$time2d");

    // Format new date objects to UTC for PUT.
    $adjustedDate1a = $dt1a->format('Y-m-d\TH:i:s\Z');
    $adjustedDate1b = $dt1b->format('Y-m-d\TH:i:s\Z');
    $adjustedDate1c = $dt1c->format('Y-m-d\TH:i:s\Z');
    $adjustedDate1d = $dt1d->format('Y-m-d\TH:i:s\Z');

    $adjustedDate2a = $dt2a->format('Y-m-d\TH:i:s\Z');
    $adjustedDate2b = $dt2b->format('Y-m-d\TH:i:s\Z');
    $adjustedDate2c = $dt2c->format('Y-m-d\TH:i:s\Z');
    $adjustedDate2d = $dt2d->format('Y-m-d\TH:i:s\Z');

    // Display new Date Objects to be PUT
    echo 'Adjusted Date 1a = ' . $adjustedDate1a . '<br/>';
    echo 'Adjusted Date 1b = ' . $adjustedDate1b . '<br/>';
    echo 'Adjusted Date 1c = ' . $adjustedDate1c . '<br/>';
    echo 'Adjusted Date 1d = ' . $adjustedDate1d . '<br/>';

    echo 'Adjusted Date 2a = ' . $adjustedDate2a . '<br/>';
    echo 'Adjusted Date 2b = ' . $adjustedDate2b . '<br/>';
    echo 'Adjusted Date 2c = ' . $adjustedDate2c . '<br/>';
    echo 'Adjusted Date 2d = ' . $adjustedDate2d . '<br/>';

    // This function returns the timezone offset.
    function get_timezone_offset($targetDate, $remote_tz, $origin_tz) {
        $origin_dtz = new DateTimeZone($origin_tz);
        $remote_dtz = new DateTimeZone($remote_tz);
        $origin_dt = new DateTime($targetDate, $origin_dtz);
        $remote_dt = new DateTime($targetDate, $remote_dtz);
        $offset = $origin_dtz->getOffset($origin_dt) - $remote_dtz->getOffset($remote_dt);
        return $offset;
    }
?>

Вывод скрипта

Original Date 1a = 2019-03-09T01:59:59Z
Original Date 1b = 2019-03-10T02:00:00Z - Change not happening at 2:00 AM
Original Date 1c = 2019-03-10T06:59:59Z
Original Date 1d = 2019-03-10T07:00:00Z - Change happens at 7:00 AM not 2:00 AM
Original Date 2a = 2019-11-03T01:59:59Z
Original Date 2b = 2019-11-03T02:00:00Z - Change not happening at 2:00 AM
Original Date 2c = 2019-11-03T05:59:59Z
Original Date 2d = 2019-11-04T06:00:00Z - Change happens at 6:00 AM not 2:00 AM
Date 1a offset in seconds = -18000 - 01:59:59 AM
Date 1b offset in seconds = -18000 - Change not happening at 2:00 AM should be -14400
Date 1c offset in seconds = -18000 - 06:59:59 AM
Date 1d offset in seconds = -14400 - Change happens at 7:00 AM not 2:00 AM
Date 2a offset in seconds = -14400 - 01:59:59 AM
Date 2b offset in seconds = -14400 - Change not happening at 2:00 AM should be -18000
Date 2c offset in seconds = -14400 - 05:59:59 AM
Date 2d offset in seconds = -18000 - Change happens at 6:00 AM not 2:00 AM
Adjusted Date 1a = 2019-03-09T06:59:59Z
Adjusted Date 1b = 2019-03-10T07:00:00Z
Adjusted Date 1c = 2019-03-10T11:59:59Z
Adjusted Date 1d = 2019-03-10T11:00:00Z
Adjusted Date 2a = 2019-11-03T05:59:59Z
Adjusted Date 2b = 2019-11-03T06:00:00Z
Adjusted Date 2c = 2019-11-03T09:59:59Z
Adjusted Date 2d = 2019-11-04T11:00:00Z

1 Ответ

0 голосов
/ 05 июня 2019

Ваши ожидания неверны, потому что:

  • Z означает UTC. Изменения происходят в 2:00 AM по местному времени , а не в 2:00 AM UTC.

  • В начале летнего времени America/New_York переходит с 01:59:59-05:00 на 03:00:00-04:00

    • В UTC это 06:59:59Z до 07:00:00Z (ваше наблюдение в 7 часов утра)
  • В конце летнего времени America/New_York переходит с 01:59:59-04:00 на 01:00:00-05:00

    • В UTC это 05:59:59Z до 06:00:00Z (ваше наблюдение в 6 часов утра)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...