Skip to main content

Module dates

Module dates 

Source
Expand description

Dates and durations for the query binding (spec/surface §1.3 “Dates and durations”, 4.8): the Dataview-parity function set, served as omgbase HOST functions through oqx’s call_function / call_method seam. Port of the reference’s oqx-js/dates.ts, function for function.

Two value conventions and no new value kinds: • a DATE is an ISO-8601 string — YYYY-MM-DD (date-only) or YYYY-MM-DDThh:mm:ss[.fff](Z|±hh:mm) — exactly what the store writes for updated_at/ts and what OQX already orders chronologically by code point (spec/oqx SEMANTICS §6); • a DURATION is a number of seconds.

Arithmetic between them is METHODS (d.plus(s), a.until(b)), never the +/- operators: + with a string operand concatenates (SEMANTICS §7), so "2026-01-05" + 86400 is "2026-01-0586400" and must stay so.

Everything is total: a value that is not a date (or a duration) yields absent (Null), so a where over mixed data filters quietly. Only a wrong ARITY is an error (filter_invalid, the surface’s eval error). The one impure input — the named points today, now, sow… — reads the HOST clock, UTC, as the instant now_ms the caller threads in: the Surface passes the clock it stamps commits with (OMGBASE_SPEC_CLOCK pins it; the fixtures run under the corpus clock, so date("today") is 2026-09-27 there). The language itself has no clock.

The pure half (parse / render / shift / until / fields / format / the duration grammar) is public for the unit tests; the two arms at the bottom (date_function, date_method) are what context.rs and the constant fold in query.rs call. Calendar arithmetic is done by hand (proleptic Gregorian, days-from-civil) — no date crate, no new dependency.

Structs§

DateValue
A parsed date: the instant (milliseconds since the Unix epoch), the offset it was WRITTEN in (minutes east of UTC; 0 for Z and for a date-only value), whether it is date-only, and whether it carried a fraction of a second as written (kept on render).
Duration
A parsed duration: the calendar counts years and months kept apart from the fixed-length seconds, so plus can be calendar-aware while dur() applies the 365-day / 30-day conventions.
Fields
The fields of a value in the offset it was written in (weekday 1 = Monday … 7 = Sunday).

Constants§

DATE_FUNCTIONS
The free functions and their arity.
DATE_METHODS
The methods and their arity: on a date string, and (dur_text/dur_iso) on a number.
MONTH_SECONDS
Days per month / year under the fixed conventions dur() applies.
NAMED_POINTS
The named points date() resolves against the clock.
YEAR_SECONDS

Functions§

calendar_parts
A duration as plus applies it: the WHOLE years and months are calendar months; a fractional year or month count is not calendar — its fraction is 365-day / 30-day seconds — and joins the fixed-length seconds.
canonical_date
date(x) on a string that is not a named point: the canonical form, or None.
date_function
call_function arm: date(x) / dur(x); None for any other name.
date_function_arity
The arity of date/dur, or None for any other name.
date_method
call_method arm: the date methods on a string receiver and the duration renderers on a number; a receiver of any other kind yields absent (the methods are total). None for any other name.
date_method_arity
The arity of a date method, or None for any other name.
date_of
date(x): a named point against the clock, else the canonical ISO form, else None.
dur_iso
n.dur_iso(): the ISO-8601 duration P[nD][T[nH][nM][nS]] — PT1H30M, P2DT3H, PT45S, PT0S for zero, a leading - for a negative duration. None for a non-number.
dur_of
dur(x): a number is that many seconds; a string is parsed; else None.
dur_text
n.dur_text(): "2d 3h", "1h 30m", "45s" — days, hours, minutes, seconds, zero parts omitted, "0s" for zero, a leading - for a negative duration, a fractional second kept ("1.5s"). None for a non-number.
duration_seconds
A duration’s length in seconds under the conventions: a year is 365 days, a month 30.
fields_of
The fields of the value in the offset it was written in.
format_date
d.format(pattern): yyyy year, MM month, dd day, HH hour, mm minute, ss second (two digits each), MMM the English month abbreviation (Jan), EEE the English weekday abbreviation (Mon); every other character is literal. Fields are read in the written offset; a date-only value has 00 time fields.
named_point
Resolve a named point at the instant now_ms (UTC): now is the instant with milliseconds (the form the store stamps commits in); the others are date-only — sow/eow the Monday/Sunday of the current week, som/eom the first/last day of the month, soy/eoy of the year. None for a name that is not a point.
parse_date
Parse an ISO-8601 date / datetime string; None for anything else (a non-string, a malformed string, an out-of-range field such as month 13 or hour 24). The shape: YYYY-MM-DD, optionally T/t/space + hh:mm[:ss[.fff…]] + an optional offset (Z, ±hh:mm, ±hhmm); a time without an offset is UTC; the fraction (1–9 digits, . or ,) is truncated to milliseconds.
parse_duration
Parse a duration string: Dataview’s <number> <unit> pairs, each pair separated from the next by spaces, a comma, or nothing ("1h30m", "2 days, 3 hours"; a trailing separator is malformed), units case-insensitive: y|yr|yrs|year|years, mo|mos|month|months, w|wk|wks|week|weeks, d|day|days, h|hr|hrs|hour|hours, m|min|mins|minute|minutes, s|sec|secs|second|seconds — or an ISO-8601 duration (P1DT2H, PT90M, P2W). None when it is neither.
plus_minus
d.plus(x) (sign 1) / d.minus(x) (sign -1).
render_date
The canonical string: YYYY-MM-DD for a date-only value; otherwise YYYY-MM-DDThh:mm:ss + .fff when the value carries a fraction (as written, or because arithmetic produced one) + Z for UTC or the written ±hh:mm.
shift_date
Shift a date by a whole number of calendar months (the month field moves and the day is clamped to the new month’s length) and then by seconds. A date-only value stays date-only when the seconds are a whole number of days; otherwise it becomes a datetime in its offset (UTC for a date-only receiver).
stamp_ms
A clock stamp (YYYY-MM-DDThh:mm:ss.fffZ, the form the Surface stamps commits in; any ISO datetime accepted) as milliseconds, or the wall clock when it does not parse.
until
a.until(b): seconds from a to b (negative when b is earlier), by instant.
wall_clock_ms
The process wall clock in milliseconds since the Unix epoch — what a caller without a pinned clock resolves the named points against.