简体   繁体   English

DateTime 修改 function 跳过二月

[英]DateTime modify function skips February

When adding a month to with DateTime::modify method, the result skips February.使用DateTime::modify方法添加一个月时,结果会跳过二月。

  • Why isn't it outputing 2020-02-31 ?为什么不输出2020-02-31
  • How to output 2020-02-29 using DateTime?如何使用日期时间 output 2020-02-29 (Last day of the month). (当月的最后一天)。
$date = new DateTime("2020-01-31");
echo $date->modify("+1 month")->format("Y-m-d"); // 2020-03-02

PHP DateTime::modify("+n month") adds between 28 to 31 days to the current day, depending of the month and year. PHP DateTime::modify("+n month")将 28 到 31 天添加到当前日期,具体取决于月份和年份。

Solution解决方案

I suggest you increment months from the first day of the month by using the modify and format methods:我建议您使用modifyformat方法从每月的第一天开始增加月份:

// Instanciates the DateTime object.
$date = new DateTime("2020-01-01");

// Adds a month to the date.
$date->modify("+1 month"); // 2020-02-01

// Format the date with "t" (gets the last day of the month).
$date->format("Y-m-t"); // 2020-02-29

Incrementing from the first day of the month will never raise the February problem which is quite a quite common, thinking that PHP DateTime will smartly add a month from 2020-02-29 and output 2020-03-31 .从当月的第一天开始递增永远不会引发相当普遍的二月问题,认为 PHP DateTime 将从2020-02-29和 output 2020-03-31巧妙地添加一个月。

Why it happens?为什么会发生?

In the Gregorian calendar , the average length of a month is 30.436875 days:公历中一个月的平均长度是 30.436875 天:

  • 30 days in April, June, September and November; 4月、6月、9月和11月30天;
  • 31 days in January, March, May, July, August, October and December;一月、三月、五月、七月、八月、十月和十二月共31天;
  • 28 days or 29 days (in leap years ) in February. 2 月 28 天或 29 天(闰年)。

PHP will add to the current date the exact number of days there is in the given month. PHP 会将给定月份的确切天数添加到当前日期。

Thus, PHP will adjust the date after the first increntation if you are incrementing from the last day of the month.因此,如果您从该月的最后一天开始递增,PHP 将在第一次递增之后调整日期。

Eg:例如:

Let's add a month from the final day of March (31th).让我们从 3 月的最后一天(31 日)开始添加一个月。

Since the current month (March) has 31 days in it, PHP will increment 31 days to the date.由于当前月份(三月)有 31 天,PHP 将增加 31 天到该日期。 Adding 31 days from 2020-03-31 will result in skipping the whole month of April.2020-03-31添加 31 天将导致跳过整个 4 月。

$date = new DateTime("2020-03-31");              // 2020-03-31
echo $date->modify("+1 month")->format("Y-m-d"); // 2020-05-01 | Added 31 days (since March has 31 days).
echo $date->modify("+1 month")->format("Y-m-d"); // 2020-06-01 | Added 31 days (since the new date is May 1st, which is a month with 31 days).
echo $date->modify("+1 month")->format("Y-m-d"); // 2020-07-01 | Added 30 days

Now, let's add a month to the final day of April (30th).现在,让我们在 4 月的最后一天(30 日)加上一个月。

We can see that since the next months all have 30+ days in it, final day will stay the same, until February of the next year .我们可以看到,由于接下来的几个月都有 30+ 天,所以最后一天将保持不变,直到明年 2 月 Since February always has between 28 and 29 days, adding 31 days to it will pass the month, and resulting date will be March 2nd.由于二月总是有 28 到 29 天,再加上 31 天,这个月就过去了,结果日期就是 3 月 2 日。

$date = new DateTime("2020-04-30");
echo $date->modify("+1 month")->format("Y-m-d"); // 2020-05-30 | Added 30 days.
echo $date->modify("+1 month")->format("Y-m-d"); // 2020-06-30 | Added 31 days.
echo $date->modify("+1 month")->format("Y-m-d"); // 2020-07-30 | Added 30 days.
// ...
echo $date->modify("+1 month")->format("Y-m-d"); // 2021-01-30 | Added 31 days
echo $date->modify("+1 month")->format("Y-m-d"); // 2021-03-02 | Added 31 days (since January has 31 days).
echo $date->modify("+1 month")->format("Y-m-d"); // 2021-04-02 | Added 31 days (since the new date is March 2nd, which is a month with 31 days).

This is why it is recommended to increment months from the first day of the month, since the 1st is common to all months.这就是为什么建议从每月的第一天开始增加月份的原因,因为第一天对所有月份都是通用的。

$date = new DateTime("2020-01-01");              // 2020-01-01
echo $date->modify("+1 month")->format("Y-m-d"); // 2020-02-01 | Added 31 days
echo $date->modify("+1 month")->format("Y-m-d"); // 2020-03-01 | Added 29 days (since 2020 is leap year, yee haw).
echo $date->modify("+1 month")->format("Y-m-d"); // 2020-04-01 | Added 31 days

I'm making an assumption that you are programming in php.我假设您正在 php 中编程。 If so, the documentation indicates that you will receive the results you are getting php DateTime::modify() .如果是这样,文档表明您将收到php DateTime::modify()的结果。

The documentation specifically indicates to "Beware"该文档特别指出“当心”

Example #2 Beware when adding or subtracting months Example #2 加减月份时要小心

 <?php
 $date = new DateTime('2000-12-31');

 $date->modify('+1 month');
 echo $date->format('Y-m-d') . "\n";

 $date->modify('+1 month');
 echo $date->format('Y-m-d') . "\n";
 ?>
 The above example will output:

 2001-01-31
 2001-03-03

If you just need to move to the end of the next +1 month, what we often do in R is go to the end of the current month and then add +1 day and then go to the end of the month again.如果你只需要移动到下一个+1月的月底,我们在R中经常做的就是go到当月的月底,然后再加上+1天,然后Z34D1F91FB2E514B8576FAB1A7B的月底再加Z34D1F91FB2E514B8576FAB1A7B。 If you know that you are always at the end of the month, then just add +1 day and then go to the end of the month.如果您知道您总是在月末,那么只需添加 +1 天,然后 go 到月末。

Other posts have some additional suggestions in this space How to find the last day of the month from date?其他帖子在这个空间有一些额外的建议如何找到从日期开始的月份的最后一天?

Example from this post:这篇文章的例子:

 $date = new DateTime('now');
 $date->modify('last day of this month');
 echo $date->format('Y-m-d');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM