如何在不跳过的日期添加1个月,即2月

2022-08-30 20:03:04

可能的重复:
PHP 日期时间::修改添加和减去月份

我有一个开始日期(即2011-01-30),并希望增加1个月。

问题在于定义什么是月。因此,如果我使用以下代码:

$d1 = DateTime::createFromFormat('Y-m-d H:i:s', '2011-01-30 15:57:57');
$d1->add(new DateInterval('P1M'));
echo $d1->format('Y-m-d H:i:s');

我得到以下结果: 2011-03-02 15:57:57

问题是,我需要它来使用以下规则:

  • 如果我添加1个月,它将只在月份部分添加1并离开日部分(2011-01-15将变成2011-02-15)
  • 如果该日不存在,我们将在该月结束,我们采取它的最后一天(2011-01-30将变为2011-02-28)

php中是否有一个通用函数可以做到这一点,或者我必须自己编写代码吗?也许我只是缺少一个参数或其他东西!?


答案 1

似乎没有现成的功能,所以我自己写了它。这应该可以解决我的问题。无论如何,感谢您的回答和评论。如果您发现一些错误,请在评论中提供。

此函数计算添加某个月份后我将结束的月份和年份。然后,它会检查日期是否正确。如果不是,则会出现该天不在目标月份的情况,因此我们取该月的最后一天。使用 PHP 5.3.10 进行测试。

<?php
$monthToAdd = 1;

$d1 = DateTime::createFromFormat('Y-m-d H:i:s', '2011-01-30 15:57:57');

$year = $d1->format('Y');
$month = $d1->format('n');
$day = $d1->format('d');

$year += floor($monthToAdd/12);
$monthToAdd = $monthToAdd%12;
$month += $monthToAdd;
if($month > 12) {
    $year ++;
    $month = $month % 12;
    if($month === 0)
        $month = 12;
}

if(!checkdate($month, $day, $year)) {
    $d2 = DateTime::createFromFormat('Y-n-j', $year.'-'.$month.'-1');
    $d2->modify('last day of');
}else {
    $d2 = DateTime::createFromFormat('Y-n-d', $year.'-'.$month.'-'.$day);
}
$d2->setTime($d1->format('H'), $d1->format('i'), $d1->format('s'));
echo $d2->format('Y-m-d H:i:s');

答案 2

除了DateInterval之外,您还有其他几种选择。

以下是使用以下方法的示例:strtotime()

http://www.brightcherry.co.uk/scribbles/php-adding-and-subtracting-dates/

// Subtracting days from a date
$date = "1998-08-14";
$newdate = strtotime ( '-3 day' , strtotime ( $date ) ) ;
$newdate = date ( 'Y-m-j' , $newdate );

echo $newdate;

...

// Subtracting months from a date
$date = "1998-08-14";
$newdate = strtotime ( '-3 month' , strtotime ( $date ) ) ;
$newdate = date ( 'Y-m-j' , $newdate );

echo $newdate;

以下是一些链接:DateInterval

:您究竟如何定义“月”?

Def#1):“月”就是“月” - 无论 #/天

Def#2):“月”为30天(例如)

Def#3):“月”是后续月份的第一个星期一之间的#/天

等等等等

问:您的“定义”究竟是什么?


推荐