skip to content

Clock, Instant & kotlinx-datetime

The stdlib gives you a Clock and Instant for wall-clock time, but calendar work — local dates, time zones, date arithmetic — lives in the separate kotlinx-datetime library. Knowing where the boundary sits saves you from reaching for java.time in multiplatform code.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

How do you get the current wall-clock instant in Kotlin's standard library, and what type does it return?

level: juniorimportance: must knowfreq 60%

answer

  1. Clock.System.now() -> Instant
  2. Instant = point on timeline, no calendar/zone
  3. Instant - Instant = Duration
  4. Clock is an interface -> inject for tests
  5. kotlin.time package, stabilized in 2.x

basics

~10 s

Use kotlin.time.Clock.System.now(). It returns an Instant, which is a single point in time (a timestamp) — not a date or a clock you read on a wall.

solid answer

~40 s

Kotlin 2.x stabilized kotlin.time.Clock and kotlin.time.Instant in the standard library. Clock.System.now() reads the platform's current moment and returns an Instant — an exact point on the timeline (effectively a UTC timestamp with nanosecond precision). An Instant has no calendar fields (no year/month/day, no time zone); it is just 'how far from the epoch'. You compute durations between two Instants by subtraction, which yields a kotlin.time.Duration: val elapsed = Clock.System.now() - start. For testable code you depend on the Clock interface and inject Clock.System in production, swapping a fake Clock in tests. Don't confuse this with kotlinx-datetime, a separate library; the Instant/Clock types now live in stdlib, while calendar types like LocalDate stay in kotlinx-datetime.

code

kotlin · 8 lines
kotlin
import kotlin.time.Clock
import kotlin.time.Instant

fun measure(clock: Clock = Clock.System): Instant = clock.now()

val a = Clock.System.now()
val b = Clock.System.now()
val d = b - a   // kotlin.time.Duration

go deeper

for a junior

Knows Clock.System.now() returns an Instant representing the current moment.

for a middle

Explains Instant has no calendar/zone, subtraction yields Duration, and Clock is injectable.

for a senior

Discusses testability via the Clock interface and the stdlib-vs-kotlinx-datetime split.

for a principal

Frames Clock as a seam for deterministic time, and distinguishes wall-clock Instant from monotonic TimeSource for measurement.

## What 'now' means There are two different ideas people lump together as 'time': a **point on the timeline** (an instant, e.g. the exact moment this ran) and a **calendar description** (year/month/day/hour in some time zone). Kotlin's stdlib gives you the first. ## Clock and Instant in stdlib In Kotlin 2.x the types `kotlin.time.Clock` and `kotlin.time.Instant` were stabilized into the standard library. - **`Instant`** = an exact point on the timeline, conceptually a count of seconds + nanoseconds from the Unix epoch (1970-01-01T00:00:00Z). It carries **no time zone and no calendar fields**. - **`Clock`** = an interface with a single method `now(): Instant`. It is the *source* of the current instant. - **`Clock.System`** = the default implementation that reads the host platform clock. ```kotlin import kotlin.time.Clock import kotlin.time.Instant val start: Instant = Clock.System.now() // ... work ... val elapsed = Clock.System.now() - start // Duration println(elapsed.inWholeMilliseconds) ``` ## Subtraction gives a Duration Subtracting two `Instant`s yields a `kotlin.time.Duration`. Adding a `Duration` to an `Instant` gives a new `Instant` (`instant + 5.minutes`). This is pure arithmetic on the timeline — no calendar rules involved. ## Why the Clock interface matters Because `Clock` is an interface, you can **inject** it. Production wires `Clock.System`; tests wire a fake that returns a fixed instant, making time-dependent logic deterministic. ```kotlin class FixedClock(private val fixed: Instant) : Clock { override fun now() = fixed } ``` ## What it is NOT - Not a calendar: an `Instant` has no `.year` or `.month`. - Not `System.currentTimeMillis()`: that's a raw `Long`; `Instant` is a typed, arithmetic-aware value. - Not `kotlinx-datetime`: that's a separate Multiplatform library for calendar work (`LocalDate`, `TimeZone`). The `Instant`/`Clock` types themselves now live in stdlib.

  • What do you get if you subtract one Instant from another?
    A kotlin.time.Duration, representing the elapsed time between the two points.
  • Why depend on Clock rather than calling Clock.System.now() directly everywhere?
    So you can inject a fake Clock in tests and make time-dependent code deterministic.

An Instant is a photo timestamp — one exact moment; a calendar date is the wall calendar you'd read in a particular city.

saying these in an interview costs you the question

  • Saying Instant carries a time zone or has year/month/day fields
  • Confusing kotlin.time.Instant with kotlinx-datetime being the only source of Instant
  • Thinking now() returns a String or a Long
  • Claiming you should use Instant for measuring elapsed time on a monotonic basis (that's TimeSource)

context

open as a page

You have an Instant. How do you convert it to a human-readable date and time, and why is a TimeZone required?

level: middleimportance: must knowfreq 50%

basics

~10 s

Call instant.toLocalDateTime(timeZone) from kotlinx-datetime. You must pass a time zone because the same instant shows a different clock time in different places (e.g. noon UTC is a different local hour in Tokyo).

open as a page

What is the relationship and division of responsibility between kotlin.time (stdlib) and the kotlinx-datetime library?

level: middleimportance: must knowfreq 55%

basics

~10 s

The 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.

open as a page

Why can't you add 'one month' or 'one day across a DST boundary' using kotlin.time.Duration, and what does kotlinx-datetime offer instead?

level: seniorimportance: should knowfreq 40%

basics

~20 s

A month isn't a fixed length and a 'day' can be 23 or 25 hours during daylight-saving switches. Duration only knows exact time amounts, so you use kotlinx-datetime's calendar arithmetic (DatePeriod, plus with a TimeZone) instead.

open as a page

How do you design time-dependent code so it is deterministic and testable, using Kotlin's Clock?

level: seniorimportance: should knowfreq 38%

basics

~10 s

Don't call Clock.System.now() deep inside logic. Depend on the Clock interface, pass Clock.System in production, and pass a fake Clock that returns a fixed instant in tests so results are predictable.

open as a page