PHP 日期时间::修改添加和减去月份

2022-08-30 07:15:56

我一直在使用DateTime类,最近在添加月份时遇到了一个我认为是错误的错误。经过一些研究,它似乎不是一个错误,而是按预期工作。根据此处找到的文档:

示例 #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

任何人都可以证明为什么这不被认为是一个错误?

此外,有没有人有任何优雅的解决方案来纠正这个问题,并使其+1个月将按预期工作,而不是按预期工作?


答案 1

为什么它不是一个错误:

当前行为是正确的。以下情况在内部发生:

  1. +1 month将月份编号(最初为 1)增加 1。这使得日期。2010-02-31

  2. 第二个月(2 月)在 2010 年只有 28 天,因此 PHP 通过继续计算从 2 月 1 日开始的天数来自动更正此情况。然后你最终在3月3日结束。

如何获得您想要的:

要获得您想要的东西,请通过以下方式:手动检查下个月。然后加上下个月的天数。

我希望你能自己编写这个代码。我只是在提供该做什么。

5.3 菲律宾比索方式:

要获得正确的行为,您可以使用 PHP 5.3 的新功能之一,该功能引入了相对时间节 。此节可以与 结合使用,或转到指定月份的第一天。您可以使用此代码来获取下个月的第一天,而不是从您正在执行的操作中,如下所示:first day ofnext monthfifth month+8 months+1 month

<?php
$d = new DateTime( '2010-01-31' );
$d->modify( 'first day of next month' );
echo $d->format( 'F' ), "\n";
?>

此脚本将正确输出 。当 PHP 处理此节时,会发生以下情况:Februaryfirst day of next month

  1. next month将月份编号(最初为 1)增加 1。这使得日期为2010-02-31。

  2. first day of将日期设置为 ,得到日期 2010-02-01。1


答案 2

这是另一个完全使用DateTime方法的紧凑型解决方案,无需创建克隆即可就地修改对象。

$dt = new DateTime('2012-01-31');

echo $dt->format('Y-m-d'), PHP_EOL;

$day = $dt->format('j');
$dt->modify('first day of +1 month');
$dt->modify('+' . (min($day, $dt->format('t')) - 1) . ' days');

echo $dt->format('Y-m-d'), PHP_EOL;

它输出:

2012-01-31
2012-02-29

推荐