What is the relationship and division of responsibility between kotlin.time (stdlib) and the kotlinx-datetime library?
answer
- stdlib = Duration/Instant/Clock/TimeSource
- kotlinx-datetime = LocalDate/LocalDateTime/TimeZone/DatePeriod
- kotlinx-datetime now reuses kotlin.time.Instant
- Instant + TimeZone -> LocalDateTime
- Add the kotlinx-datetime dependency; stdlib needs none
basics
~10 sThe stdlib gives you instants, durations, and a clock for 'now'. kotlinx-datetime is a separate library you add for calendar things: dates, time zones, and breaking an instant into year/month/day.
solid answer
~40 skotlin.time (standard library, no dependency) owns timeline primitives: Duration, Instant, Clock, and TimeSource/TimeMark for monotonic measurement. It deliberately has no calendar concept. kotlinx-datetime is an opt-in Kotlin Multiplatform library (org.jetbrains.kotlinx:kotlinx-datetime) that adds the calendar layer: LocalDate, LocalDateTime, LocalTime, TimeZone, DatePeriod/DateTimePeriod, and conversions between an Instant and human calendar fields. Crucially, since the Instant/Clock types were stabilized in stdlib, kotlinx-datetime now reuses kotlin.time.Instant and kotlin.time.Clock rather than defining its own; older code referenced kotlinx.datetime.Instant which is now a deprecated typealias/migration target. You convert with extensions like instant.toLocalDateTime(timeZone) and localDateTime.toInstant(timeZone). Rule of thumb: stdlib for 'when and how long', kotlinx-datetime for 'what date in what zone'.
go deeper
Knows kotlinx-datetime is a separate library for dates and zones.
Maps each type to the right layer and knows you need a TimeZone to get calendar fields.
Explains the stdlib stabilization of Instant/Clock and how kotlinx-datetime now reuses them.
Reasons about the dependency boundary, multiplatform reuse, and migration story from kotlinx.datetime.Instant aliases.
## Two layers Kotlin separates **timeline math** from **calendar semantics**. ### Layer 1 — kotlin.time (standard library) Always available, no dependency. It contains: - **`Duration`** — an amount of time (e.g. `5.minutes`). - **`Instant`** — an exact point on the timeline (stabilized in Kotlin 2.x). - **`Clock`** — interface providing `now(): Instant`; `Clock.System` is the default. - **`TimeSource` / `TimeMark`** — monotonic measurement for elapsed-time benchmarking. This layer has **no notion of years, months, days, or time zones**. It is pure timeline arithmetic. ### Layer 2 — kotlinx-datetime (separate library) You add a dependency: `org.jetbrains.kotlinx:kotlinx-datetime`. It is a **Kotlin Multiplatform** library and supplies the calendar layer: - **`LocalDate`**, **`LocalTime`**, **`LocalDateTime`** — calendar values with no zone. - **`TimeZone`** — IANA zone rules (`TimeZone.of("Europe/Paris")`, `TimeZone.UTC`, `TimeZone.currentSystemDefault()`). - **`DatePeriod` / `DateTimePeriod`** — calendar-aware spans (months, days) that respect varying month lengths. ## How they connect Because `Instant`/`Clock` are now stdlib types, **kotlinx-datetime reuses them** instead of declaring its own. Historically `kotlinx.datetime.Instant` and `kotlinx.datetime.Clock` existed; today those are migration aliases pointing at the `kotlin.time` types, and code should import from `kotlin.time`. ```kotlin import kotlin.time.Clock import kotlinx.datetime.TimeZone import kotlinx.datetime.toLocalDateTime val zone = TimeZone.of("Europe/Paris") val ldt = Clock.System.now().toLocalDateTime(zone) println(ldt.year) // calendar field, only after applying a zone ``` ## The conversion seam An `Instant` becomes calendar fields only when you apply a `TimeZone`: - `Instant.toLocalDateTime(timeZone)` -> `LocalDateTime` - `LocalDateTime.toInstant(timeZone)` -> `Instant` ## Rule of thumb - 'How long did X take?' / 'when did it happen?' -> **kotlin.time** (`Duration`, `Instant`, `Clock`). - 'What date is it in Tokyo?' / 'add one month' -> **kotlinx-datetime** (`LocalDate`, `TimeZone`, `DatePeriod`).
- Why did kotlinx-datetime stop defining its own Instant?Once Instant/Clock were stabilized in stdlib, duplicating them caused friction; kotlinx-datetime now reuses the kotlin.time types, with the old ones as migration aliases.
- Which library would you reach for to add one calendar month to a date?kotlinx-datetime, using DatePeriod(months = 1) with LocalDate.plus, because month length is calendar-dependent.
saying these in an interview costs you the question
- Believing LocalDate/TimeZone live in the standard library
- Thinking you must add a dependency just to call Clock.System.now()
- Insisting kotlinx-datetime.Instant is distinct from kotlin.time.Instant in current versions
- Using Duration arithmetic to add 'one month' (months aren't a fixed duration)