为什么它说 5,以及为什么这在技术上是正确的
在Sydney, DST 开始于 2013-10-06 02:00:00 - 所以你在跨越那个日期的时候损失了一个小时。
当您调用 strtime 时,它会将时间解释为悉尼时间,但返回一个 Unix 时间戳。如果你将第二组时间戳转换为 UTC,你会得到一个从 2013-09-30 14:00:00 到 2013-10-06 13:00:00 的范围,这不是 6 天,所以得到四舍五入到 5。
如何获得忽略 DST 转换的时差
尝试使用DateTime对象,例如
$tz=new DateTimeZone('Australia/Sydney');
$start=new DateTime('2013-10-01', $tz);
$end=new DateTime('2013-10-07', $tz);
$diff=$end->diff($start);
//displays 6
echo "difference in days is ".$diff->d."\n";
为什么 DateTime::diff 的工作方式不同?
你可能会问“为什么会这样?” - 毕竟,这些时间之间真的没有6天,而是5天23小时。
原因是DateTime::diff实际上更正了 DST 转换。我必须阅读源代码才能弄清楚 - 更正发生在内部timelib_diff函数中。如果满足以下所有条件,则会发生此更正
- 每个 DateTime 使用相同的时区
- 时区必须是地理 ID,而不是 GMT 之类的缩写
- 每个 DateTime 必须有不同的 DST 偏移量(即一个在 DST 中,一个不在 DST 中)
为了说明这一点,如果我们在切换到 DST 的任一侧仅几个小时内使用两次会发生什么
$tz=new DateTimeZone('Australia/Sydney');
$start=new DateTime('2013-10-06 00:00:00', $tz);
$end=new DateTime('2013-10-06 04:00:00', $tz);
//diff will correct for the DST transition
$diffApparent=$end->diff($start);
//but timestamps represent the reality
$diffActual=($end->getTimestamp() - $start->getTimestamp()) / 3600;
echo "Apparent difference is {$diffApparent->h} hours\n";
echo "Actual difference is {$diffActual} hours\n";
这输出
Apparent difference is 4 hours
Actual difference is 3 hours