DateTime :: diff意外结果 [英] DateTime::diff unexpected results
问题描述
我有以下计算,我希望返回0。但是在许多我可以访问的系统上,它返回1:
I have the following calculation, which I expect to return 0. However it returns 1 on many systems I have access to:
Ubuntu 16.04服务器(错误)
Ubuntu 16.04 server (wrong)
php -v
PHP 7.0.22-0ubuntu0.16.04.1 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.0.22-0ubuntu0.16.04.1, Copyright (c) 1999-
2017, by Zend Technologies
echo "<?php echo DateTime::createFromFormat('Y-m-d H:i:s', '2017-12-01 00:00:00')->diff(DateTime::createFromFormat('Y-m-d H:i:s', '2017-12-31 23:59:59' ))->format('%m');"|php
1
来自deb.sury.org的PHP 7.1(带有Xdebug)
PHP 7.1 from deb.sury.org with Xdebug (wrong)
php -v
PHP 7.1.6-1~ubuntu16.04.1+deb.sury.org+1 (cli) (built: Jun 9 2017
08:26:34) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.1.6-1~ubuntu16.04.1+deb.sury.org+1, Copyright
(c) 1999-2017, by Zend Technologies
with Xdebug v2.5.4, Copyright (c) 2002-2017, by Derick Rethans
echo "<?php echo DateTime::createFromFormat('Y-m-d H:i:s', '2017-12-01 00:00:00')->diff(DateTime::createFromFormat('Y-m-d H:i:s', '2017-12-31 23:59:59' ))->format('%m');"|php
1
phpfiddle.org
phpfiddle.org
->按预期返回0
日期的时区相同
推荐答案
来自 DateInterval :: format
:
DateInterval :: format ()方法不会重新计算时间字符串或日期段中的结转点。这是预料之中的,因为不可能溢出 32天之类的值,该值可以解释为从 1个月4天到 1个月1天的任何值。
The DateInterval::format() method does not recalculate carry over points in time strings nor in date segments. This is expected because it is not possible to overflow values like "32 days" which could be interpreted as anything from "1 month and 4 days" to "1 month and 1 day".
所以必须重新计算结转点。以下是中的相关代码 DateInterval :: format
:
So one has to recalculate carry over points. Below is the relevant code from DateInterval::format
:
class DateIntervalEnhanced extends DateInterval {
public function recalculate() {
$from = new DateTime;
$to = clone $from;
$to->add($this);
$diff = $from->diff($to);
foreach ($diff as $k => $v) $this->$k = $v;
return $this;
}
}
实用函数:
function myFormatter($d1, $d2, $format) {
$diff = strtotime($d1) - strtotime($d2);
$df = abs($diff);
$di = new DateIntervalEnhanced("PT${df}S");
$di->invert = $diff < 0;
return $di->recalculate()->format($format);
}
echo myFormatter("2017-12-31 23:59:59", "2017-12-01 00:00:00", "%m");
DEMO
Link to a post you might wanna read
这篇关于DateTime :: diff意外结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!