Skip to content
CryoCryo home
StdlibSystem

time

Spans and clocks. Duration measures a length of time, Instant reads the monotonic clock, SystemTime reads the wall clock, and DateTime breaks a timestamp into UTC calendar parts.

All four are POD — copied by value, nothing to drop. Every difference saturates at zero rather than wrapping.

ItemImport
Durationimport std::time::duration;
Instant, SystemTime, sleepimport std::time::clock;
DateTimeimport std::time::datetime;

A plain import std::time; brings in the whole module.

Duration

Whole seconds plus a sub-second nanosecond remainder, always normalized so that nanos < 1_000_000_000.

import std::time;

const timeout: Duration = Duration::from_millis(250);
sleep(timeout);

Building

static new(secs: u64, nanos: u32) carries any nanosecond overflow into the seconds field, so the stored value is always normalized. Then the unit constructors — from_secs, from_millis, from_micros, from_nanos, and from_secs_f64 (negative input clamps to zero) — plus the named constants zero(), second(), millisecond(), microsecond(), and nanosecond().

Reading

MethodReturns
as_secs()Whole seconds; the sub-second part is dropped.
as_millis() / as_micros() / as_nanos()The whole span in that unit.
subsec_nanos() / subsec_millis() / subsec_micros()Just the remainder.
is_zero()boolean

Arithmetic

checked_add and checked_sub return Option<Duration>, None on overflow or underflow. saturating_add and saturating_sub clamp instead. scale(factor: u64) and divide(divisor: u64) scale the span.

Duration implements Eq, Ord, and Display, rendering in the largest sensible unit — 1.5s, 250ms, 10ns. to_string() gives the same text directly, and to_debug_string() the Debug form.

Instant — the monotonic clock

Instant only ever moves forward, which makes it the right tool for measuring elapsed time. It is opaque: a single reading is meaningful only relative to another one.

const start: Instant = Instant::now();
do_work();
println(f"took {start.elapsed()}");
MethodReturns
static now()Instant
elapsed()Duration from this reading until now.
duration_since(earlier: &Instant)Duration from earlier to this. saturating_duration_since is an alias naming the saturation explicitly.
as_nanos()i64 raw monotonic nanoseconds, from an unspecified epoch — for lightweight elapsed math where carrying a Duration is overkill.
checked_add(dur) / checked_sub(dur)Option<Instant>, None on overflow or on going below zero.

Eq and Ord are implemented, so instants compare directly.

Underneath it is CLOCK_MONOTONIC via clock_gettime on POSIX, and QueryPerformanceCounter scaled by QueryPerformanceFrequency on Windows.

SystemTime — the wall clock

SystemTime is subject to NTP steps and manual changes, so it is not for measuring elapsed time. Use it when you need an actual date.

MethodReturns
static now() / static unix_epoch()SystemTime
static from_unix_secs(secs: i64)SystemTime
unix_secs()i64 — whole seconds since the epoch, negative before 1970.
duration_since_epoch()Duration — saturates at zero for a clock set before 1970.
duration_since(earlier: &SystemTime)Duration — only meaningful if the clock has not been stepped in between.
checked_add(dur)Option<SystemTime>

POSIX reads CLOCK_REALTIME; Windows uses GetSystemTimePreciseAsFileTime and converts from FILETIME ticks since 1601 to the Unix epoch.

DateTime

A broken-out UTC civil calendar reading, derived from a Unix timestamp or a SystemTime.

import std::time::datetime;

println(f"{DateTime::now()}");     // 2026-07-28T21:14:07Z

static from_unix_secs(secs: i64), static from_system_time(t: &SystemTime), static now(), and to_string(), which renders the same ISO-8601 text as the Display impl.

All fields are UTC and already normalized: month in 1–12, day in 1–31, hour in 0–23, minute and second in 0–59. year is the proleptic Gregorian year and may be negative for timestamps far before the Common Era.

The conversion uses Howard Hinnant's civil_from_days algorithm, which is exact and branch-light across the whole proleptic Gregorian calendar — leap years, century rules, and pre-epoch timestamps all fall out of the arithmetic with no per-month tables. The day index and second-of-day are split with a floor division so a negative timestamp lands on the correct civil day; truncating toward zero would put −1 second on 1970-01-01 instead of 1969-12-31.

Only whole seconds are rendered. Any sub-second precision stays in the source SystemTime.

sleep

sleep(dur: Duration) -> void parks the calling thread for at least dur.

The POSIX path uses nanosleep and restarts across EINTR using the kernel's remaining-time readout, so a signal does not cut the sleep short. Windows uses Sleep, which is uninterruptible at the millisecond granularity it accepts; a sub-millisecond request rounds up to 1 ms there, so a non-zero request always blocks.