Skip to main content

core::time — Durations, instants, timers

Monotonic time (Instant), wall-clock time (SystemTime), durations, and interval streams.

FileWhat's in it
duration.vrDuration — time span
instant.vrInstant — monotonic point in time
system_time.vrSystemTime, SystemTimeError
interval.vrInterval, AsyncInterval — tick streams
mod.vrTime namespace + re-exports

Duration

Time span with nanosecond resolution.

Construction

Duration.new(secs: Int, nanos: Int) -> Duration
Duration.from_secs(secs) Duration.from_millis(ms) Duration::from_micros(us)
Duration::from_nanos(ns) Duration.from_secs_f64(f)
Duration.ZERO Duration::MAX

Literal sugar (on any integer)

5.nanoseconds() 5.microseconds() 5.milliseconds()
5.seconds() 5.minutes() 5.hours()
5.days()
// Aliases: 5.ns(), 5.us(), 5.ms()

Inspection

d.as_nanos() -> Int d.as_micros() -> Int
d.as_millis() -> Int d.as_secs() -> Int
d.as_secs_f64() -> Float d.as_secs_f32() -> Float
d.subsec_nanos() -> Int d.subsec_micros() -> Int d.subsec_millis() -> Int
d.is_zero() -> Bool

Arithmetic

d + d2 d - d2 d * n d / n
d.checked_add(d2) / checked_sub / checked_mul / checked_div -> Maybe<Duration>
d.saturating_add(d2) / saturating_sub / saturating_mul
d.mul_f64(factor) -> Duration d.div_f64(divisor) -> Duration

Implements Eq, Ord, Clone, Copy, Hash, Debug, Display.


Instant — monotonic time

Always moves forward. Unaffected by wall-clock adjustments (NTP, DST, manual time changes). Use for measuring elapsed time.

Instant.now() -> Instant

i.elapsed() -> Duration // since this instant
i.duration_since(&earlier) -> Duration // panics if i < earlier
i.checked_duration_since(&earlier) -> Maybe<Duration>
i.saturating_duration_since(&earlier) -> Duration

i.checked_add(duration) -> Maybe<Instant>
i.checked_sub(duration) -> Maybe<Instant>
i + duration i - duration
i < other i == other // comparison

Typical measurement

let start = Instant.now();
do_work();
let elapsed = start.elapsed();
print(f"took {elapsed.as_millis()} ms");

SystemTime — wall-clock time

Tied to real-world time. Subject to adjustments (NTP, DST, leap seconds).

SystemTime.now() -> SystemTime
SystemTime.UNIX_EPOCH // 1970-01-01T00:00:00Z

t.duration_since(&earlier) -> Result<Duration, SystemTimeError>
t.elapsed() -> Result<Duration, SystemTimeError>
t.checked_add(duration) -> Maybe<SystemTime>
t.checked_sub(duration) -> Maybe<SystemTime>
t + duration t - duration
t < other t == other

type SystemTimeError is { /* negative duration */ };
err.duration() -> Duration

Unix epoch helper

let now = SystemTime.now();
let unix_ms = now.duration_since(&SystemTime.UNIX_EPOCH)
.unwrap_or(Duration.ZERO)
.as_millis();

When to use which

NeedUse
Measure elapsed timeInstant
Schedule future workInstant.now() + duration
Timestamp for logs, user displaySystemTime
Compare with filesystem mtimeSystemTime
Store as persistent recordSystemTime (convert to UNIX epoch)

Sleep

Time::sleep(duration) // blocking
Time::sleep_ms(ms) Time::sleep_secs(secs)

sleep(duration).await // async (from core::async)
sleep_until(instant).await

Interval — repeating timer

Interval.new(period: Duration) -> Interval
interval(period) -> Interval // re-exported from async

iv.tick().await -> Instant // fires at `period` intervals
iv.reset() // restart from now
iv.period() -> Duration
iv.missed_tick_behavior() -> MissedTickBehavior
iv.set_missed_tick_behavior(behaviour)
type MissedTickBehavior is
| Burst // fire all missed ticks immediately
| Delay // skip missed, restart from now
| Skip; // skip and keep original schedule

Example

async fn heartbeat() using [Logger] {
let mut iv = Interval.new(1.seconds());
loop {
iv.tick().await;
Logger.info(&"heartbeat");
}
}

Time namespace

Convenience static methods:

Time::now() -> Duration // monotonic, since epoch
Time::monotonic() -> Int // raw nanoseconds
Time::system_time() -> SystemTime
Time::instant() -> Instant
Time::sleep(duration)
Time::sleep_ms(ms) Time::sleep_secs(secs)

Low-level intrinsics

monotonic_nanos() -> UInt64 // CLOCK_MONOTONIC / equivalent
realtime_nanos() -> UInt64 // CLOCK_REALTIME / equivalent
realtime_secs() -> Int64
sleep_ms(ms) sleep_ns(ns)

These are @requires_runtime intrinsics backing the higher-level API.


Timestamps for logs

Common idiom — record absolute time and monotonic elapsed:

type LogLine is {
wall_time: SystemTime,
elapsed_ms: Int,
message: Text,
};

fn now_line(msg: Text, program_start: Instant) -> LogLine {
LogLine {
wall_time: SystemTime.now(),
elapsed_ms: program_start.elapsed().as_millis(),
message: msg,
}
}

See also

  • async → timerssleep, timeout, Interval.
  • intrinsicsmonotonic_nanos, rdtsc, rdtscp.
  • sys — platform clock_gettime / libSystem equivalents.