碳 - 为什么addMonths()改变了月份的日期?

Lim*_*nte 7 php datetime date laravel php-carbon

这是一个简单的例子(今天是2016-08-29):

var_dump(Carbon::now());
var_dump(Carbon::now()->addMonths(6));
Run Code Online (Sandbox Code Playgroud)

输出:

object(Carbon\Carbon)#303 (3) {
  ["date"] => string(26) "2016-08-29 15:37:11.000000"
}
object(Carbon\Carbon)#303 (3) {
  ["date"] => string(26) "2017-03-01 15:37:11.000000"
}
Run Code Online (Sandbox Code Playgroud)

因为Carbon::now()->addMonths(6)我期待2017-02-29,不是2017-03-01.

我错过了有关日期修改的内容吗?

Ale*_*hov 11

它甚至比那更残缺 - 减法有同样的问题.但是有一些特殊方法可以避免溢出:

function original(){ 
    return new Carbon('2016-08-31'); 
};
function print_dt($name, $date){ 
    echo $name . $date->toAtomString() . PHP_EOL; 
};

print_dt('original:            ', original());
echo '-----' . PHP_EOL;
print_dt('addMonths:           ', original()->addMonths(6));
print_dt('addMonthsNoOverflow: ', original()->addMonthsNoOverflow(6));
echo '-----' . PHP_EOL;
print_dt('subMonths:           ', original()->subMonths(2));
print_dt('subMonthsNoOverflow: ', original()->subMonthsNoOverflow(2));
Run Code Online (Sandbox Code Playgroud)

输出:

original:            2016-08-31T00:00:00+00:00
----- 
addMonths:           2017-03-03T00:00:00+00:00
addMonthsNoOverflow: 2017-02-28T00:00:00+00:00
----- 
subMonths:           2016-07-01T00:00:00+00:00
subMonthsNoOverflow: 2016-06-30T00:00:00+00:00
Run Code Online (Sandbox Code Playgroud)


RIa*_*lis 9

没有2/29/2017.闰年发生在2016年.

以下链接:

http://carbon.nesbot.com/docs/#api-addsub

提供了一个添加1个月到2012年1月31日并在2012年3月3日到达的示例.这是有意的,虽然看起来让我感到困惑.


作为一个展示不同行为的反例,在SQL中:

SELECT dateadd(m,1,'2012-01-31') 
Run Code Online (Sandbox Code Playgroud)

结果是在2012年2月29日,所以检查您计划使用的任何addmonth()函数的规范是个好主意.