Carbon – почему addMonths () меняет день месяца?

Вот простой пример (сегодня – 2016-08-29):

var_dump(Carbon::now()); var_dump(Carbon::now()->addMonths(6)); 

Вывод:

 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" } 

Для Carbon::now()->addMonths(6) Я ожидаю 2017-02-29 , а не 2017-03-01 .

Я что-то пропустил о модификациях даты?

Нет 2/29/2017. Високосный год произошел в 2016 году.

Следующая ссылка:

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

дает пример добавления от 1 месяца до 1/31/2012 и прибытия 3/3/2012. Которое предназначено, хотя мне кажется смущенным.

Как встречный пример, демонстрирующий различное поведение, в SQL:

 SELECT dateadd(m,1,'2012-01-31') 

результаты в 2/29/2012, поэтому было бы неплохо проверить спецификации любой функции addmonth (), которую вы планируете использовать.

Это еще больше искалечено. И есть специальный метод, чтобы избежать переполнения:

 $original = new Carbon('2016-08-31'); echo 'original: ' . $original->toAtomString() . PHP_EOL; echo '----- ' . PHP_EOL; echo 'addMonths: ' . (new Carbon($original))->addMonths(6)->toAtomString() . PHP_EOL; echo 'addMonthsNoOverflow: ' . (new Carbon($original))->addMonthsNoOverflow(6)->toAtomString() . PHP_EOL; echo '----- ' . PHP_EOL; echo 'subMonths: ' . (new Carbon($original))->subMonths(2)->toAtomString() . PHP_EOL; echo 'subMonthsNoOverflow: ' . (new Carbon($original))->subMonthsNoOverflow(2)->toAtomString() . PHP_EOL; 

вывод:

 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