有人能解释一下这个例子中的strtotime函数有什么问题吗?我正在计算日期之间的差异。PHP 5.6.0(cli)(内置时间:2014年8月28日08:03:51)当我执行这个循环时,它会两次显示数字88。
date_default_timezone_set('Europe/London');
for($i=1;$i<=100;$i++){
$daysAfterTime = floor( abs( strtotime('2014-01-01') - strtotime('2014-01-01 +'.$i.' days') )/(60*60*24));
echo $daysAfterTime.'<br/>';
}
strtotime()
不适用于日期数学。手册上甚至这样说。
使用此函数进行数学运算是不可取的。
天数不完全是60*60*24
秒长,等等。
正如评论中所提到的,DateTime()
更适合这一点,因为它考虑了夏令时、闰年等因素。以下是使用DateTime()
、DateInterval()
和DatePeriod()
执行相同操作的高级方法,对于任何试图弄清楚发生了什么的人来说都更清楚。
$start = new DateTimeImmutable('2014-01-01', new DateTimeZone('Europe/London'));
$finish = $start->modify('+101 days'); // extra day as the last day is not inclusive
$interval = new DateInterval('P1D'); // interval of one day
$period = new DatePeriod($start, $interval, $finish);
foreach ($period as $date) {
$diff = $start->diff($date);
echo $diff->days . "<br>";
}
演示
我不知道预期的输出是什么,但其他88的结果是因为floor()
函数。它四舍五入到最低值,因此88重复。切换增长值减去常数值,这样就不需要使用abs()
和ceil()
。
date_default_timezone_set('Europe/London');
for($i=1;$i<=100;$i++){
$daysAfterTime = ceil((strtotime('2014-01-01 +'.$i.' days') - strtotime('2014-01-01'))/(60*60*24));
echo $daysAfterTime.'<br/>';
}
date_default_timezone_set('Europe/London');
echo (strtotime('2014-01-01 +89 days') - strtotime('2014-01-01 +88 days'))/(60*60), ' hours per day';
// 23 hours per day
我认为欧洲/伦敦时区使用夏令时
伦敦夏令时信息:http://www.timeanddate.com/time/zone/uk/london
var_dump(date('Y-m-d',strtotime('2014-01-01 +88 days')));
// string(10) "2014-03-30"
p.S。将date与z一起使用,效果如预期。
date_default_timezone_set('Europe/London');
for($i=1;$i<=100;$i++){
$daysAfterTime = date('z', strtotime('2014-01-01 +'.$i.' days')) - date('z', strtotime('2014-01-01'));
echo $daysAfterTime.PHP_EOL;
}