You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Utc: parse ISO 8601 / RFC 3339, and format with fractions of a second #533
Utc.to_iso_8601 formats an instant, but nothing parses one back, and the format drops fractions of a second.
What we needed while porting a Go service to 0.26.0-rc3: it keeps a ledger file of the droplets it created, written by Go with time.Time (RFC 3339 with nanoseconds, "2026-10-17T09:01:23.456789123Z", and "0001-01-01T00:00:00Z" for none). Reading it back in Roc means writing an RFC 3339 parser by hand. Times in JSON from other tools are the same: GitHub's published_at, systemd's timestamps, cloud APIs.
A sketch:
Utc.from_iso_8601 : Str -> Try(Utc, [InvalidTime(Str)]) # RFC 3339: Z or an offset, optional fractionUtc.to_iso_8601_nanos : Utc -> Str# "2026-10-17T09:01:23.456789123Z"
The calendar arithmetic is already there (InternalDateTime), and Utc's signed range covers year 1. If it is out of scope for basic-cli, a line in Utc's docs saying so would also help.
Thanks for the pointer to roc-time; keeping parsing out of the host makes sense.
We tried roc-time 0.3.0 (OffsetTimestamp.parse, then boundary) against our small hand-written parser on the times our files hold. Everything roc-time accepts agrees with ours exactly: .123456Z, .123Z, -04:00 offsets and Go's zero time 0001-01-01T00:00:00Z.
The one gap: these files are written by Go's time.Time JSON encoding, which is RFC 3339 with up to nine fraction digits (time.RFC3339Nano), and roc-time refuses 2026-10-20T17:01:16.123456789Z with UnsupportedPrecision. Its docs say six digits at most is by design, so for now we keep our parser.
That's roc-time's question rather than basic-cli's, so feel free to close this. If a nanosecond (RFC3339Nano) profile is in scope for roc-time, I'd be glad to open an issue there.
A correction to the above: I checked the actual file rather than assuming. Our ledger holds no nine-digit times any more. The tool that now writes it rewrites every entry with millisecond fractions on each save, so the Go-written times were already gone. roc-time 0.3.0 would read everything we have today.
So nine digits isn't a need for us, and I won't open anything on roc-time for it. We keep our small parser only because it covers the four things we use (parse, format, the start of a month, and Go's zero time), not because roc-time falls short.
Activity
y2kbugger commentedon Oct 21, 2026
Thanks for the pointer to roc-time; keeping parsing out of the host makes sense.
We tried roc-time 0.3.0 (
OffsetTimestamp.parse, thenboundary) against our small hand-written parser on the times our files hold. Everything roc-time accepts agrees with ours exactly:.123456Z,.123Z,-04:00offsets and Go's zero time0001-01-01T00:00:00Z.The one gap: these files are written by Go's
time.TimeJSON encoding, which is RFC 3339 with up to nine fraction digits (time.RFC3339Nano), and roc-time refuses2026-10-20T17:01:16.123456789ZwithUnsupportedPrecision. Its docs say six digits at most is by design, so for now we keep our parser.That's roc-time's question rather than basic-cli's, so feel free to close this. If a nanosecond (RFC3339Nano) profile is in scope for roc-time, I'd be glad to open an issue there.
y2kbugger commentedon Oct 21, 2026
Closing: answered by #534, which documents the boundary (parsing belongs in a time package such as roc-time, not the native host).
y2kbugger commentedon Oct 21, 2026
A correction to the above: I checked the actual file rather than assuming. Our ledger holds no nine-digit times any more. The tool that now writes it rewrites every entry with millisecond fractions on each save, so the Go-written times were already gone. roc-time 0.3.0 would read everything we have today.
So nine digits isn't a need for us, and I won't open anything on roc-time for it. We keep our small parser only because it covers the four things we use (parse, format, the start of a month, and Go's zero time), not because roc-time falls short.