Php 如何在不跳过日期(即2月)的情况下在日期上添加1个月

Php 如何在不跳过日期(即2月)的情况下在日期上添加1个月,php,datetime,Php,Datetime,可能重复: 我有一个开始日期(即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 问题是,我需要它使用以

可能重复:

我有一个开始日期(即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,而在日部分加1 (2011-01-15将成为2011-02-15)
  • 如果该日在我们将结束的月份中不存在,则取该日存在的最后一天 (2011-01-30将变为2011-02-28)
php中是否有一个通用函数可以实现这一点,或者我必须自己编写代码?
也许我只是缺少了一个参数或什么

除了DateInterval之外,您还有几个选择

下面是使用
strotime()
的示例:

以下是有关
DateInterval
的一些链接:

问:你如何定义“月”

定义1:“月”是一个“月”-不管#/天

定义2:“月”是30天(例如)

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

等等等等


问:你的“定义”到底是什么?好吧-据我所知,你还没有明确定义“月”是什么意思

但这里还有一个功能可能会有所帮助:


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

此函数计算添加月份后我将结束的月份和年份。然后检查日期是否正确。如果不是,我们就有一种情况,那就是当天不在目标月份,所以我们选择该月份的最后一天。 使用PHP5.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');

如果您要迭代多个月,您需要小心不要在28日被“卡住”。e、 如果你从1/30开始。。2/28 .. 3/28,当你可能想要3/30的时候。我最近处理了这个问题,实现了一个商业计费系统。没有预先烘焙的解决方案。你必须记录你的开始日期,增加月份,看看下个月是否有这一天,如果没有,使用该月的最后一天。这其实并不复杂,但感觉不必写那么多代码。这里的要求是添加日历月。跳到每月的第一天,加上你想要的月份,然后跳回到你开始的日期,或者如果月份短于开始的日期,跳回到新月份的最后一天。这里也一样。如果我尝试:$date=“2011-01-30”$newdate=strottime('+1个月',strottime($date));回显日期('Y-m-d',$newdate);我得到的是2011-03-02,而不是我需要的2011-02-28,你可以从我的问题中看到,我使用了你的Def#1。如果你使用的是strotime(),那么避免跳过2月份的最好方法是添加$date=strotime(+1个月的第一天);完美的我需要这个,但时间段是互斥的——我刚刚添加了
$day=$day-1
$day=$d1>格式('d')之后某些负值问题:替换
$year+=floor($monthToAdd/12)
$year+=$monthToAdd>=0?楼层($monthToAdd/12):ceil($monthToAdd/12)
if(!checkdate())
之前,添加以下内容:
if($month<0){$month=12+$month%12;$year-->}
。使用PHP5.6.29进行测试。希望它能帮助别人。
// Subtracting months from a date
$date = "1998-08-14";
$newdate = strtotime ( '-3 month' , strtotime ( $date ) ) ;
$newdate = date ( 'Y-m-j' , $newdate );

echo $newdate;
/* Function to find the first and last day of the month from the given date.
*
* Author Binu v Pillai            binupillai2003@yahoo.com
* @Param            String             yyyy-mm-dd
*
*/
function findFirstAndLastDay($anyDate)
{
    //$anyDate            =    '2009-08-25';    // date format should be yyyy-mm-dd
    list($yr,$mn,$dt)    =    split('-',$anyDate);    // separate year, month and date
    $timeStamp            =    mktime(0,0,0,$mn,1,$yr);    //Create time stamp of the first day from the give date.
    $firstDay            =     date('D',$timeStamp);    //get first day of the given month
    list($y,$m,$t)        =     split('-',date('Y-m-t',$timeStamp)); //Find the last date of the month and separating it
    $lastDayTimeStamp    =    mktime(0,0,0,$m,$t,$y);//create time stamp of the last date of the give month
    $lastDay            =    date('D',$lastDayTimeStamp);// Find last day of the month
    $arrDay                =    array("$firstDay","$lastDay"); // return the result in an array format.

    return $arrDay;
}
<?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');