【问题标题】:Is this a bug in PHP's DateTime:diff?这是 PHP 的 DateTime:diff 中的错误吗?
【发布时间】:2012-04-11 15:41:35
【问题描述】:
>> $start_dt = new DateTime()
DateTime::__set_state(array(
   'date' => '2012-04-11 08:34:01',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
>> $end_dt = new DateTime()
DateTime::__set_state(array(
   'date' => '2012-04-11 08:34:06',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
>> $start_dt->setTimestamp(strtotime('31-Jan-2012'))
DateTime::__set_state(array(
   'date' => '2012-01-31 00:00:00',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
>> $end_dt->setTimestamp(strtotime('1-Mar-2012'))
DateTime::__set_state(array(
   'date' => '2012-03-01 00:00:00',
   'timezone_type' => 3,
   'timezone' => 'America/Los_Angeles',
))
>> $interval = $start_dt->diff($end_dt)
DateInterval::__set_state(array(
   'y' => 0,
   'm' => 0,
   'd' => 30,
   'h' => 0,
   'i' => 0,
   's' => 0,
   'invert' => 0,
   'days' => 30,
))
>> $interval->format('%mm %dd')
'0m 30d'

即,31-Jan-20121-Mar-2012 的收益不到一个月!我希望输出为 1 个月 1 天。二月的天数无关紧要;这就是使用时间库的重点——它应该处理这些事情。 WolframAlpha agrees.

我应该向 PHP 提交错误吗?是否有破解/修复/解决方法可以让几个月按预期工作?

【问题讨论】:

    标签: php datetime date time date-math


    【解决方案1】:

    更新答案

    DateTime::diff 的这种行为当然是出乎意料的,但这不是错误。简而言之,diff 返回年、月、日等,如果你这样做了

    $end_ts = strtotime('+$y years +$m months +$d days' /* etc */, $start_ts);
    

    您将取回与结束原始结束日期相对应的时间戳。

    这些添加是“盲目”执行的,然后应用日期更正(例如,1 月 31 日 + 1 个月将是 2 月 31 日,根据年份更正为 3 月 2 日或 3 月 3 日)。在这个具体的例子中,你甚至不能像salathe 解释的那样添加一个月。

    【讨论】:

    • 12 月 1 日在间隔 (example) 中显示 10 个月。
    • 我认为月份和年份没有固定的天数。如果您询问几个月,它应该计算两个日期之间的日历个月数;多年来相同。 是使用库的优势;如果我想要一个“目标”(阅读:一致)天数,我只需将我的两个时间戳除以2629743.83
    • 我明白你现在在说什么……但它是如何提出来的更有意义。真可惜。我想我必须想出一个不同的解决方案来解决我的问题;也许我只是把月份数字减去。
    【解决方案2】:

    我应该向 PHP 提交错误吗?

    没有。

    间隔的“月”部分表示开始日期的月部分可以增加那么多个月。 PHP 中的行为,将您的开始日期设为 31-Jan-2012 并增加月份(字面意思是 31-Feb-2012),然后更正一个有效日期(PHP 为您执行此操作)将给出晚于目标日期的 02-Mar-2012你正在使用的。

    为了证明这一点,请获取您的开始日期并添加 n 个月的几个月以查看行为。

    31-Jan-2012 (Interval)
    02-Mar-2012 (P1M)
    31-Mar-2012 (P2M)
    01-May-2012 (P3M)
    31-May-2012 (P4M)
    01-Jul-2012 (P5M)
    

    您可以看到月份正在递增,然后调整为有效日期。

    【讨论】:

    • +1 因为这是正确的答案——我过去曾遇到过这种行为,但由于文档不够出色,我没有发现这一点。谢谢你的光。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 2013-05-04
    • 2011-09-28
    • 2017-07-23
    • 2012-09-15
    • 2017-03-22
    相关资源
    最近更新 更多