具有较早日期时间的 PHP 日期时间对象具有更高的时间戳值?



我正在尝试做一个函数,如果现在当前在一周中的某些小时和几天之间,它将返回 true。

问题是,unix时间戳似乎不匹配。

<?php
function isWorkingTime() {
$now = new DateTime(date('Y-m-d H:i:00'), new DateTimeZone(date('T')));
$tz = $now->getTimezone();
if(strtolower($tz->getName()) != 'est'){
$now->setTimezone(new DateTimeZone('EST'));
}
$min = clone $now;
$min->setTime(8,30,0);
$max = clone $now;
switch($now->format('N')){
case 1:
case 2:
case 3:
case 4:
$max->setTime(17,30,0);
break;
case 5:
$max->setTime(16,30,0);
break;
default:
return false;
break;
}
return ($now >= $min && $now < $max);
}
?>

如果我继续尝试输出 3 个日期时间对象,如下所示:

<?php
echo 'now: '.$now->format('Y-m-d H:i:s U T').PHP_EOL;
echo 'min: '.$min->format('Y-m-d H:i:s U T').PHP_EOL;
echo 'max: '.$max->format('Y-m-d H:i:s U T').PHP_EOL;
?>

我明白这个:

now: 2017-02-15 13:17:00 1487164620 EST
min: 2017-02-15 08:30:00 1487165400 EST
max: 2017-02-15 17:30:00 1487197800 EST

为什么$min时间戳大于$now?

我正在运行 PHP 5.6.30

文档声明您不应该使用 EST,并警告有关"奇怪"效果:

警告 请不要使用此处列出的任何时区(除了 UTC),它们仅出于向后兼容的原因而存在,并且可能会暴露 错误行为。

http://php.net/manual/en/timezones.others.php

使用正确的时区名称(如America/New_York)运行代码段不会显示此问题:https://3v4l.org/NR3cg

要明确问题/错误:

使用 EST: https://3v4l.org/BdUan

02/15/2017 6:00 am 1487138400 -> TS says 02/15/2017 @ 6:00am (UTC) (wrong)
02/15/2017 8:30 am 1487165400 -> TS says 02/15/2017 @ 1:30pm (UTC) (right)

使用美国/New_York: https://3v4l.org/ndISv

02/15/2017 6:00 am 1487156400 -> TS says 02/15/2017 @ 11:00am (UTC) (right)
02/15/2017 8:30 am 1487165400 -> TS says 02/15/2017 @ 1:30pm (UTC) (right)

(虽然所有内容都应该是非常相同的时间戳,但与第 2 行相比)

我可能是错的,但在您的情况下,您似乎需要在 setTime() 之后再次设置时区:

<?php
$now = new DateTime(date('Y-m-d H:i:00'), new DateTimeZone(date('T')));
echo '          original: '.$now->format('Y-m-d H:i:s U T').PHP_EOL;
$now->setTimezone(new DateTimeZone('EST'));
echo '    after timezone: '.$now->format('Y-m-d H:i:s U T').PHP_EOL;
$now->setTime(8,30,0);
echo '     after settime: '.$now->format('Y-m-d H:i:s U T').PHP_EOL;
$now->setTimezone(new DateTimeZone('EST'));
echo 'after 2nd timezone: '.$now->format('Y-m-d H:i:s U T').PHP_EOL;

结果:

original: 2017-02-15 22:44:00 1487187840 MSK
after timezone: 2017-02-15 14:44:00 1487169840 EST
after settime: 2017-02-15 08:30:00 1487165400 EST
after 2nd timezone: 2017-02-15 08:30:00 1487147400 EST

建议说明:$now->format('U')给您错误的时间戳,对于实际时间戳,您需要通过$now->getTimestamp()检索它,它必须等于原始时间戳。

settimezone 不会更改基础时间戳,只会更改时间戳的显示格式。

结果是,您在 GMT 中创建了一个日期时间。这意味着时间戳来自格林威治标准时间。然后,您更改了时区,使其以 EST 显示时间,但实际时间仍来自 GMT。

然后,在 EST 中创建一个新的日期时间,并在EST 中设置时间。实际的基础时间/时间戳来自美国东部标准时间。然后,您复制了此过程。

结果是,您有一个 GMT 时间(现在)和两个 EST 时间(最小/最大)创建的 UTC 时间戳。

编辑: 结论是DateTime::setTimeZone只影响时间的视觉显示方式。它不会更改创建时所引用的时间点。

第二次编辑: 我无法复制问题。这可能是您正在运行的 PHP 版本中的错误,但 format('U') 应该为您使用的格式化时间提供正确的 unix 时间戳。显然不是,因为您现在的时间戳与 GMT 而不是 EST 中的时间戳相匹配。

相关内容

  • 没有找到相关文章

最新更新