129 lines
3.7 KiB
Markdown
129 lines
3.7 KiB
Markdown
# 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
|
|
|
|
Choose an explicit clock when migrating old time APIs. Use
|
|
`std.Io.Timestamp.now(io, .real)` for wall time and `.boot` or `.awake` for
|
|
elapsed-time measurements; `Timestamp` is not a one-for-one timer replacement.
|
|
- `{D}` duration formatting -> format `std.Io.Duration` with `{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
|
|
|
|
```zig
|
|
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:
|
|
|
|
```zig
|
|
const start = std.Io.Clock.Timestamp.now(io, .boot);
|
|
```
|
|
|
|
## Duration
|
|
|
|
```zig
|
|
const d1 = std.Io.Duration.fromMilliseconds(16);
|
|
const d2 = std.Io.Duration.fromSeconds(1);
|
|
const ns = d1.toNanoseconds();
|
|
_ = .{ d2, ns };
|
|
```
|
|
|
|
Formatting:
|
|
|
|
```zig
|
|
try writer.print("{f}", .{std.Io.Duration.fromMilliseconds(250)});
|
|
```
|
|
|
|
Do not use the removed `{D}` format specifier.
|
|
|
|
## Elapsed Time
|
|
|
|
```zig
|
|
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:
|
|
|
|
```zig
|
|
const start = std.Io.Clock.Timestamp.now(io, .boot);
|
|
|
|
// work
|
|
|
|
const elapsed = start.untilNow(io);
|
|
```
|
|
|
|
## Sleeping
|
|
|
|
Use clock-aware durations/timestamps so sleeping cooperates with the selected
|
|
`std.Io` backend and propagates cancelation.
|
|
|
|
```zig
|
|
try std.Io.Clock.Duration{
|
|
.raw = std.Io.Duration.fromMilliseconds(10),
|
|
.clock = .boot,
|
|
}.sleep(io);
|
|
```
|
|
|
|
## Resolution
|
|
|
|
Clock resolution may fail or return zero for unsupported clocks.
|
|
|
|
```zig
|
|
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:
|
|
|
|
```zig
|
|
const now = std.Io.Timestamp.now(io, .real);
|
|
const seconds: u64 = @intCast(now.toSeconds());
|
|
const epoch_seconds = std.time.epoch.EpochSeconds{ .secs = seconds };
|
|
```
|
|
|
|
This conversion is only valid for non-negative Unix timestamps and truncates
|
|
sub-second precision. Guard pre-epoch values or retain a signed representation.
|
|
|
|
## Application Guidance
|
|
|
|
- Put common wall-clock timestamp reads behind a shared application helper when consistent clock selection matters.
|
|
- Store/pass `std.Io` on timer systems that sample time repeatedly.
|
|
- Avoid direct `std.time.microTimestamp`-style callsites in new code; route through the shared helper.
|
|
- Use `.boot` or `.awake` for elapsed-time measurement; use `.real` for timestamps intended to correspond to wall-clock time.
|
|
|
|
## Review Checklist
|
|
|
|
- Is the code using `std.Io.Timestamp.now(io, clock)` rather than old `std.time.timestamp` helpers?
|
|
- Is the clock choice documented by usage (`.real` for wall time, monotonic clocks for elapsed time)?
|
|
- Is duration formatting using `{f}` with `std.Io.Duration`?
|
|
- Does the API receive or store `io` rather than constructing a fallback locally?
|
|
- Does sleeping use a clock-aware `std.Io` API and handle `error.Canceled`?
|