PHP Carbon DateTime добавляет два месяца и полностью пропускает ноябрь

Мне нужно отобразить три календаря: один на текущий месяц, а два других на следующие два месяца.

Я использую Carbon для выполнения этих расчетов.

Сегодня 31 октября.

Если я напишу следующее

$carbon = Carbon::now('UTC'); // current datetime in UTC is 8:54 AM October 31, 2016
echo $carbon->format('F') . '<br>';
echo $carbon->addMonths(1)->format('F');

Я получаю этот вывод

Октябрь

Декабрь

Я полностью пропускаю ноябрь... так как мне добавить месяц к октябрю, чтобы я получил ноябрь.


person Jethro Hazelhurst    schedule 31.10.2016    source источник
comment
попробуйте addMonths(2) что такое возврат?   -  person Chonchol Mahmud    schedule 31.10.2016
comment
Не совсем уверен, но если отнять 1 день, а потом добавить месяц, что тогда получится?   -  person Epodax    schedule 31.10.2016
comment
@Epodax, хорошо поймал ... он показывает ноябрь, значит ли это, что что-то идет не так с расчетами Carbons?   -  person Jethro Hazelhurst    schedule 31.10.2016
comment
@Chonchol Mahmud, да, интересно, я все еще получаю декабрь, пишу ли я $carbon-›addMonths(1)-›format('F'); или $carbon-›addMonths(2)-›format('F');   -  person Jethro Hazelhurst    schedule 31.10.2016
comment
Я не использовал углерод раньше, но я предполагаю, что это потому, что у нас сегодня 31 октября, а в ноябре всего 30 дней, поэтому, добавив еще один месяц, он перескочил прямо на 1 декабря.   -  person Epodax    schedule 31.10.2016
comment
@JethroHazelhurst, я думаю, это проблема високосного года с углеродом :/   -  person Chonchol Mahmud    schedule 31.10.2016
comment
@JethroHazelhurst см. carbon.nesbot.com/docs в этой документации.   -  person Chonchol Mahmud    schedule 31.10.2016
comment
Хорошо, спасибо, Чончол!   -  person Jethro Hazelhurst    schedule 31.10.2016
comment
Интересное решение, Райан, я думаю, что это сработает, я видел аналогичный ответ здесь: stackoverflow.com/questions/40339468/, и это выглядит как жизнеспособное решение.   -  person Jethro Hazelhurst    schedule 31.10.2016


Ответы (2)


По умолчанию addMonths(1) добавляет к месяцу ровно 30 дней.

Чтобы добавить ровно один месяц (например, чтобы перейти с октября на ноябрь, независимо от того, 29/30/31 день), вам нужно покончить с addMonth() и вместо этого использовать addMonthsNoOverflow(n).

Так, например:

$carbon = Carbon::now('UTC'); // current datetime in UTC is 8:54 AM October 31, 2016
echo $carbon->format('F') . '<br>';
echo $carbon->addMonths(1)->format('F');

неожиданно выводит:

октябрь декабрь

Тогда как

$carbon = Carbon::now('UTC'); // current datetime in UTC is 8:54 AM October 31, 2016
echo $carbon->format('F') . '<br>';
echo $carbon->addMonthsNoOverflow(1)->format('F');

Правильно выводит:

Октябрь ноябрь

Такое поведение связано не с Carbon, а с классом datetime PHP, на котором он построен.

Причина, по которой addMonthsNoOverflow() НЕ является поведением по умолчанию, заключается в том, что это было бы «критическим изменением».

Подробнее об этом можно прочитать в этой беседе на Github: https://github.com/briannesbitt/Carbon/issues/627

person Jethro Hazelhurst    schedule 31.10.2016

Это ошибка в базовой библиотеке php: \DateTime

в вашем наборе кода запуска php:

Carbon:: useMonthsOverflow(false);

Чтобы решить эту проблему и просто иметь возможность использовать addMonths() вместо этого.

Предупреждение, хотя это может нарушить существующий код, зависящий от Carbon, если он у вас есть.

person Joel Harkes    schedule 31.10.2018