Краткий ответ:
В примере результатом будет последний день февраля, 2012-02-29
.
Объяснение:
Вопрос «какая дата получится, если добавить месяц» может быть открытым для интерпретации. Чтобы избежать этого, java.time
API имеет очистить правило. Результат будет иметь тот же день месяца, что и ввод, если только это не будет недопустимой датой, и в этом случае результатом будет последний день месяца.
Таким образом, 31 января плюс один месяц дадут 31 февраля, но, поскольку это недопустимая дата, результатом будет последняя действительная дата в феврале, то есть 28 или 29 февраля, в зависимости от того, високосный ли это год:
// normal case
2011-01-15 plus 1 month = 2011-02-15 // 15 Jan -> 15 Feb
// special rule choosing the last valid day-of-month
2011-01-31 plus 1 month = 2011-02-28 // 31 Jan -> 28 Feb (2011 is normal year)
2012-01-31 plus 1 month = 2012-02-29 // 31 Jan -> 29 Feb (2012 is leap year)
// same rule applies for months other than February
2013-03-31 plus 1 month = 2013-04-30 // 31 Mar -> 30 Apr (only 30 days in April)
То же правило применяется при добавлении одного месяца или нескольких месяцев и всегда основывается на полученном месяце. т.е. сначала добавляется месяц (при необходимости корректируя год), и только потом учитывается день месяца. Это же правило действует и при вычитании.
// multiple months works on the month of the result
2013-10-31 plus 4 months = 2014-02-28 // last day of February
2013-10-31 minus 4 months = 2013-06-30 // last day of June
Те же правила действуют и при прибавлении/вычитании лет к/от даты - годы прибавляются, и только потом день месяца проверяется на достоверность в пределах месяца.
// years use the same rule
2012-02-29 plus 1 year = 2013-02-28 // 29th February invalid so adjusted to 28th
Если вашей бизнес-логике требуется другое правило для добавления месяца, лучший подход — написать TemporalAdjuster
или TemporalAmount
, которые упаковывают вашу специальную логику.
person
JodaStephen
schedule
09.03.2014