PHP - 智能添加月份

时间:2017-06-09 16:04:22

标签: php date

我刚刚发现了一个常用方法的问题,即将月份加到PHP日期。如果你在谷歌或这个论坛上搜索,你通常会找到这样的东西:

$date = strtotime(date("Y-m-d", strtotime($date)) . " +1 month");

$months = DateInterval::createFromDateString('1 month');
$dateInDateTime->add($months);

在我看来,这两种方法都不正确。

例如,在我的代码中,我必须从4月的最后一天开始的月份增加3倍,并返回该月的最后一天。 所以我的代码生成了这个结果:

  • 2017-04-30
  • 2017-05-31
  • 2017年7月31日

脚本第二次添加+1个月,从2017-05-31到2017-07-01,因为31-05 + 30天超过了6月的最后一天。

我期待的是06-30,因为你总结了MONTHS而不是DAYS,如果你有溢出,代码必须纠正它,而不是我。 当您管理二月或十二月(由于年度变化)时,这是一个常见的错误。

我期待一个增加月份的脚本。所以,如果我有2017-03-23和+1个月的总和,我得到2017-04-23,如果我总和+1月到2017-03-31我得到了2017-04-30。

因此。使用此功能时请注意。

3 个答案:

答案 0 :(得分:0)

我认为你正在尝试危险的事情。

2月份发生了什么事?如果您希望所有时间只更改月份数​​,它将在本月的最后几天中断,相同的月份为30天而不是31 ...

您必须以另一种方式考虑您的方法,因为单独更改月份有时不会创建现有日期。

+30天似乎是最好的事情

答案 1 :(得分:0)

  

我期待的是06-30,因为你总结了MONTHS而不是DAYS,如果你有溢出,代码必须纠正它,而不是我。

PHP确实纠正了它。它永远不会返回6月的31 st ,因为这样的日期不存在。它将其修正为7月的1 st

您显然期望的是,当您在一个月的最后一天添加1个月以获得下个月的最后一天时。但这没有任何意义。

strtotime('2017-06-30 +1 month')应该返回什么?

2017-07-31,因为您要在6月的最后一天或2017-07-30添加1个月,因为您要在6月的30 th 日加1个月?

时间向前发展,从月底开始计算天数并不自然。有时它很有用但不是很多次。并且始终有一个更好的解决方案:从下个月的第一天减去1天。通过这种方式,您无需对具有不同天数甚至闰年的月份进行任何更正或关注。

答案 2 :(得分:-1)

这是我写的函数:

  //it accept negative month value
public static function realAddMonthsToDate($month,$dateToModify, 
    $dateFormatInput = DEFAULT_SQL_DATE_FORMAT, $dateFormatOutput = DEFAULT_SQL_DATE_FORMAT)
    {
        $currentDate = DateTime::createFromFormat($dateFormatInput, $dateToModify);
        $cDay = $currentDate->format('d');
        $cMonth = $currentDate->format('m');
        $cYear  = $currentDate->format('Y');
        $monthRest = $month;
        $yearOffset = 0;
        if ($month > 12)
        {
            $yearOffset = floor($month / 12);
            $monthRest = $month - ($yearOffset * 12);
        }

        $cMonth += $monthRest;
        if ($cMonth > 12) {
            $cMonth = $cMonth - 12;
            $cYear += 1;
        }
        if ($cMonth <= 0)
        {
            $cMonth = 12 + $cMonth;
            $cYear -= 1;
        }
        $cYear += $yearOffset; 

        $arrivalMonthDays = cal_days_in_month(CAL_GREGORIAN, $cMonth, $cYear);
        if ($cDay >= $arrivalMonthDays) $cDay = $arrivalMonthDays;
        $newDate = new DateTime($cYear.'-'.$cMonth.'-'.$cDay);
        return $newDate->format($dateFormatOutput);
    }