In java.time, how is the result of adding a month calculated?
Asked Answered
P

1

24

In the JSR-310 java.time API in JDK 8, what are the rules for calculating the result of adding a month to a date. In particular, what happens when you add 1 month to a date like January 31st?

LocalDate initial = LocalDate.of(2012, 1, 31);  // 31st January 2012
LocalDate result = initial.plusMonths(1);
// what is the result?
Protractile answered 9/3, 2014 at 0:30 Comment(0)
P
26

Short answer:

In the example, the result will be the last day of February, 2012-02-29.

Explanation:

The question, "what date do you get if you add a month", is one which could be open to interpretation. To avoid this, the java.time API has a clear rule. The result will have the same day-of-month as the input, unless that would be an invalid date, in which case the result is the last day of the month.

Thus, the 31st January plus one month would result in the 31st February, but since that is an invalid date, the result is the last valid date in February, which is 28th or 29th February depending on whether it is a leap year:

// 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)

The same rule applies whether adding one month or many months and is always based on the resulting month. ie. the month is added first (adjusting the year if necessary), and only then is the day-of-month considered. The same rule also applies when subtracting.

// 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

The same rules also apply when adding/subtracting years to/from a date - the years are added, and only then is the day-of-month checked for validity within the month.

// years use the same rule
2012-02-29 plus 1 year = 2013-02-28  // 29th February invalid so adjusted to 28th

If your business logic needs a different rule for month addition, the best approach is to write a TemporalAdjuster or TemporalAmount that packages up your special logic.

Protractile answered 9/3, 2014 at 0:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.