std.time

Clocks, sleeping, date-time values, and ISO-8601 conversion.

Importuse std.time

Types

struct DateTime#

Civil date-time from std.time. UTC-first: constructors interpret and produce UTC unless an explicit offset variant is used. weekday is ISO (0 = Monday .. 6 = Sunday).

use std.time.DateTime

fn main() {
  let instant: DateTime = std.time.from_epoch_ms(0)
  println(std.time.format_iso(instant))
  println(std.time.format(instant, "%a %Y-%m-%d"))
  println(std.time.to_epoch_ms(instant))
  println(std.time.parse_iso("2026-08-30T12:34:56Z").unwrap().year)
}
year: int

Proleptic Gregorian year; values below 1 run before the common era.

month: int

Month of the year, 1..12.

day: int

Day of the month, 1..31.

hour: int

Hour of the day, 0..23.

minute: int

Minute of the hour, 0..59.

second: int

Second of the minute, 0..59.

millisecond: int

Millisecond of the second, 0..999.

microsecond: int

Sub-millisecond remainder, 0..999. The whole fraction is millisecond * 1000 + microsecond, so existing millisecond-only code keeps its meaning and a Postgres timestamp no longer has to travel as text to survive a round trip.

weekday: int

ISO day of the week: 0 is Monday and 6 is Sunday.

Functions

extern fn now_ms() -> int#

Returns Unix wall-clock time in milliseconds.

let wall_ms = std.time.now_ms()
let wall_ns = std.time.now_ns()
let started = std.time.monotonic_ms()
std.time.sleep_ms(5)
println(std.time.monotonic_ms() >= started)
println(wall_ms > 0 && wall_ns > 0)
extern fn now_ns() -> int#

Returns Unix wall-clock time in nanoseconds.

extern fn monotonic_ms() -> int#

Returns monotonic time in milliseconds.

extern fn monotonic_ns() -> int#

Returns monotonic time in nanoseconds.

extern fn sleep_ms(ms: int)#

Blocks the current task for the requested milliseconds.

  • ms: How long to block, in milliseconds.
fn from_epoch_ms(epoch_ms: int) -> DateTime#

Converts Unix epoch milliseconds to a UTC date and time.

  • epoch_ms: Milliseconds since the Unix epoch.
fn to_epoch_ms(dt: DateTime) -> int#

Converts a UTC date and time to epoch milliseconds.

  • dt: Civil time read as UTC.
fn from_epoch_ms_offset(epoch_ms: int, offset_min: int) -> DateTime#

Converts epoch milliseconds using a fixed UTC offset.

  • epoch_ms: Milliseconds since the Unix epoch.
  • offset_min: Fixed offset from UTC in minutes; east of Greenwich is positive.
fn to_epoch_ms_offset(dt: DateTime, offset_min: int) -> int#

Converts a date and fixed offset to epoch milliseconds.

  • dt: Civil time read in the given offset.
  • offset_min: Fixed offset from UTC in minutes; east of Greenwich is positive.
fn from_epoch_us(epoch_us: int) -> DateTime#

Epoch microseconds -> UTC civil time, at full precision.

  • epoch_us: Microseconds since the Unix epoch.
let utc = std.time.from_epoch_us(1_500_123)
println(std.time.to_epoch_us(utc))
let east = std.time.from_epoch_us_offset(1_500_123, 120)
println(std.time.to_epoch_us_offset(east, 120))

let local = std.time.from_epoch_ms_offset(0, -300)
println(std.time.to_epoch_ms_offset(local, -300))
println(std.time.format_iso_offset(local, -300))
fn to_epoch_us(dt: DateTime) -> int#

UTC civil time -> epoch microseconds.

  • dt: Civil time read as UTC.
fn from_epoch_us_offset(epoch_us: int, offset_min: int) -> DateTime#

Converts epoch microseconds using a fixed UTC offset.

  • epoch_us: Microseconds since the Unix epoch.
  • offset_min: Fixed offset from UTC in minutes; east of Greenwich is positive.
fn to_epoch_us_offset(dt: DateTime, offset_min: int) -> int#

Converts a date and fixed offset to epoch microseconds.

  • dt: Civil time read in the given offset.
  • offset_min: Fixed offset from UTC in minutes; east of Greenwich is positive.
fn parse_utc(text: string) -> Result<DateTime, Error>#

Reads an offsetless ISO-8601 input as UTC — the PostgreSQL timestamp (without time zone) case, where the text carries no zone and the column's contract says the value is already UTC. parse_iso behaves identically; this name says so at the call site.

  • text: Offsetless ISO-8601 timestamp, read as already being UTC.
fn format(dt: DateTime, spec: string) -> string#

Formats a DateTime for display. Formatting is locale-independent, uses English abbreviated names, and never applies an implicit timezone.

DirectiveOutput
%YYear, minus sign when negative plus at least four magnitude digits
%mMonth, minimum two digits
%dDay, minimum two digits
%HHour, minimum two digits
%MMinute, minimum two digits
%SSecond, minimum two digits
%3fMilliseconds, minimum three digits
%6fMicroseconds, minimum six digits
%aEnglish abbreviated weekday
%bEnglish abbreviated month
%%Literal percent sign

Unknown and incomplete directives are copied literally. Use from_epoch_ms_offset when a fixed UTC offset is required.

  • dt: Civil time to render, taken at face value with no timezone applied.
  • spec: Format string of the directives tabled below; anything else is copied literally.
fn format_iso(dt: DateTime) -> string#

Formats a UTC date and time in ISO-8601 form.

  • dt: Civil time to render, read as UTC.
fn format_iso_offset(dt: DateTime, offset_min: int) -> string#

Formats a date and time with a fixed UTC offset.

  • dt: Civil time to render.
  • offset_min: Fixed offset from UTC in minutes; east of Greenwich is positive.
fn parse_iso(text: string) -> Result<DateTime, Error>#

Parses a supported ISO-8601 timestamp.

  • text: ISO-8601 timestamp to read.
extern fn local_offset_min() -> int#

The host's current local UTC offset in minutes. Native: the C library's own timezone conversion, so it honors TZ, the system zone, and the DST rule in force now. Hosts that cannot answer report 0 (UTC), which is the contract this had unconditionally before.

fn iso_ms(epoch_ms: int) -> string#

append_iso_ms's string form.

  • epoch_ms: Milliseconds since the Unix epoch.
use std.bytes
use std.bytes.Bytes

fn main() {
  let instant = 1_700_000_000_123
  println(std.time.iso_ms(instant))
  println(std.time.stamp_ms(instant))
  let out = bytes.new()
  std.time.append_iso_ms(out, instant)
  std.time.append_stamp_ms(out, instant)
  println(out.to_string())
}
fn append_iso_ms(out: Bytes, epoch_ms: int)#

Appends epoch_ms as Date.prototype.toISOString() spells it: UTC, always exactly three fraction digits, trailing Z. That is the shape JSON carries a JavaScript Date in, and so the shape a wire contract written against one owes its clients — format_iso above drops a zero fraction and widens to six digits for a sub-millisecond one, which is the right ISO-8601 answer and the wrong toISOString one.

  • out: Buffer the rendering is appended to.
  • epoch_ms: Milliseconds since the Unix epoch.
fn stamp_ms(epoch_ms: int) -> string#

append_stamp_ms's string form.

  • epoch_ms: Milliseconds since the Unix epoch.
fn append_stamp_ms(out: Bytes, epoch_ms: int)#

Appends epoch_ms as %Y%m%d%H%M%S — the same six fields with no separators and no fraction, which is the form a cache-busting URL parameter, a generated filename or a version stamp wants.

  • out: Buffer the rendering is appended to.
  • epoch_ms: Milliseconds since the Unix epoch.