【发布时间】:2017-03-23 13:51:52
【问题描述】:
从 PHP 5.2.2 开始,支持使用比较运算符比较 DateTime 对象。
5.2.2 DateTime 对象与比较运算符的比较更改为按预期工作。以前,所有 DateTime 对象都被认为是相等的(使用 ==)。
我的问题是,当我修改现有 DateTime 对象的时区时,它不再等于更改时区之前等于的 DateTime 对象。更奇怪的是,如果我在修改后的 DateTime 对象上调用 DateTime::getTimestamp(),它现在将等于另一个 DateTime 对象。
例如:
<?php
$dt = new DateTime("2016-11-08 08:27:33am -08");
$dt2 = new DateTime("2016-11-08 09:27:33am -07");
var_dump($dt == $dt2);
$dt2->setTimezone(new DateTimeZone("-08"));
var_dump($dt == $dt2);
var_dump($dt < $dt2);
var_dump($dt > $dt2);
var_dump($dt2->getTimestamp());
var_dump($dt == $dt2);
var_dump($dt < $dt2);
var_dump($dt > $dt2);
将产生以下输出:
bool(true)
bool(false)
bool(false)
bool(true)
int(1478622453)
bool(true)
bool(false)
bool(false)
那是什么?如您所见,$dt 和 $dt2 在创建时是相等的,尽管它们位于不同的时区。不过,这种行为是意料之中的。 $dt 和 $dt2 都代表完全相同的时刻。如果您同时拨打getTimestamp(),您将获得相同的号码。同样,如果您明确设置两个 DateTime 的时区,它们将相等。
PHP 手册确实指出,如果初始化字符串包含时区(或者是 unix 时间戳),则忽略时区:
注意: 当 $time 参数是 UNIX 时间戳(例如 @946684800)或指定时区(例如 2010-01-28T15:00:00+02:00)时,$timezone 参数和当前时区将被忽略。
所以我确实相信这是导致这种看似不正常的行为的原因,但我不介意知道原因。
那么,有人知道为什么 DateTimes 会这样吗? DateTime 对象实际上是如何比较的?如果您仍需要将 DateTime 对象与另一个 DateTime 对象进行比较,那么更改其时区的最佳方法是什么?
【问题讨论】:
-
更令人毛骨悚然:-S pastebin.com/b8VXm5dG
-
对我来说看起来像一个错误。报告它。请注意,
-08不是真正的时区。如果您使用实时时区,也许您可以获得更好的结果。 -
虽然偏移量确实不是实时时区,但 PHP 的文档没有出现来表明它是否支持偏移量。如果我可以在这个实现中使用确切的时区,我会的。不幸的是,在这种情况下这是不可能的。像这样的代码:
<?php $dt = DateTime::createFromFormat('O', "-08"); var_export($dt);将时区显示为“-08:00”。