Php 菲律宾2月日;2015-01-31“+;1个月:;2015年3月30日;。如何修复?

Php 菲律宾2月日;2015-01-31“+;1个月:;2015年3月30日;。如何修复?,php,date,datetime,Php,Date,Datetime,如果我使用此代码,会得到奇怪的结果: $datetime = new DateTime('2015-01-31'); $datetime->modify('+1 month'); echo $datetime->format('Y-m-t') . "<br>"; $datetime->modify('+1 month'); echo $datetime->format('Y-m-t') . "<br>"; $datetime->modify(

如果我使用此代码,会得到奇怪的结果:

$datetime = new DateTime('2015-01-31');
$datetime->modify('+1 month');
echo $datetime->format('Y-m-t') . "<br>";
$datetime->modify('+1 month');
echo $datetime->format('Y-m-t') . "<br>";
$datetime->modify('+1 month');
echo $datetime->format('Y-m-t') . "<br>";
而不是
2015-02-28


如何修复?

如果您想获得下个月的最后一天,可以使用:

$datetime->modify('last day of next month');
像这样修理它

$datetime = new DateTime('2015-01-31');
$datetime->modify('28 days');
echo $datetime->format('Y-m-t') . "<br>";
$datetime->modify('+1 month');
echo $datetime->format('Y-m-t') . "<br>";
$datetime->modify('+1 month');
echo $datetime->format('Y-m-t') . "<br>";

按照
DateTime
的工作方式,
+1个月
会将月份值增加1,为您提供
2015-02-31
。由于2月只有28或29天,这将评估为3月的前几天。然后,如你所知,要求Y-m-t将给你3月的最后一天

由于您已经在使用
t
获取月的最后一天,因此可以通过将日期改为月初来避免此问题:

$datetime = new DateTime('2015-01-01');

参考:

您可以尝试使用此函数向datetime对象添加月份

    /**
 * 
 * @param \DateTime $date DateTime object
 * @param int $monthToAdd Months to add at time
 */
function addMonth(\DateTime $date, $monthToAdd)
{
    $year = $date->format('Y');
    $month = $date->format('n');
    $day = $date->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)) {
        $newDate = \DateTime::createFromFormat('Y-n-j', $year . '-' . $month . '-1');
        $newDate->modify('last day of');
    } else {
        $newDate = \DateTime::createFromFormat('Y-n-d', $year . '-' . $month . '-' . $day);
    }
    $newDate->setTime($date->format('H'), $date->format('i'), $date->format('s'));

    return $newDate->format('Y-m-d');
}

echo addMonth(new \DateTime('2015-01-30'), 1); //2015-02-28
echo addMonth(new \DateTime('2015-01-30'), 2); //2015-03-30
echo addMonth(new \DateTime('2015-01-30'), 3); //2015-04-30

你真是天才!!天才!!!天才!!!不完全是。。这通常不起作用。如果你已经知道你要处理的是一月,那么,为什么要用
DateTime
把你带到二月呢?最好选择一个简单的解决方案,它总是有效的,而且看起来总是一样的,就像mopo发布的那样。我说你是天才是在开玩笑。@all:这是真的bug吗?这显然破坏了可用性,也破坏了许多应用程序。这应该是公认的!
$datetime = new DateTime('2015-01-01');
    /**
 * 
 * @param \DateTime $date DateTime object
 * @param int $monthToAdd Months to add at time
 */
function addMonth(\DateTime $date, $monthToAdd)
{
    $year = $date->format('Y');
    $month = $date->format('n');
    $day = $date->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)) {
        $newDate = \DateTime::createFromFormat('Y-n-j', $year . '-' . $month . '-1');
        $newDate->modify('last day of');
    } else {
        $newDate = \DateTime::createFromFormat('Y-n-d', $year . '-' . $month . '-' . $day);
    }
    $newDate->setTime($date->format('H'), $date->format('i'), $date->format('s'));

    return $newDate->format('Y-m-d');
}

echo addMonth(new \DateTime('2015-01-30'), 1); //2015-02-28
echo addMonth(new \DateTime('2015-01-30'), 2); //2015-03-30
echo addMonth(new \DateTime('2015-01-30'), 3); //2015-04-30