Datetime grammar: definitions #
This file gives a direct, parser-independent transcription of the datetime grammar, its component
value function, and the declarative relation connecting a string to its epoch-millisecond value.
Well-formedness takes the same shape as the decimal and duration grammars — the string is the
rendering of well-formed components — but the datetime grammar describes a date optionally
followed by a time, a fractional-seconds field, and a zone designator, so the components form a
nested record rather than a flat sequence of fields.
The Digit⁺ predicate IsDigits and its fixed-width refinement IsFixedDigits (the grammar's
Digit{n}, used for every numeric field here) are shared with the decimal and duration grammars
and live in Cedar.Thm.Data.String, together with the shared natOf numeric reader.
Numeric constraints #
The grammar's Constraints block bounds each numeric field. These are pure arithmetic predicates
over the field values; daysInMonth and isLeapYear transcribe the two auxiliary functions the
day constraint depends on.
The grammar's daysInMonth(y, m): 30 for April/June/September/November, 28 or 29 for
February depending on the leap year, and 31 otherwise.
Equations
Instances For
Components #
Each nonterminal of the grammar becomes a record of its fixed-width digit fields. A syntaxWf
predicate pins the field widths (Digit{n}) and a constraintsWf predicate imposes the numeric
bounds from the grammar's Constraints block.
YYYY is Digit{4}; MM and DD are Digit{2}.
Equations
- d.syntaxWf = (String.IsFixedDigits 4 d.year ∧ String.IsFixedDigits 2 d.month ∧ String.IsFixedDigits 2 d.day)
Instances For
The month/day bounds: 01 ≤ MM ≤ 12 and 01 ≤ DD ≤ daysInMonth(YYYY, MM).
Equations
Instances For
hh, mm, and ss are each Digit{2}.
Equations
- t.syntaxWf = (String.IsFixedDigits 2 t.hours ∧ String.IsFixedDigits 2 t.minutes ∧ String.IsFixedDigits 2 t.seconds)
Instances For
The offset's hh and mm are each Digit{2}, matching the Time nonterminals.
Equations
- o.syntaxWf = (String.IsFixedDigits 2 o.hours ∧ String.IsFixedDigits 2 o.minutes)
Instances For
Because the offset reuses the hh/mm nonterminals, it inherits their bounds:
00 ≤ hh ≤ 23 and 00 ≤ mm ≤ 59.
Instances For
The zone designator that terminates a datetime with a time: either the UTC marker 'Z'
(Date 'T' Time 'Z' / Date 'T' Time '.' SSS 'Z') or an explicit Offset.
- utc : Zone
- offset (o : OffsetComponents) : Zone
Instances For
A UTC marker imposes nothing; an offset must have well-formed digit fields.
Equations
Instances For
A UTC marker imposes nothing; an offset must satisfy the hh/mm bounds.
Equations
Instances For
Render the zone: 'Z' for UTC, otherwise the offset's ('+' | '-') hh mm.
Equations
Instances For
The time-bearing tail of a datetime: a Time, an optional fractional-seconds field SSS
('.' SSS), and a Zone. Absent SSS (none) corresponds to the forms without a
'.' SSS; some corresponds to the '.' SSS forms.
- time : TimeComponents
- zone : Zone
Instances For
Lift IsFixedDigits 3 (the grammar's SSS ::= Digit{3}) to the optional field:
an absent SSS is trivially valid.
Equations
Instances For
The time and zone satisfy their numeric bounds. SSS is unconstrained (000–999 are all
valid), so it contributes no numeric constraint.
Equations
- tp.constraintsWf = (tp.time.constraintsWf ∧ tp.zone.constraintsWf)
Instances For
A datetime is a Date optionally followed by a time-bearing tail. none is the date-only
form Date; some tp covers the four Date 'T' Time … forms, with the presence of SSS
and the choice of Zone selecting among them.
- date : DateComponents
Instances For
Every present component satisfies its numeric bounds.
Equations
- c.constraintsWf = (c.date.constraintsWf ∧ match c.time with | none => True | some tp => tp.constraintsWf)
Instances For
Canonical string representation: the date, followed by the time-bearing tail when present.
Phrasing well-formedness existentially over asString (below) bakes the grammar's structure
in for free — the separators, the fixed field order, and the choice among the five top-level
forms all follow from the shape of the witnessing record.
Instances For
The datetime grammar production witnessed by a syntactically and numerically valid component record and its rendering.
Equations
- Cedar.Thm.Datetime.DatetimeProduction str components = (components.syntaxWf ∧ components.constraintsWf ∧ str = components.asString)
Instances For
A datetime string is well-formed exactly when it has a valid grammar production.
Equations
- Cedar.Thm.Datetime.IsWfDatetime str = ∃ (components : Cedar.Thm.Datetime.DatetimeComponents), Cedar.Thm.Datetime.DatetimeProduction str components
Instances For
Value relation #
The component value functions below transcribe the grammar's date/time →
milliseconds-since-epoch formula. IsDatetimeValue str v then reuses the same witnesses as
IsWfDatetime and states that their denotation is v. No second string parser is part of the
trusted grammar specification.
Day count of a date since the Unix epoch (1970-01-01), via Howard Hinnant's days_from_civil
algorithm. This transcribes Std.Time.PlainDate.toEpochDay over raw Nat fields, independently
of the Std.Time date type.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The offset's signed second count: ± (hh × 3600 + mm × 60). Positive offsets (+hhmm) are
east of UTC, so the parser subtracts this to normalize to UTC.
Equations
Instances For
Signed UTC-normalization seconds contributed by a zone: 0 for the 'Z' marker, and the
offset's second count otherwise.
Equations
Instances For
Milliseconds-since-epoch value of a well-formed date's midnight UTC.
Equations
Instances For
Milliseconds-since-epoch value of a datetime's time-bearing tail relative to its date's midnight: the wall-clock time in milliseconds, less the zone offset (converting to UTC), plus the optional fractional-seconds field.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Milliseconds-since-epoch value of a whole datetime: the date's midnight plus the time-bearing
tail's contribution (0 for the date-only form).
Instances For
v is the value of the datetime literal str: str is the rendering of syntactically and
numerically well-formed datetime components, and v is their epoch-millisecond denotation.
The existential supplies the grammar decomposition directly, so this relation does not
re-parse the string. It is total on well-formed syntax (wf_iff_exists_value) and
single-valued (isDatetimeValue_unique).
Equations
- Cedar.Thm.Datetime.IsDatetimeValue str v = ∃ (components : Cedar.Thm.Datetime.DatetimeComponents), Cedar.Thm.Datetime.DatetimeProduction str components ∧ v = components.toMillis
Instances For
Canonical serialization #
Datetime stores an arbitrary Int64 millisecond value, while the concrete syntax restricts
years to 0000 through 9999. Serialization is therefore partial. It always emits the most
explicit grammar form, YYYY-MM-DDTHH:mm:ss.SSS±HHMM, using a zero offset when UTC is in range and
the smallest minute offset needed at either endpoint. All decimal fields are rendered here rather
than through Std.Time's formatter.
Smallest millisecond value whose UTC civil date has a four-digit nonnegative year.
Equations
- Cedar.Thm.Datetime.MIN_UTC_MILLIS = -62167219200000
Instances For
Largest millisecond value whose UTC civil date has a four-digit nonnegative year.
Equations
- Cedar.Thm.Datetime.MAX_UTC_MILLIS = 253402300799999
Instances For
Largest legal timezone-offset magnitude, 23:59, in milliseconds.
Equations
- Cedar.Thm.Datetime.MAX_OFFSET_MILLIS = 86340000
Instances For
Exact lower endpoint representable by the datetime grammar.
Equations
Instances For
Exact upper endpoint representable by the datetime grammar.
Equations
Instances For
Render a natural number as an ASCII decimal string padded with leading zeroes to width.
Equations
- Cedar.Thm.Datetime.fixedWidthNat width n = String.ofList (List.leftpad width '0' (toString n).toList)
Instances For
Select UTC whenever possible. Immediately outside the UTC civil range, select the smallest minute offset that moves the local civil time back into that range.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Build canonical grammar components from an in-range local millisecond value and its selected
explicit offset. PlainDate.ofEpochDay supplies numeric calendar fields only; rendering is
performed by fixedWidthNat.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Executable mirror of IsFixedDigits.
Equations
- Cedar.Thm.Datetime.isFixedDigits width s = ((Cedar.Spec.Ext.toNat?' s).isSome && s.length == width)
Instances For
Executable mirror of DatetimeComponents.syntaxWf.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Executable mirror of DatetimeComponents.constraintsWf.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Produce certified canonical components for a datetime value. The final check is deliberately
stated in terms of the owned grammar and value function, insulating serialization from
Std.Time formatting behavior.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Canonical partial serializer for datetime values. Every successful result has the fixed form
YYYY-MM-DDTHH:mm:ss.SSS±HHMM.
Equations
Instances For
Canonical-form normalizer: parse the string and re-serialize. Returns none for malformed
inputs (mirror of the decimal and duration normalizers); because serialization is partial the
re-serialization is a bind rather than the total map used there.