The canonical serialization of xs:dateTime, xs:dateTimeStamp, and xs:date emits years above 9999 with a leading +:
>> string(xs:dateTime("10000-01-01T00:00:00Z"))
"+10000-01-01T00:00:00Z"
XSD's lexical space doesn't allow a leading + in year fields, so the engine's own output fails to round-trip through its own cast:
>> xs:dateTime(string(xs:dateTime("10000-01-01T00:00:00Z")))
FORG0001
The cause is chrono's %Y format specifier, which switches to a signed representation for years outside 0..=9999 (per its ISO 8601 expanded-representation convention). The three canonical_* functions for dateTime/dateTimeStamp/date in atomic/cast_datetime.rs use %Y; the gregorian types (canonical_g_year etc.) already format years manually and are unaffected.
Negative years are fine (-0005-... is the XSD form chrono happens to produce).
I ran into this while testing 24:00 rollover across year 9999 for fn:parse-ietf-date (#36). Fix incoming as a PR.
-Tony Bufort
The canonical serialization of
xs:dateTime,xs:dateTimeStamp, andxs:dateemits years above 9999 with a leading+:XSD's lexical space doesn't allow a leading
+in year fields, so the engine's own output fails to round-trip through its own cast:The cause is chrono's
%Yformat specifier, which switches to a signed representation for years outside 0..=9999 (per its ISO 8601 expanded-representation convention). The threecanonical_*functions for dateTime/dateTimeStamp/date inatomic/cast_datetime.rsuse%Y; the gregorian types (canonical_g_yearetc.) already format years manually and are unaffected.Negative years are fine (
-0005-...is the XSD form chrono happens to produce).I ran into this while testing 24:00 rollover across year 9999 for
fn:parse-ietf-date(#36). Fix incoming as a PR.-Tony Bufort