我尝试执行的功能如果现在是在一周的某些时段和几天之间,则会返回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
答案 0 :(得分:0)
该文件声明您不应使用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)
使用America / 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行比较)
答案 1 :(得分:0)
settimezone不会更改基础时间戳,只会更改时间戳的显示格式。
结果是,您在GMT中创建了一个日期时间。这意味着时间戳来自GMT。然后你更改了时区,以便在EST中显示时间,但实际时间仍然是GMT。
然后在EST中创建一个新的日期时间并在EST 中设置时间。实际的基础时间/时间戳来自EST。然后你复制了这个过程。
结果是您从一个GMT时间(现在)和两个EST时间(最小/最大)创建了UTC时间戳。
编辑: 需要注意的是,DateTime :: setTimeZone仅影响时间的可视化显示方式。它不会改变它在创建时的时间点。
第二次编辑: 我无法复制这个问题。这可能是您运行的PHP版本中的错误,但格式(&#39; U&#39;)应为您使用的格式化时间提供正确的unix时间戳。显然不是这样,因为你现在的时间戳与GMT而不是EST相匹配。
答案 2 :(得分:0)
我可能错了,但在你的情况下,似乎你需要在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()
检索它的实际时间戳,它必须等于原始时间戳。