@core/time separates elapsed time from wall-clock time. Bind it when you need to measure durations or work with UTC timestamps.
Three types of time
Duration for elapsed amountsTimeMark for measuring elapsed time and frame deltasTimestamp for real-world UTC instants
These types stay opaque. Pass them to the package functions. Do not construct them with struct syntax.
Measuring elapsed time
Use TimeMark for a monotonic measurement point. Use Duration for the elapsed amount.
@core/time TimeMark, mark_now, duration_between, as_seconds
previous ~= mark_now()
current = mark_now()
delta = duration_between(previous, current)
previous = current
seconds = as_seconds(delta)
This shape works for frame-delta style code without requiring a scheduler or animation package.
UTC timestamps
Use Timestamp for real-world UTC instants that may be logged, stored or exchanged with external systems.
@core/time Timestamp, timestamp_from_iso_string, timestamp_from_unix_milliseconds, to_iso_string
parse_created || -> Timestamp, Error!:
return timestamp_from_iso_string("1970-01-01T00:00:00.000Z")!
;
created = parse_created() catch:
then timestamp_from_unix_milliseconds(0.0)
;
io.line(to_iso_string(created))
timestamp_from_iso_string takes the fallible path because invalid strings can fail. Handle it with ! or catch. For the full function list, backend behaviour and deferred surfaces, see Core time advanced.
@core/time separates elapsed time from wall-clock time. It belongs to the binding-backed Core package family with no prelude alias, so it requires an explicit dependency clause.
@core/time carries Core origin with ExternalBinding backing. See Package origins and backing for origin and backing rules.
Dependency roots
Bind individual symbols or the whole namespace:
@core/time Duration, TimeMark, mark_now, duration_between, as_seconds
@core/time
previous = time.mark_now()
Opaque types
The package exposes three opaque types. Do not construct them with struct syntax or inspect their fields. Pass them to the package functions.
Type | Purpose |
Duration | Signed elapsed amount |
TimeMark | Monotonic clock mark for deltas and frame timing |
Timestamp | UTC wall-clock instant for logs, storage and system boundaries |
All three use the handle ABI. They carry no source-visible fields.
Monotonic clock functions
Function | Parameters | Returns | Error |
mark_now() | none | TimeMark | no |
elapsed_since(start) | TimeMark | Duration | no |
duration_between(start, end) | TimeMark, TimeMark | Duration | no |
mark_now() returns the current monotonic mark. elapsed_since(start) returns the duration from start to now. duration_between(start, end) returns the duration from start to end.
Wall-clock timestamp functions
Function | Parameters | Returns | Error |
timestamp_now() | none | Timestamp | no |
timestamp_from_unix_seconds(seconds) | Float | Timestamp | no |
timestamp_from_unix_milliseconds(milliseconds) | Float | Timestamp | no |
timestamp_from_iso_string(text) | String | Timestamp, Error! | yes |
timestamp_from_iso_string is the only fallible function. Invalid ISO strings return through Error!.
@core/time Timestamp, timestamp_from_iso_string, timestamp_from_unix_milliseconds
created = timestamp_from_iso_string("not-a-date") catch:
then timestamp_from_unix_milliseconds(0.0)
;
Duration construction and helpers
Function | Parameters | Returns | Error |
duration_from_seconds(seconds) | Float | Duration | no |
duration_from_milliseconds(milliseconds) | Float | Duration | no |
as_seconds(duration) | Duration | Float | no |
as_milliseconds(duration) | Duration | Float | no |
is_negative(duration) | Duration | Bool | no |
abs(duration) | Duration | Duration | no |
clamp(duration, min, max) | Duration, Duration, Duration | Duration | no |
Timestamp helpers
Function | Parameters | Returns | Error |
unix_seconds(timestamp) | Timestamp | Float | no |
unix_milliseconds(timestamp) | Timestamp | Float | no |
to_iso_string(timestamp) | Timestamp | String | no |
Access and return contracts
All parameters use shared access. No function requires mutable access. All return values stay fresh. timestamp_from_iso_string returns through Error! on invalid input. Every other function stays infallible.
Backend behaviour
HTML-JS lowers mark_now to globalThis.performance.now(). timestamp_now lowers to Date.now(). to_iso_string lowers to (new Date(#0)).toISOString(). Duration and timestamp construction helpers lower to inline JavaScript expressions.
HTML-Wasm lacks a Wasm lowering for these functions. See progress matrix for current target availability.
Unsupported source forms
- Direct symbol-path clauses such as
@core/time/mark_now face rejection. Use direct selections or a namespace clause. - Named arguments are not supported. Binding-backed calls are positional-only.
- Do not construct
Duration, TimeMark or Timestamp with struct syntax. - Do not inspect opaque type fields directly.
- The package does not expose receiver methods.
Deferred surfaces
Calendar date types, time zones, local-time conversion, locale-aware formatting, timers, sleep, intervals, animation callbacks and non-JS lowerings remain deferred. Browser animation-frame integration belongs in a future web-specific package rather than @core/time. See progress matrix for current status.
Related concepts