DateTime :: diff意外结果 [英] DateTime::diff unexpected results

查看:82
本文介绍了DateTime :: diff意外结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下计算,我希望返回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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆