3.6 KiB
Time and Timing (Zig 0.16.0)
Primary release-note source: https://ziglang.org/download/0.16.0/release-notes.html
Zig 0.16 moves time APIs that depend on the runtime behind std.Io. Use std.Io.Timestamp, std.Io.Duration, and std.Io.Clock.
Migration Summary
Release-note map:
std.time.Instant->std.Io.Timestampstd.time.Timer->std.Io.Timestampstd.time.timestamp->std.Io.Timestamp.now{D}duration formatting -> formatstd.Io.Durationwith{f}
std.time still provides constants and calendar helpers such as ns_per_ms, ns_per_s, and std.time.epoch.
Clocks
std.Io.Clock values:
.real: wall-clock Unix/POSIX time, affected by clock changes..awake: monotonic-style clock intended to exclude suspend time where possible..boot: monotonic-style clock intended to include suspend time where possible..cpu_process: CPU time used by current process..cpu_thread: CPU time used by current thread.
Current Timestamp
const wall = std.Io.Timestamp.now(io, .real);
const boot = std.Io.Timestamp.now(io, .boot);
const awake = std.Io.Timestamp.now(io, .awake);
Clock-specific wrapper:
const start = std.Io.Clock.Timestamp.now(io, .boot);
Duration
const d1 = std.Io.Duration.fromMilliseconds(16);
const d2 = std.Io.Duration.fromSeconds(1);
const ns = d1.toNanoseconds();
_ = .{ d2, ns };
Formatting:
try writer.print("{f}", .{std.Io.Duration.fromMilliseconds(250)});
Do not use the removed {D} format specifier.
Elapsed Time
const start = std.Io.Timestamp.now(io, .boot);
// work
const end = std.Io.Timestamp.now(io, .boot);
const elapsed = start.durationTo(end);
Or with clock-tagged timestamps:
const start = std.Io.Clock.Timestamp.now(io, .boot);
// work
const elapsed = start.untilNow(io);
Sleeping
Use clock-aware durations/timestamps rather than std.Thread.sleep when the code should cooperate with the selected std.Io backend.
try std.Io.Clock.Duration{
.raw = std.Io.Duration.fromMilliseconds(10),
.clock = .boot,
}.sleep(io);
For low-level OS-thread code that deliberately blocks a thread and is not part of I/O task scheduling, std.Thread.sleep is still available.
Resolution
Clock resolution may fail or return zero for unsupported clocks.
const clock: std.Io.Clock = .boot;
const resolution = try clock.resolution(io);
if (resolution.nanoseconds == 0) {
return error.ClockUnavailable;
}
Epoch and Calendar Helpers
Use std.time.epoch for calendar conversion. Timestamps can be converted to seconds:
const now = std.Io.Timestamp.now(io, .real);
const seconds: u64 = @intCast(now.toSeconds());
const epoch_seconds = std.time.epoch.EpochSeconds{ .secs = seconds };
Application Guidance
- Put common wall-clock timestamp reads behind a shared application helper when consistent clock selection matters.
- Store/pass
std.Ioon timer systems that sample time repeatedly. - Avoid direct
std.time.microTimestamp-style callsites in new code; route through the shared helper. - Use
.bootor.awakefor elapsed-time measurement; use.realfor timestamps intended to correspond to wall-clock time.
Review Checklist
- Is the code using
std.Io.Timestamp.now(io, clock)rather than oldstd.time.timestamphelpers? - Is the clock choice documented by usage (
.realfor wall time, monotonic clocks for elapsed time)? - Is duration formatting using
{f}withstd.Io.Duration? - Does the API receive or store
iorather than constructing a fallback locally? - Is
std.Thread.sleeponly used for deliberate OS-thread blocking?