skip to content

Time & Duration

kotlin.time gives you a typed Duration, inline measuring helpers, and monotonic time marks. It matters in interviews mostly as the correct alternative to passing bare Long milliseconds around.

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

explore

questions

20

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

How do you create a kotlin.time.Duration value in Kotlin, and what is the idiomatic way to express '5 seconds' or '100 milliseconds'?

level: juniorimportance: must knowfreq 60%

basics

~10 s

Use the extension properties on numbers from kotlin.time, like 5.seconds or 100.milliseconds. They return a Duration object that represents a length of time, which you can add, compare, or convert.

open as a page

What does Kotlin's measureTime { } do, and how is it different from measureTimedValue { }?

level: juniorimportance: must knowfreq 55%

basics

~10 s

measureTime runs a block and gives back how long it took as a Duration. measureTimedValue runs a block and gives back both the block's result and how long it took, packaged together.

open as a page

How do you measure how long a block of code takes using TimeSource.Monotonic, and why use it instead of System.currentTimeMillis()?

level: juniorimportance: must knowfreq 55%

basics

~10 s

Call TimeSource.Monotonic.markNow() before the code to get a TimeMark, then call mark.elapsedNow() after to get a Duration. It uses a steady clock that never jumps backward, unlike wall-clock millis.

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

What arithmetic and comparison operations does kotlin.time.Duration support, and how does multiplying or dividing durations behave?

level: middleimportance: must knowfreq 50%

basics

~20 s

You can add and subtract two durations, multiply or divide a duration by a number, divide one duration by another to get a ratio, negate it, and compare them with < or >. Durations also implement Comparable.

open as a page

How do you convert a kotlin.time.Duration to a numeric value in a specific unit? Explain DurationUnit and the inWhole* accessors.

level: middleimportance: must knowfreq 45%

basics

~10 s

Use properties like inWholeMilliseconds or inWholeSeconds to get a whole Long count, or toDouble(unit) for a fractional value. DurationUnit is the enum (SECONDS, MILLISECONDS, etc.) you pass when you need to name the unit.

open as a page

Because measureTime and measureTimedValue are inline, what does that mean for using non-local return, suspend calls, and timing accuracy inside the block?

level: middleimportance: should knowfreq 35%

basics

~20 s

Because the block is inlined, you can call suspend functions inside it and even return from the surrounding function. The timing is the real time the block ran, including any suspension or blocking that happens.

open as a page

Why do measureTime / measureTimedValue use a monotonic clock instead of System.currentTimeMillis(), and what could go wrong if you timed code with wall-clock time?

level: middleimportance: should knowfreq 45%

basics

~20 s

A monotonic clock only moves forward at a steady pace, so it gives correct elapsed times. Wall-clock time can jump backward or forward (clock adjustments), which can make a measured duration wrong or even negative.

open as a page

Explain mark + Duration arithmetic and comparing two TimeMarks. What does (markB - markA) give, and what does hasPassedNow() mean?

level: middleimportance: should knowfreq 40%

basics

~20 s

You can add or subtract a Duration to a mark to get a shifted mark, subtract two marks to get the Duration between them, and compare marks. hasPassedNow() returns true once the current time is at or past that mark.

open as a page

You need to time a block and also keep the result. Compare doing it manually with markNow()/elapsedNow() versus measureTime/measureTimedValue, and when does the manual TimeMark approach win?

level: middleimportance: should knowfreq 25%

basics

~20 s

For timing one self-contained block, measureTime { } (returns a Duration) or measureTimedValue { } (returns both the value and Duration) is cleanest. Use manual markNow()/elapsedNow() when the start and end are in different places, like a deadline or multi-stage timing.

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

Explain Duration.parse, parseOrNull, and toIsoString. What string formats are accepted and what are the failure modes?

level: seniorimportance: should knowfreq 28%

basics

~10 s

toIsoString turns a duration into an ISO-8601 string like PT1H23M45S. Duration.parse reads such strings back, plus Kotlin's own format like '1h 23m'. parse throws on bad input; parseOrNull returns null instead.

open as a page

What does Duration.toComponents do, and how would you use it to render a duration like '1h 23m 45s'?

level: seniorimportance: should knowfreq 30%

basics

~10 s

toComponents splits a duration into separate fields like hours, minutes, seconds, and nanoseconds, handing them to a lambda you provide. You then format those numbers into a human-readable string.

open as a page

How can you make code that uses measureTime / measureTimedValue deterministic in tests, and what role does a custom TimeSource play?

level: seniorimportance: should knowfreq 25%

basics

~20 s

The plain measureTime always uses the real clock, so it is hard to test. Instead, call measureTime on a TimeSource you control — like TestTimeSource — and advance it manually, so the measured duration is exactly what you set.

open as a page

How do you test time-dependent code deterministically with TestTimeSource? Show how marks behave as you advance virtual time.

level: seniorimportance: should knowfreq 35%

basics

~20 s

TestTimeSource is a fake clock you control. It does not advance on its own; you call plusAssignDuration (the += operator) to move virtual time forward. Marks taken from it then report exactly the elapsed time you advanced, so tests are deterministic.

open as a page

You want to time many small operations and aggregate their durations (e.g., total and average per call). Show how measureTimedValue and Duration arithmetic support this, and what pitfalls to avoid.

level: seniorimportance: nice to knowfreq 18%

basics

~20 s

Wrap each operation in measureTimedValue to get its result and time, then add the durations together. Duration supports +, division by a number, and comparison, so totals and averages are easy. Avoid calling these in extremely hot inner loops where even small overhead matters.

open as a page

What is ValueTimeMark, why is it a value class, and what subtle pitfalls exist with monotonic marks (wraparound, no calendar meaning, cross-platform reading)?

level: seniorimportance: nice to knowfreq 18%

basics

~20 s

ValueTimeMark is the inline value-class TimeMark returned by Monotonic, so creating marks allocates nothing. Marks have no calendar meaning, are only comparable within one source, and rely on the platform's monotonic timer, which differs per platform.

open as a page