date/time/datetime and real objects, in TS vs. Python.
Python has distinct datetime.date/datetime.datetime classes, so a real
object unambiguously satisfies exactly one of date/datetime (never
both), matching model.md §10's mutual-exclusion rule for the object form.
The Document layer here has no such distinction -- src/document.ts
maps bothdate and datetime onto the single native Date type (see
its file-top comment) -- so a real Date value carries no signal, by
itself, of which kind its field was meant to declare, UNLESS it came from
a schema-directed parse (readOml's DATE/DATETIME tokens, or
deserialize.ts's materialize upgrading an ISO string). Those two call
sites go through src/temporal.ts's parseDateToken/parseDatetimeToken,
which tag the returned Date with the kind that was actually read (issue
#14). dateKind() below consults that tag when present.
This resolves the issue #14 gap for the case that actually matters: the
same Document, materialized once against a schema that says date, no
longer also satisfies a different schema that says datetime for the
same label -- matching Python's isinstance-based exclusion. A Date
that never passed through a schema-directed parse (e.g. new Date()
constructed directly by application code) carries no tag and stays
ambiguous by necessity: there is no signal to draw a kind from, so it is
still accepted for whichever of date/datetime the field declares, as
before. That residual case is not a bug this change tries to close --
see temporal.ts's file-top comment for the full reasoning.
The string form was already, and remains, mutually exclusive on its own
terms regardless of tagging: a bare ISO date string never also satisfies
datetime, and vice versa.
date/time/datetimeand real objects, in TS vs. Python.Python has distinct
datetime.date/datetime.datetimeclasses, so a real object unambiguously satisfies exactly one ofdate/datetime(never both), matching model.md §10's mutual-exclusion rule for the object form. The Document layer here has no such distinction --src/document.tsmaps bothdateanddatetimeonto the single nativeDatetype (see its file-top comment) -- so a realDatevalue carries no signal, by itself, of which kind its field was meant to declare, UNLESS it came from a schema-directed parse (readOml's DATE/DATETIME tokens, ordeserialize.ts'smaterializeupgrading an ISO string). Those two call sites go throughsrc/temporal.ts'sparseDateToken/parseDatetimeToken, which tag the returnedDatewith the kind that was actually read (issue #14).dateKind()below consults that tag when present.This resolves the issue #14 gap for the case that actually matters: the same Document, materialized once against a schema that says
date, no longer also satisfies a different schema that saysdatetimefor the same label -- matching Python'sisinstance-based exclusion. ADatethat never passed through a schema-directed parse (e.g.new Date()constructed directly by application code) carries no tag and stays ambiguous by necessity: there is no signal to draw a kind from, so it is still accepted for whichever ofdate/datetimethe field declares, as before. That residual case is not a bug this change tries to close -- seetemporal.ts's file-top comment for the full reasoning.The string form was already, and remains, mutually exclusive on its own terms regardless of tagging: a bare ISO date string never also satisfies
datetime, and vice versa.