DateTime 对象不受其时间戳的约束?
DateTime object not bound by its timestamp?
DateTime
对象 不受其时间戳的约束吗? 或者 getTimestamp() 是否有某种副作用 在 DST 更改时使用?
详情
当设置 DST
上的 DateTime
对象的时间戳时(意味着格式化时间同时存在 before/after 更改时钟)返回的时间戳与设置的时间戳不同。
$ 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?)**
为什么打印的值不相等?
\DateTime
对象不保留时间戳而是本地时间,并在timestamp getter and timestamp setter.
中进行转换
当关闭 DST 时,每年都会产生一次副作用,因为时间戳范围 1319932800..1319936400 和 1319936400..1319940000 解析为相同的本地时间:
https://www.epochconverter.com/timezones?q=1319936399&tz=Europe%2FBerlin
https://www.epochconverter.com/timezones?q=1319939999&tz=Europe%2FBerlin
首先,unix 时间戳始终是 UTC,因此它没有时区和 DST。
另一方面,DateTime
对象仅存储 当地时间 ("local" 表示在 DateTime
实例).
因此在设置时间戳之前,您应该将时区设置为 +00:00 或 UTC 以避免不必要的时间转换和 DST 猜测.
您有两个选择:
1。通过 DateTime
的构造函数设置时间戳
构造函数将覆盖默认时区并显式设置为 +00:00 当它获得时间戳 (以 @
开始) 在第一个参数中:
$set_timestamp = 1319932800;
$date = new DateTime('@' . $set_timestamp);
print($set_timestamp . "\n");
print($date->getTimestamp() . "\n");
信息:在这种情况下,构造函数的时区参数总是会被覆盖。
2。调用前设置时区 setTimestamp()
在调用 setTimestamp()
:
之前使用 DateTimeZone('+00:00')
或 DateTimeZone('UTC')
时区调用 setTimezone()
$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 时间戳转换为本地时间时) 时区将再次变得有趣。
DateTime
对象 不受其时间戳的约束吗? 或者 getTimestamp() 是否有某种副作用 在 DST 更改时使用?
详情
当设置 DST
上的 DateTime
对象的时间戳时(意味着格式化时间同时存在 before/after 更改时钟)返回的时间戳与设置的时间戳不同。
$ 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?)**
为什么打印的值不相等?
\DateTime
对象不保留时间戳而是本地时间,并在timestamp getter and timestamp setter.
当关闭 DST 时,每年都会产生一次副作用,因为时间戳范围 1319932800..1319936400 和 1319936400..1319940000 解析为相同的本地时间:
https://www.epochconverter.com/timezones?q=1319936399&tz=Europe%2FBerlin
https://www.epochconverter.com/timezones?q=1319939999&tz=Europe%2FBerlin
首先,unix 时间戳始终是 UTC,因此它没有时区和 DST。
另一方面,DateTime
对象仅存储 当地时间 ("local" 表示在 DateTime
实例).
因此在设置时间戳之前,您应该将时区设置为 +00:00 或 UTC 以避免不必要的时间转换和 DST 猜测.
您有两个选择:
1。通过 DateTime
的构造函数设置时间戳
构造函数将覆盖默认时区并显式设置为 +00:00 当它获得时间戳 (以 @
开始) 在第一个参数中:
$set_timestamp = 1319932800;
$date = new DateTime('@' . $set_timestamp);
print($set_timestamp . "\n");
print($date->getTimestamp() . "\n");
信息:在这种情况下,构造函数的时区参数总是会被覆盖。
2。调用前设置时区 setTimestamp()
在调用 setTimestamp()
:
DateTimeZone('+00:00')
或 DateTimeZone('UTC')
时区调用 setTimezone()
$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 时间戳转换为本地时间时) 时区将再次变得有趣。