4

我未能找到解决此问题的适当方法。正如您在 PHP 文档中的示例 #3 中看到的,他们声明在使用 DateTime::add 中的 DateInterval添加月份时必须小心。

对于该方法的行为为何如此以及我可以做些什么来避免这种情况,并没有真正的任何解释,我乍一看发现这是一个错误。

有人对此有所了解吗?

4

2 回答 2

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”或其他东西,并用它来确定您应该查看的月份中的哪一天

于 2012-02-14T18:44:42.717 回答
0

如果您的目标是严格按用户友好的月份递增(因此,从 1 月 21 日开始的 3 个月应该是 4 月 21 日),但较短的会员月份会缩短(因此,从 1 月 31 日开始的 1 个月是 2 月 28 日/29 日),那么如果你跨到下个月,你只需要回去几天:

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
于 2016-11-29T23:18:29.167 回答