-
Notifications
You must be signed in to change notification settings - Fork 119
Description
The purpose of DatePeriod
and DateTimePeriod
is to define the duration between two dates or instants, respectively. Intuitively, it makes sense to define addition of two periods: if there's time p1
between moments A
and B
and time p2
between moments B
and C
, then p1 + p2
could be the amount of time between A
and C
. Unfortunately, it doesn't work this way.
val date1 = LocalDate(2024, 4, 12)
val date2 = LocalDate(2024, 9, 4)
val date3 = LocalDate(2024, 12, 27)
assertEquals(LocalDate(2024, 12, 27), (date1 + (date2 - date1)) + (date3 - date2)) // without using period addition
assertEquals(LocalDate(2024, 12, 28), date1 + ((date2 - date1) + (date3 - date2))) // using period addition
assertEquals(DatePeriod(months = 4, days = 23), date2 - date1)
assertEquals(DatePeriod(months = 3, days = 23), date3 - date2)
assertEquals(DatePeriod(months = 3, days = 23), date3 - date2)
assertEquals(DatePeriod(months = 8, days = 15), date3 - date1)
assertEquals(DatePeriod(months = 7, days = 46), (date3 - date2) + (date2 - date1))
If we don't add periods together, we get what we expected: x + (y - x)
becomes y
, so in the end, we get back to date3
.
The reason the result is different when we add periods together first lies in the order in which addition of periods happens. In the normal case, we get
date1.plus(4, DateTimeUnit.MONTH).plus(23, DateTimeUnit.DAY).plus(3, DateTimeUnit.MONTH).plus(23, DateTimeUnit.DAY)
In the case of adding periods together first, instead, we get
date1.plus(4, DateTimeUnit.MONTH).plus(3, DateTimeUnit.MONTH).plus(23, DateTimeUnit.DAY).plus(23, DateTimeUnit.DAY)
But waiting for three months and then for 23 days is not the same as waiting for 23 days and then waiting for three months, because the lengths of months are different.
With DateTimePeriod
, the situation is even worse, because the time component is also added, giving us additional problems like the difference between waiting for 24 hours and one whole day (which isn't always the same, because clocks could shift due to DST transitions).
With all of this in mind, it's unclear what use cases adding periods together correctly achieves and even what precise semantics it has. If we learn of use cases where plus
always does what's expected, we could try to limit plus
to just these cases.