Xo is experimental. The source is now public on GitHub, or try Xo in your browser.
Menu · time

Docs

std/time

On this page

Index

Constants

RFC3339

const RFC3339: Str = "{year}-{month}-{day}T{hour}:{minute}:{second}{frac}{offset}"

Source: std/time.xo:146

RFC1123

const RFC1123: Str = "{weekday:short}, {day} {month:short} {year} {hour}:{minute}:{second} {zone}"

HTTP dates.

Source: std/time.xo:148

DATE

const DATE: Str = "{year}-{month}-{day}"

Source: std/time.xo:149

TIME

const TIME: Str = "{hour}:{minute}:{second}"

Source: std/time.xo:150

RFC3339_LAYOUT

const RFC3339_LAYOUT: Layout = layout(RFC3339)

Source: std/time.xo:169

RFC1123_LAYOUT

const RFC1123_LAYOUT: Layout = layout(RFC1123)

Source: std/time.xo:170

DATE_LAYOUT

const DATE_LAYOUT: Layout = layout(DATE)

Source: std/time.xo:171

TIME_LAYOUT

const TIME_LAYOUT: Layout = layout(TIME)

Source: std/time.xo:172

Types

Zone

struct Zone {}

A time zone: a handle to its rules. Equal when the names (and, for fixed, the offsets) are equal; displays as its name.

Source: std/time.xo:13

Zone.display

fn (z: Zone) display() -> Str

Source: std/time.xo:15

Zone.name

fn (z: Zone) name() -> Str

Source: std/time.xo:38

Zone.offset_at

fn (z: Zone) offset_at(t: Time) -> Duration

The offset from UTC at that instant.

Source: std/time.xo:40

Zone.abbreviation_at

fn (z: Zone) abbreviation_at(t: Time) -> Str

“CET”, “CEST”.

Source: std/time.xo:42

ZoneErr

enum ZoneErr {
  Unknown(name: Str)
  NoLocal(msg: Str)
}

Displays as unknown time zone "Mars/Olympus" or cannot determine the local time zone: the system zone is not set.

Source: std/time.xo:19

ZoneErr.display

fn (e: ZoneErr) display() -> Str

Source: std/time.xo:26

Date

struct Date {
  year: Int
  month: Int
  day: Int
} derive Ord, Json

A calendar date in the proleptic Gregorian calendar.

Source: std/time.xo:45

Date.weekday

fn (d: Date) weekday() -> Weekday

Source: std/time.xo:109

Date.add_days

fn (d: Date) add_days(n: Int) -> Date

Source: std/time.xo:110

Date.add_months

fn (d: Date) add_months(n: Int) -> Date

Clamps the day: Jan 31 + 1 month is Feb 28 or 29.

Source: std/time.xo:112

Date.days_until

fn (d: Date) days_until(o: Date) -> Int

Source: std/time.xo:113

Date.display

fn (d: Date) display() -> Str

“2026-10-09”.

Source: std/time.xo:115

ClockTime

struct ClockTime {
  hour: Int
  minute: Int
  second: Int
  nanos: Int
} derive Ord, Json

A wall clock time of day.

Source: std/time.xo:52

Civil

struct Civil {
  date: Date
  time: ClockTime
  offset: Duration
  zone: Str
} derive Json

A wall clock reading in a zone: what civil(t, z) returns.

Source: std/time.xo:60

Weekday

enum Weekday {
  Monday
  Tuesday
  Wednesday
  Thursday
  Friday
  Saturday
  Sunday
} derive Display, Ord, Json

Source: std/time.xo:67

Weekday.number

fn (w: Weekday) number() -> Int

The ISO 8601 number of the day: Monday 1 to Sunday 7 (decision 0414).

Source: std/time.xo:118

Ambiguity

enum Ambiguity {
  Earlier
  Later
  Reject
}

What instant does with a civil time that falls in a daylight saving gap (does not exist) or overlap (exists twice). Earlier gives the earlier instant and Later the later one, so Earlier is never after Later: for a gap, 02:30 on 2026-03-08 in New York is 01:30 EST (Earlier, the clock moved back by the gap) or 03:30 EDT (Later); for an overlap, 01:30 on 2026-11-01 is 01:30 EDT or 01:30 EST.

Source: std/time.xo:83

CivilErr

enum CivilErr {
  Invalid(msg: Str)
  Skipped(at: Str)
  Repeated(at: Str)
}

Displays as invalid civil time: month 13 out of range 1 to 12, 2026-03-08T02:30:00 America/New_York does not exist (skipped by a daylight saving change), or 2026-11-01T01:30:00 America/New_York happens twice (repeated by a daylight saving change).

Source: std/time.xo:93

CivilErr.display

fn (e: CivilErr) display() -> Str

Source: std/time.xo:103

Ticker

struct Ticker {
  clock: Clock
  period: Duration
  next_ns: Atomic[Int]
}

A clock’s ticks every period (Go’s time.Ticker without a goroutine): wait sleeps until the next tick and returns its time; ticks that a slow caller missed are dropped, as Go’s channel of one drops them, and the phase is kept (decision 0414). Copies share the schedule.

Source: std/time.xo:134

Ticker.wait

fn (t: Ticker) wait() -> Time uses clock

Source: std/time.xo:142

Ticker.reset

fn (t: Ticker) reset(period: Duration) -> Ticker uses clock

Restarts the schedule: the next tick one (new) period from now.

Source: std/time.xo:144

Layout

struct Layout {}

A layout parsed once. Hot code should use it: format and parse with a string layout parse the text on every call (5.4x and 4.7x of Go’s wall), while a const Layout runs at 2.03x and 1.90x (bench/results/std-twin-rows2-2026-11-03.md). A layout parsed once: const ISO: Layout = layout("{year}-{month}-{day}") parses it on first use (decision 0332), and format and parse then skip the layout walk. Displays as the layout text; equal when the texts are.

Source: std/time.xo:159

Layout.display

fn (l: Layout) display() -> Str

Source: std/time.xo:163

Layout.format

fn (l: Layout) format(t: Time, z: Zone) -> Str

Same text as time.format(t, z, text).

Source: std/time.xo:165

Layout.parse

fn (l: Layout) parse(s: Str, z: Zone) -> Time ! ParseErr

Same result as time.parse(s, text, z).

Source: std/time.xo:167

ParseErr

struct ParseErr {
  input: Str
  layout: Str
  at: Int
  msg: Str
}

Displays as at byte 5 of "2026-1x-09": expected 2 digit month.

Source: std/time.xo:175

ParseErr.display

fn (e: ParseErr) display() -> Str

Source: std/time.xo:182

LayoutErr

struct LayoutErr {
  layout: Str
  msg: Str
}

Displays as bad layout "{yr}": unknown field {yr}.

Source: std/time.xo:185

LayoutErr.display

fn (e: LayoutErr) display() -> Str

Source: std/time.xo:190

Functions

utc

fn utc() -> Zone

utc() needs no zone data.

Source: std/time.xo:29

zone

fn zone(name: Str) -> Zone ! ZoneErr

An IANA name: “Europe/Berlin”. Pure: the data is embedded in the program.

Source: std/time.xo:31

fixed

fn fixed(name: Str, offset: Duration) -> Zone

A zone with one offset forever (“UTC+2” style names); faults past 24h.

Source: std/time.xo:33

local

fn local(env: Env) -> Zone ! ZoneErr uses env

The machine’s zone: TZ, then the system setting. A fake Env without TZ gives utc().

Source: std/time.xo:36

civil

fn civil(t: Time, z: Zone) -> Civil

Source: std/time.xo:105

instant

fn instant(date: Date, time: ClockTime, z: Zone, ambiguity: Ambiguity = Ambiguity.Reject) -> Time ! CivilErr

Source: std/time.xo:106

date

fn date(year: Int, month: Int, day: Int) -> Date ! CivilErr

Source: std/time.xo:107

weekday_from

fn weekday_from(n: Int) -> Weekday?

The weekday of an ISO 8601 number (1 Monday to 7 Sunday), None outside 1 to 7.

Source: std/time.xo:121

truncate

fn truncate(t: Time, d: Duration) -> Time

t rounded down to a multiple of d since the zero time (January 1 of year 1, UTC), Go’s Time.Truncate: for a d that divides a day this is the start of the UTC minute, hour or day. d <= 0 returns t.

Source: std/time.xo:126

round

fn round(t: Time, d: Duration) -> Time

t rounded to the nearest multiple of d (halves up), Go’s Time.Round.

Source: std/time.xo:128

ticker

fn ticker(clock: Clock, period: Duration) -> Ticker uses clock

A ticker whose first tick is one period from now; faults for a period of 0 or less (Go’s NewTicker panics).

Source: std/time.xo:141

layout

fn layout(text: Str) -> Layout

Faults on a bad layout (a constant layout is checked at compile time).

Source: std/time.xo:162

format

fn format(t: Time, z: Zone, layout: Str) -> Str

Faults on a bad layout (a constant layout is checked at compile time). {frac} and {frac:N} include their leading .: write {second}{frac:7}, not {second}.{frac:7}.

Source: std/time.xo:194

parse

fn parse(s: Str, layout: Str, z: Zone) -> Time ! ParseErr

Strict: accepts exactly the layout. z applies when the text has no offset.

Source: std/time.xo:197

check_layout

fn check_layout(layout: Str) -> () ! LayoutErr

Source: std/time.xo:198

↑ index