使用DateInterval和DateTime :: add添加月份时会出现什么问题?

时间:2012-02-14 18:36:15

标签: php datetime dateinterval

我未能找到解决此问题的正确方法。正如您在PHP文档中的示例#3中看到的那样,他们使用DateTime :: add中的DateInterval声明one must beware when adding months

对于为什么方法的行为是这样的,并且我可以做些什么来避免这种情况,我没有任何解释,我发现这是一个错误。

任何人都对此有所了解吗?

2 个答案:

答案 0 :(得分:7)

问题是每个月可能有不同的天数。问题是当你想把日期增加1个月时你正在做什么。根据PHP文档,如果您在1月31日(或30日)并且您添加1个月,那么预期的行为是什么?

二月只有29天。你想成为这个月的最后一天吗?如果这是您正在寻找的,或者基于当前日期的静态日期,您通常会在一定天数内增加安全性。当你增加月份时不知道你想要完成什么,很难说如何观察错误。

编辑:
正如有人在上面提到的Mike B评论的类似帖子中提到的那样,你可能想要做某些事情(伪代码):

 1) Use cal_days_in_month() for the next month and save that number to a variable x
 2) If x >= current billing DOB, increment and be done
 3) DateTime::modify('last day')  (havent used this before but something along these lines) to set the date to the last date of the next month (set it to the 1st of the next month, then last day?)

值得注意的是,如果您在此处使用变量作为新的结算值,则会清除原始值。我会保存一个额外的DB值,即“第一个开票日期”或者只是“billing_day_of_month”或者其他东西,然后用它来计算你应该看的月份日期

答案 1 :(得分:0)

如果您的目标是通过用户友好的月份严格增加(因此,1月21日的3个月应该是4月21日),但会员月的缩短时间缩短(因此,从1月31日起的1个月是2月28日/如果你越过下个月,你只需要回去几天:

function addMonths($date,$months) {
  $orig_day = $date->format("d");
  $date->modify("+".$months." months");
  while ($date->format("d")<$orig_day && $date->format("d")<5)
    $date->modify("-1 day");
}

$d = new DateTime("2000-01-31");
addMonths($d,1);
echo $d->format("Y-m-d"); // 2000-02-29