I see that java.time.Period with java.time.LocalDates works mostly as desired and I can use it to get the duration between two dates in years, months and days but I found an example that is not working (not as I expected it), like following:
val test1 = LocalDate.of(2023, 1, 31)
val test2 = LocalDate.of(2023, 1, 28)
val testToday = LocalDate.of(2023, 3, 9)
val period1 = Period.between(test1, testToday)
val period2 = Period.between(test2, testToday)
L.d { "test1 = $test1 | test2 = $test2 | today = $testToday" }
L.d { "period1 = $period1 | period2 = $period2" }
Output is following:
period1 = P1M9D | period2 = P1M9D
test1 = 2023-01-31 | test2 = 2023-01-28 | today = 2023-03-09
Problem
The solution above tells me following:
- Duration between 2023-01-31 and 2023-03-09 => 1 month and 9 days (P1M9D)
- Duration between 2023-01-28 and 2023-03-09 => 1 month and 9 days (P1M9D)
=> but this is wrong, the second one should show 3 days more as duration... Is there an explanation for this?
The "problem" is the way
Period.betweenperforms its calculation:This results in 2023-01-28 until 2023-01-01 counting as 1 month and 1 day (P1M1D), but so will 2023-01-29, 30, and 31. This is because 2023-01-31 plus 1 month is 2023-02-31, which is invalid, so it uses 2023-02-28 (and same for 29 and 30, and of course 28). In other words, there is 1 full month, which ends on 2023-02-28, and then there are 9 more days until 2023-03-09 (exclusive).
This conforms to the behaviour documented for
LocalDate.plusMonths: