Module Time

Instants, durations, time zones, and civil date-times.

An Instant is a point on the timeline; a Duration is a signed span of nanoseconds. The difference of two instants is a duration (Since), and two instants can be ordered (Compare). A Zone maps instants to UTC offsets, and InZone projects an instant into a Zoned civil date-time for calendar work.

type Time.Duration = Int

A signed span of time, measured in nanoseconds.

Duration is just Int, so it supports the full integer algebra: add and subtract durations, multiply or divide by a number, negate, and compare them. Build durations from the unit constants, e.g. 5 * Time.Second or 2 * Time.Hour + 30 * Time.Minute.

type Time.Instant = iterative box choice {
  .add(Time.Duration) => self,
  .unixNanos => Int,
}

A point on the timeline, independent of any time zone.

  • .unixNanos — nanoseconds since the Unix epoch (1970-01-01T00:00:00Z).
  • .add(duration) — shift the instant by a duration, returning a new instant.

Differences and ordering are the free functions Since and Compare; civil fields come from projecting into a Zone with InZone.

type Time.Weekday = either {
  .friday!,
  .monday!,
  .saturday!,
  .sunday!,
  .thursday!,
  .tuesday!,
  .wednesday!,
}

A day of the week.

type Time.Zone = box choice {
  .name => String,
  .offsetAt(Time.Instant) => Time.Duration,
}

A time zone: a mapping from instants to UTC offsets.

  • .name — the zone's name (an IANA name like "Europe/Prague", or an offset like "+02:00" for fixed zones).
  • .offsetAt(instant) — the zone's UTC offset at the given instant, as a duration (it can vary across the year because of daylight saving time).
type Time.Zoned = iterative box choice {
  .addDays(Int) => self,
  .addMonths(Int) => self,
  .addYears(Int) => self,
  .day => Nat,
  .format(String) => String,
  .hour => Nat,
  .instant => Time.Instant,
  .minute => Nat,
  .month => Nat,
  .nanosecond => Nat,
  .second => Nat,
  .weekday => Time.Weekday,
  .year => Int,
  .zone => Time.Zone,
}

An instant seen through a time zone: a civil date-time with calendar fields.

  • .year — the year (can be negative for years before 1 CE).
  • .month — the month, 1 to 12.
  • .day — the day of the month, 1 to 31.
  • .hour — the hour, 0 to 23.
  • .minute — the minute, 0 to 59.
  • .second — the second, 0 to 59.
  • .nanosecond — the sub-second part, 0 to 999999999.
  • .weekday — the day of the week.
  • .zone — the time zone this date-time is in.
  • .instant — the underlying instant on the timeline.
  • .format(layout) — render using a strftime-style layout.
  • .addYears(n) — shift by whole years on the calendar, returning a new value.
  • .addMonths(n) — shift by whole months on the calendar.
  • .addDays(n) — shift by whole days on the calendar.

Calendar arithmetic (.addYears / .addMonths / .addDays) respects the zone, including daylight-saving transitions. For exact arithmetic on the timeline use Instant.add instead.

dec Time.At : [Time.Zone, Int, Nat, Nat, Nat, Nat, Nat] Option<Time.Zoned>

Builds a civil date-time in a zone from its calendar fields: At(zone, year, month, day, hour, minute, second). Returns .none! if the fields do not denote a valid date and time.

dec Time.Now : Time.Instant

The current instant, read from the system clock.