cljs-time parses ISO8601 offset string to wrong epoch milliseconds
0 reputation · 01 Feb 2023, 08:58 UTC
0 reputation · 01 Feb 2023, 08:58 UTC
When I parse an ISO8601 string that includes an explicit offset, the resulting inst epoch milliseconds do not match the expected UTC value. For example, "2023-12-31T23:59:59-05:00" should correspond to epoch ms 1704067199000, but the value returned is off by the offset amount.
My understanding is that cljs-time delegates to JavaScript Date parsing, which may normalize to local time or interpret offsets inconsistently across browsers. I also know core ClojureScript's inst stores UTC epoch ms with no time-zone context, so the offset handling must come from the parsing library.
Is this discrepancy caused by cljs-time's parsing pattern, or by JavaScript Date itself? Should I use cljs-time.format/parse with a pattern like "yyyy-MM-dd'T'HH:mm:ssZ", or is it necessary to bring in js-joda for reliable offset handling? How can I verify the parsed epoch ms across Chrome and Firefox?
32775 reputation · 01 Feb 2023, 12:39 UTC
The wrong epoch ms is caused by cljs-time's format/parse path, not by JavaScript Date itself in modern browsers. An inst is UTC epoch milliseconds with no zone context, so the parser must convert "2023-12-31T23:59:59-05:00" to the UTC instant 2024-01-01T04:59:59Z, epoch ms 1704067199000. If the result is off by exactly the offset, the offset was ignored or applied with the wrong sign.
With a pattern like "yyyy-MM-dd'T'HH:mm:ssZ" the offset may not be captured for the colon form, so the fields 2023-12-31T23:59:59 are treated as local time. The resulting inst is then shifted by the local zone offset relative to UTC, which looks like an error equal to the input offset.
js/Date.parse "2023-12-31T23:59:59-05:00"It should equal 1704067199000 in Chrome and Firefox.(require '[cljs-time.format :as f] '[cljs-time.coerce :as c])
(c/to-long (f/parse (f/formatters :date-time) "2023-12-31T23:59:59-05:00"))One diagnostic detail that changes the recommendation: which cljs-time version and which exact formatter you are using. cljs-time is effectively unmaintained and built on goog.date, so behavior varies by version and by whether you use a custom pattern or a built-in formatter.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.