What's the deal with `kotlin.time` vs `kotlinx.dat...
# kotlinx-datetime
m
What's the deal with
kotlin.time
vs
kotlinx.datetime
? It seems like the former is what we are supposed to be using since it's part of stdlib, but crucial features (like
Instant.toLocalDateTime
) seem to only be present on the latter.
j
kotlin.time
is for basic time and duration support, while
kotlinx.datetime
can handle time zones, date formatting, calendar-based operations, etc. You need stuff from
kotlin.time
when working with
kotlinx.datetime
, but the opposite is not true. Not everything that cares about durations and instants also cares about dates nor needs time zones.
I'm not working on Kotlin libraries, but my best guess for why
kotlinx.datetime
is not in the stdlib is because we don't want to embed the timezone database in all Kotlin projects.
c
Another way to explain it: • If it's about the physical passage of time, it's in
kotlin.time
(Clock, Instant, Duration) • If it's about how humans write time in a calendar, it's in
kotlinx.datetime
💯 6
> we don't want to embed the timezone database in all Kotlin projects. I'm not sure that's the reason.
kotlinx-datetime
doesn't embed tzdata by default on JS (there is an additional dependency to do it), and it's already in the JVM no matter what (I don't know about native). I think it was to allow the team to prototype datetime types with a different release cycle than the stdlib? I personally really like that split. The rules for physical- and human-based timekeeping are very different (e.g.
1.days
and
1, TimeUnit.DAY
mean different things) and it's very useful to just look at the package to know which rules are used
j
doesn't embed tzdata by default on JS (there is an additional dependency to do it)
Ah good to know, somehow I thought this dependency was transitively brought by
kotlinx.datetime
I totally agree with your point about the semantic separation (and package separation). But it doesn't explain in itself why it's a separate library. That said, even without tzdb concerns, it's still a bunch of code that a lot of apps don't need, so it makes sense to have a separate library. It's a bit like coroutines, or
<http://kotlinx.io|kotlinx.io>
.
2
c
Working with passage of time is pretty much standard for any application at some level of its stack, whether you're aware of it or not. Coroutine dispatchers, UI frame clocks, performance metrics embedded in a library, autogenerated timestamps, etc. It's a low level API driven by the OS needed for virtually every application or one of its dependencies, which is why it is part of the stdlib. In fact, its many (all?) of the
kotlin.time
APIs originated in
kotlinx.datetime
but were promoted to the stdlib because of how ubiquitous they are. In contrast, nowadays
kotlinx.datetime
is mostly useful for human-oriented display of dates and times, which are significantly more complicated than just measuring passage of time or Unix timestamps. Humans and our calendars have to deal with all kinds of things like daylight savings, leap days/seconds, etc. That stuff is expensive to work with, and it's really easy to confuse wall-clock-time (kotlinx.datetime) and moment-in-time (kotlin.time). Historically, many datetime libraries did not separate the two concepts, leading to infamous bugs like Y2K. To my knowledge, Java's introduction of the
java.time
APIs were one of the first to mainstream the strict separation between the two concepts, forcing you to explicitly convert between an
Instant
and the equivalent
LocalDate
,
LocalTime
, etc., and the Kotlin team has done a great thing by doubling down on that strict separation, and even taking it further by requiring a TimeZone in cases where java.time defaults to the current system timezone.
3