php在使用澳大利亚/悉尼时区时给出错误的答案


php giving wrong answer when using time zone Australia/Sydney

我正在开发一个在澳大利亚运行的网站。

所以我设置了时区如下。

date_default_timezone_set('Australia/Sydney');

我需要计算两个日期之间的天数。

我在十月份发现了一种奇怪的行为。

 $now = strtotime('2013-10-06'); // or your date as well
 $your_date = strtotime('2013-10-01');
 $datediff = $now - $your_date;
 echo floor($datediff/(60*60*24));//gives output 5, this is right

 $now = strtotime('2013-10-07'); // or your date as well
 $your_date = strtotime('2013-10-01');
 $datediff = $now - $your_date;
 echo floor($datediff/(60*60*24));//gives output 5, this is wrong, but it should be 6 here

在2013-10-07之后总是少给一天的答复。在其他时区也没问题。可能是由于夏令时。但是这个问题的解决方法是什么呢?

请帮助。

谢谢

为什么说5,为什么这在技术上是正确的

在悉尼,夏令时开始于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会发生什么

$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
相关文章: