Time primitives for Cure (v0.27.0).

Instant is a point in time represented as Unix microseconds since the epoch (1970-01-01T00:00:00Z). Duration is a signed length in microseconds; both types are closed records over a single micros field so arithmetic on time values stays monomorphic.

The ISO 8601 helpers accept the canonical YYYY-MM-DDTHH:MM:SS form with optional fractional seconds and trailing Z or +HH:MM offset; any other shape yields Error(InvalidFormat(_)).

All functions are pure from Cure's point of view: the now/0 and utc_now/0 wall-clock readers carry the Io effect so callers are forced to declare it.

Runtime companion: :cure_std_time (see lib/cure/stdlib/cure_std_time.ex). Every external call here maps directly to a one-line wrapper in that module, so the surface remains small and auditable.

Examples

use Std.Time

let origin = of_unix(0)
format_iso8601(origin)                   # => "1970-01-01T00:00:00Z"
add(origin, seconds(60))                 # one minute after the epoch
use Std.Time

match parse_iso8601("2024-05-01T12:00:00Z")
  Ok(i)    -> to_unix(i)                 # => 1714564800
  Error(_) -> 0

Types

  • type ParseError = InvalidFormat | OutOfRange

    Parse errors returned by parse_iso8601/1.

Functions

  • # fn __group__() -> Atom

    Group tag consumed by Cure.Stdlib.Preload.

  • # fn add(i: Instant, d: Duration) -> Instant extern

    Shift an Instant forward by a Duration. Use negative durations to go backward.

  • # fn diff(a: Instant, b: Instant) -> Duration extern

    Difference between two Instants as a Duration: diff(a, b) == a - b.

  • # fn format_iso8601(i: Instant) -> String extern

    Format an Instant as an ISO 8601 UTC string with a Z suffix. A zero microsecond component is suppressed.

  • # fn hours(n: Int) -> Duration

    Build a Duration from a whole number of hours.

  • # fn millis(n: Int) -> Duration

    Build a Duration from a whole number of milliseconds.

  • # fn minutes(n: Int) -> Duration

    Build a Duration from a whole number of minutes.

  • # fn now() -> Instant ! Io extern

    Current wall-clock time as an Instant.

  • # fn of_unix(s: Int) -> Instant extern

    Promote Unix seconds into an Instant at second granularity.

  • # fn parse_iso8601(s: String) -> Result(Instant, ParseError) extern

    Parse an ISO 8601 timestamp. Accepts Z, +HH:MM, or -HH:MM offsets; fractional seconds up to microsecond precision are honoured. Returns Error(InvalidFormat(_)) on any other shape.

  • # fn seconds(n: Int) -> Duration

    Build a Duration from a whole number of seconds.

  • # fn to_unix(i: Instant) -> Int extern

    Unix seconds since the epoch for an Instant. Truncates sub-second precision toward zero.

  • # fn utc_now() -> Instant ! Io extern

    Alias for now/0. Kept explicit for readability in client code.

  • # fn zone(i: Instant, name: String) -> Result(String, ParseError) extern

    Project an Instant into the named time zone; returns an ISO 8601 string with the appropriate offset. Pass "UTC" for epoch offset 0, or e.g. "+02:00" / "-05:00".