When using java.time.Period.between()
across months of varying lengths, why does the code below report different results depending on the direction of the operation?
import java.time.LocalDate;
import java.time.Period;
class Main {
public static void main(String[] args) {
LocalDate d1 = LocalDate.of(2019, 1, 30);
LocalDate d2 = LocalDate.of(2019, 3, 29);
Period period = Period.between(d1, d2);
System.out.println("diff: " + period.toString());
// => P1M29D
Period period2 = Period.between(d2, d1);
System.out.println("diff: " + period2.toString());
// => P-1M-30D
}
}
Live repl: https://repl.it/@JustinGrant/BigScornfulQueryplan#Main.java
Here's how I'd expect it to work:
2019-01-30 => 2019-03-29
- Add one month to 2019-01-30 => 2019-02-30, which is constrained to 2019-02-28
- Add 29 days to get to 2019-03-29
This matches Java's result: P1M29D
(reversed) 2019-03-29 => 2019-01-30
- Subtract one month from 2019-03-29 => 2019-02-29, which is constrained to 2019-02-28
- Subtract 29 days to get to 2019-01-30
But Java returns P-1M-30D
here. I expected P-1M-29D
.
The reference docs say:
The period is calculated by removing complete months, then calculating the remaining number of days, adjusting to ensure that both have the same sign. The number of months is then split into years and months based on a 12 month year. A month is considered if the end day-of-month is greater than or equal to the start day-of-month. For example, from
2010-01-15
to2011-03-18
is one year, two months and three days.
Maybe I'm not reading this carefully enough, but I don't think this text fully explains the divergent behavior that I'm seeing.
What am I misunderstanding about how java.time.Period.between
is supposed to work? Specifically, what is expected to happen when the intermediate result of "removing complete months" is an invalid date?
Is the algorithm documented in more detail elsewhere?