Time


Quick Start

(module demo
  (import std.time std.io)
  (begin
    ;; Wall-clock epoch values
    (println (time:now-ms))                     ;; e.g. 1745712345678
    (println (time:format-iso8601-utc 0))       ;; "1970-01-01T00:00:00Z"

    ;; Monotonic timing for benchmarks
    (let ((t0 (time:monotonic-ms)))
      (time:sleep-ms 50)
      (let ((t1 (time:monotonic-ms)))
        (println (time:elapsed-ms t0 t1))))     ;; ~50

    ;; Broken-down calendar parts
    (let ((parts (time:utc-parts (time:now-ms))))
      (println (cdr (assoc 'year   parts)))
      (println (cdr (assoc 'month  parts)))
      (println (cdr (assoc 'day    parts))))))

std.time is a thin Eta layer over native %time-* primitives. It has no external dependencies and is auto-loaded by the prelude.


API

Wall-Clock & Monotonic Time

FunctionSignatureNotes
time:now-ms() -> intUnix epoch in milliseconds.
time:now-us() -> intUnix epoch in microseconds.
time:now-ns() -> intUnix epoch in nanoseconds.
time:monotonic-ms() -> intMonotonic clock; never goes backwards. Use for elapsed-time measurement.
time:elapsed-ms(start end) -> intNon-negative delta end - start; clamped to 0 if negative.
time:sleep-ms(ms) -> unspecifiedBlock the current process for ms milliseconds.

Broken-Down Calendar Parts

time:utc-parts and time:local-parts take a millisecond epoch value and return an association list with the following keys:

KeyRangeNotes
yearfull year, e.g. 2026
month112
day131Day of month.
hour023
minute059
second06060 allows for leap seconds where the platform reports them.
weekday060 = Sunday.
yearday0365Day of year.
is-dstboolDST in effect (always #f for UTC).
offset-minutesintOffset from UTC in minutes (always 0 for UTC).
(let ((parts (time:utc-parts (time:now-ms))))
  (cdr (assoc 'year parts)))     ;; => 2026

ISO-8601 Formatting

FunctionSignatureOutput
time:format-iso8601-utc(epoch-ms) -> string"YYYY-MM-DDTHH:MM:SSZ" (20 chars).
time:format-iso8601-local(epoch-ms) -> string"YYYY-MM-DDTHH:MM:SS±HH:MM" (25 chars).
(time:format-iso8601-utc 0)      ;; "1970-01-01T00:00:00Z"
(time:format-iso8601-local 0)    ;; e.g. "1969-12-31T19:00:00-05:00"

Patterns

Benchmarking

Always use the monotonic clock for elapsed-time measurement — wall-clock time can jump (NTP adjustments, DST transitions, manual clock changes).

(defun bench (thunk)
  (let ((t0 (time:monotonic-ms)))
    (let ((result (thunk)))
      (let ((t1 (time:monotonic-ms)))
        (cons result (time:elapsed-ms t0 t1))))))

Timestamps in Logs

(defun log-line (msg)
  (println (string-append
            "[" (time:format-iso8601-utc (time:now-ms)) "] " msg)))

Throttled Polling

(defun poll-every (interval-ms thunk)
  (let loop ()
    (thunk)
    (time:sleep-ms interval-ms)
    (loop)))

Notes