Skip to content

Commit ff43dd6

Browse files
authored
Add LocalDateTime arithmetic to the README (#126)
Closes #66
1 parent e31f3aa commit ff43dd6

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,33 @@ Notice that instead of general `DateTimeUnit` and `DateTimePeriod` we're using t
226226
`DateTimeUnit.DateBased` and `DatePeriod` respectively. This allows preventing the situations when
227227
time components are being added to a date at compile time.
228228

229+
### Date + time arithmetic
230+
231+
Arithmetic on `LocalDateTime` is intentionally omitted. The reason for this is that the presence of daylight saving time
232+
transitions (changing from standard time to daylight saving time and back) causes `LocalDateTime` arithmetic to be
233+
ill-defined. For example, consider time gaps (or, as [`dst` tag wiki on Stack Overflow](https://stackoverflow.com/tags/dst/info)
234+
calls them, "spring forward" transitions), that is, ranges of date + time combinations that never occur in a given
235+
time zone due to clocks moving forward. If we allowed `LocalDateTime` arithmetic that ignored time zones, then it
236+
could result in `LocalDateTime` instances that are inside a time gap and are invalid in the implied time zone.
237+
238+
Therefore, the recommended way to use a `LocalDateTime` is to treat it as a representation of an `Instant`,
239+
perform all the required arithmetic on `Instant` values, and only convert to `LocalDateTime` when a human-readable
240+
representation is needed.
241+
242+
```kotlin
243+
val timeZone = TimeZone.of("Europe/Berlin")
244+
val localDateTime = LocalDateTime.parse("2021-03-27T02:16:20")
245+
val instant = localDateTime.toInstant(timeZone)
246+
247+
val instantOneDayLater = instant.plus(1, DateTimeUnit.DAY, timeZone)
248+
val localDateTimeOneDayLater = instantOneDayLater.toLocalDateTime(timeZone)
249+
// 2021-03-28T03:16:20, as 02:16:20 that day is in a time gap
250+
251+
val instantTwoDaysLater = instant.plus(2, DateTimeUnit.DAY, timeZone)
252+
val localDateTimeTwoDaysLater = instantTwoDaysLater.toLocalDateTime(timeZone)
253+
// 2021-03-29T02:16:20
254+
```
255+
229256
## Implementation
230257

231258
The implementation of date/time types, such as `Instant`, `LocalDateTime`, `TimeZone` and so on, relies on:

0 commit comments

Comments
 (0)