PHP time() 和 DST 问题结束 - DST 结束后 1 小时
Posted
技术标签:
【中文标题】PHP time() 和 DST 问题结束 - DST 结束后 1 小时【英文标题】:PHP time() and end of DST issue - 1 hour after end of DST 【发布时间】:2013-09-29 00:59:05 【问题描述】:我已经这样定义了这段代码(为了清楚起见,简化版):
$fifteenMinsLater = strtotime('+900 second', time());
$now = time();
if ( $now > $fifteenMinsLater )
mtrace("This should NEVER happen");
else
mtrace("This should always be the case");
2013 年 3 月 11 日凌晨 2:00,美国/纽约的夏令时结束,时钟倒转一小时到凌晨 1:00。
当我在 2013 年 3 月 11 日和凌晨 1:00 到凌晨 2:00 之间的 DST 结束后(即凌晨 2:00 变为凌晨 1:00)运行上述代码时:
This should NEVER happen
被打印出来。但是,在 DST 转换之前或新的凌晨 2:00 之后的任何时间都可以。
这导致了一个重大错误,导致用户尝试访问使用上述代码的函数在 DST 转换后的一小时内惨遭失败。
php 5.2.11。
有什么想法吗?
【问题讨论】:
你确定你没有过分简单化吗?strtotime
& time
返回 unix 时间戳,据了解,它不知道 DST/不会意外倒计时 3600 秒。您是在比较这些时间戳的表示,而不是原始整数时间戳本身吗? AFAIK,只有闰秒会影响 unix 时间戳。
$now 和 $fifteenMinsLater 的回声将大大有助于解决这个问题。
Site 3v4l.org 非常适合测试不同的 PHP 版本。只有版本 5.0.0 to 5.0.2 返回无效比较。
【参考方案1】:
strtotime()
和 PHP 中的其他日期函数不考虑时区。 DateTime()
确实:
$fifteenMinsLater = new DateTime();
$fifteenMinsLater->modify('+15 minutes');
$now = new DateTime();
if ( $now > $fifteenMinsLater )
mtrace("This should NEVER happen");
else
mtrace("This should always be the case");
以下是 PHP 5.5 中的操作方法:
$now = new DateTimeImmutable();
$fifteenMinsLater = $now->modify('+15 minutes');
if ( $now > $fifteenMinsLater )
mtrace("This should NEVER happen");
else
mtrace("This should always be the case");
【讨论】:
是的,他们确实没有考虑时区,但这就是重点。他们使用UTC unix时间。因此,向同一个 time() 函数添加 15 分钟应该可以作为派生时间变量($now 和 $fifteenMinLater)工作,但它们是 int unix 时间戳。我会给你的答案投票(如果我有足够的代表),因为在 PHP 5.3.6 中使用上面的第一个代码会产生正确的结果。然而,在 PHP 5.2.17 上使用它显示了同样的问题,这让我相信 PHP 5.2.x 中存在一个继承错误。非常感谢!以上是关于PHP time() 和 DST 问题结束 - DST 结束后 1 小时的主要内容,如果未能解决你的问题,请参考以下文章
DST 结束时的 Laravel Carbon addHour()