Объект DateTime не привязан своей отметкой времени?

Это DateTime объект не связаны его отметкой времени? Или делает getTimestamp () имеет некоторый побочный эффект когда используется на DST меняются?

подробности
При установке отметки времени DateTime объект, который находится на DST (то есть отформатированное время существует как до, так и после смены часов), возвращаемая временная метка отличается от установленной временной метки.

$ php --version
PHP 7.1.3 (cli) (built: Mar 17 2017 16:59:59) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

воспроизводить
Рассмотрим следующее php сценарий:

date_default_timezone_set('Europe/Berlin');

$date = new DateTime();
$set_timestamp = 1319932800;
$date->setTimestamp($set_timestamp);
$get_timestamp = $date->getTimestamp();

fwrite(STDERR, $set_timestamp . "\n");  // 1319932800
fwrite(STDERR, $get_timestamp . "\n");  // 1319936400 **(WHY IS THIS DIFFERENT?)**

Зачем напечатанные значения не равный?

4

Решение

Прежде всего, метка времени Unix всегда находится в UTC, поэтому она не имеет часового пояса и летнего времени.

С другой стороны, DateTime хранилища объектов местное время только («местный» означает, какой часовой пояс установлен в DateTime пример).

Поэтому вы должны установить часовой пояс на +00:00 или же универсальное глобальное время прежде чем установить временную метку, чтобы избежать ненужных преобразований времени и угадывания летнего времени.

У вас есть два варианта:

Конструктор переопределяет часовой пояс по умолчанию и явно указывает на +00:00 когда он получил метку времени (началось с @) по первому параметру:

$set_timestamp = 1319932800;
$date = new DateTime('@' . $set_timestamp);

print($set_timestamp . "\n");
print($date->getTimestamp() . "\n");

Информация: в этом случае параметр часового пояса конструктора всегда будет переопределен.

Вызов setTimezone() с DateTimeZone('+00:00') или же DateTimeZone('UTC') часовой пояс, прежде чем позвонить setTimestamp():

$set_timestamp = 1319932800;
$date = new DateTime();
$date->setTimezone(new DateTimeZone('UTC'));
$date->setTimestamp($set_timestamp);

print($set_timestamp . "\n");
print($date->getTimestamp() . "\n");

Конечно, в обоих случаях на выходе будет:

1319932800
1319932800

date_default_timezone_set() в этих случаях нет необходимости, потому что вы не хотите ничего делать по местному времени.

Однако, когда вы хотите напечатать $date в удобочитаемом формате (поэтому, когда вы конвертируете метку времени Unix в местное время) часовой пояс снова будет интересным.

3

Другие решения

\DateTime объект хранит не временные метки, а местное время и выполняет преобразования в получатель метки времени а также установщик метки времени.

Это приводит к побочному эффекту один раз в год при выключении летнего времени, поскольку обе временные метки: диапазоны 1319932800..1319936400 и 1319936400..1319940000 разрешают одно и то же местное время:
https://www.epochconverter.com/timezones?q=1319936399&TZ = Europe% 2FBerlin
https://www.epochconverter.com/timezones?q=1319939999&TZ = Europe% 2FBerlin

3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector