PHP DateTime子项产生意外结果

时间:2016-06-01 15:43:10

标签: php date datetime dateinterval

我有以下示例从DateTimeImmutable

中减去DateInterval
    $dateA = new DateTimeImmutable('2016-06-30');
    $dateB = new DateTimeImmutable('2016-05-31');
    $dateInterval = new DateInterval('P3M');
    // print 2016-03-30 as expected
    echo $dateA->sub($dateInterval)->format('Y-m-d'); 
    // print 2016-03-02 which i would expect 2016-02-29
    echo $dateB->sub($dateInterval)->format('Y-m-d');

当我将句点设置为'P8M'时,它按预期工作。它是怎么来的,它适用于二月?

2 个答案:

答案 0 :(得分:2)

好的,它非常简单(有点)。每个月“#39;区间评估为当月(或之前的X个数字)的等效日。如果当月有更多的天数,那么超出的月份将超过下个月。

因此,如果您的日期是2016年5月31日,并希望减去3个月的间隔,则会:

  • 回去3个月(在几个月的列表中,不要再想几天),导致二月'
  • 然后寻找2月31日。这种情况不会在接下来的第2个月出现(2016年2月有29天,所以额外增加2天)
  • 中提琴! 3月2日。

前进,让我们说你在2016年5月31日,并希望增加一个月

  • 一个月前往六月。
  • 寻找6月31日,不,再加1天,流到7月。
  • 正如所料,7月1日就是答案。

上面的教训:添加和减去月份间隔很糟糕,令人困惑,并且可能导致不直观的结果,除非您已经计算了月份计算结果。

答案 1 :(得分:0)

来自PHP Docs

的说明
  

注意:   相对月份值是根据它们经过的月份长度计算的。一个例子是" + 2个月2011-11-30",这将产生" 2012-01-30"。这是因为11月是30天,12月是31天,总共61天。