众所周知,DST 切换会引入重复的本地时间。如果您在 2:00 将时钟向后移动 1 小时,那么您将在同一天两次获得 1:00。 PHP 能够处理它并跟踪它是哪个 1:00。最好用另一个测试用例来说明这一点:
$timeZone = new DateTimeZone('America/New_York');
$modified = new DateTime('2021-11-07 01:55:00.000000', $timeZone);
$modified->add(new DateInterval('PT5M'));
$raw = new DateTime('2021-11-07 01:00:00.000000', $timeZone);
var_dump($modified, $raw, $modified == $raw, $modified < $raw, $modified > $raw);
$control = new DateTime('2021-11-07 01:00:00.000000', $timeZone);
var_dump($raw, $raw, $control == $raw, $control < $raw, $control > $raw);
object(DateTime)#2 (3) {
["date"]=>
string(26) "2021-11-07 01:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "America/New_York"
}
object(DateTime)#3 (3) {
["date"]=>
string(26) "2021-11-07 01:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "America/New_York"
}
bool(false)
bool(false)
bool(true)
object(DateTime)#3 (3) {
["date"]=>
string(26) "2021-11-07 01:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "America/New_York"
}
object(DateTime)#3 (3) {
["date"]=>
string(26) "2021-11-07 01:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "America/New_York"
}
bool(true)
bool(false)
bool(false)
如果我们设置1:55 并继续前进,PHP 知道结果时间是第二个1:00。如果我们直接设置1:00,它假定它是第一个1:00——老实说,它没有办法知道你指的是哪个,因为地理时区标识符会造成这种歧义。即使var_dump() 也无法显示差异。
另一方面,这些重复的1:00s 并不真正模棱两可,因为它们属于不同的时区:EDT 和EST。就是这样:
var_dump($modified->format('r T'), $raw->format('r T'), $control->format('r T'));
string(35) "Sun, 07 Nov 2021 01:00:00 -0500 EST"
string(35) "Sun, 07 Nov 2021 01:00:00 -0400 EDT"
string(35) "Sun, 07 Nov 2021 01:00:00 -0400 EDT"
简而言之,这里的一切都按预期工作。唯一的潜在问题是当您需要在 DST 边界处精确设置时间时,因为由于地理标识符的模糊性而无法使用它。您需要指定EST 或EDT,这不太方便,也不一定是等效的。