Internet timestamp formats: RFC 3339, HTTP-date and Unix epoch
README.md

timestamp #

Internet timestamp formats for OCaml: RFC 3339, HTTP-date and Unix epoch.

Internet protocols write time as text in several ways. JSON APIs use RFC 3339 ("2024-11-03T10:30:00Z"), HTTP headers use the date of RFC 9110 ("Sun, 06 Nov 1994 08:49:37 GMT"), and many APIs send POSIX epoch seconds or milliseconds as bare numbers. timestamp parses each of these into a Ptime.t and formats it back, and gives each a nox-json codec that a larger JSON codec can use for a timestamp field.

It needs OCaml 4.14 or later.

Installation #

$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam install timestamp

Usage #

# Timestamp.Rfc3339.parse "2024-11-03T10:30:00Z" |> Option.map (Timestamp.Rfc3339.format ~frac_s:3)
- : string option = Some "2024-11-03T10:30:00.000Z"
# Timestamp.Http.parse "Sun, 06 Nov 1994 08:49:37 GMT" |> Option.map Timestamp.Http.format
- : string option = Some "Sun, 06 Nov 1994 08:49:37 GMT"
# Timestamp.Unix.of_s 1_730_629_800 |> Option.map Timestamp.Unix.to_s
- : int option = Some 1730629800

API #

Each format has its own submodule with a parser, a formatter and, where one makes sense, a JSON codec of type Ptime.t Json.Codec.t.

Timestamp.Rfc3339 handles RFC 3339, a strict profile of ISO 8601.

  • parse applies the UTC offset and returns the instant.
  • parse_with_offset also returns the offset of the input in seconds, so the timestamp can be written back the way it came.
  • format ?frac_s ?tz_offset_s writes an instant with frac_s fractional digits and the given offset.
  • codec ?frac_s () is the JSON string codec.

Timestamp.Http handles the HTTP date of RFC 9110 Section 5.6.7. parse accepts the preferred IMF-fixdate and also the two obsolete forms that a recipient still has to accept, RFC 850 and ANSI C asctime. format always writes IMF-fixdate in GMT. One instant in the three forms reads Sun, 06 Nov 1994 08:49:37 GMT (IMF-fixdate), Sunday, 06-Nov-94 08:49:37 GMT (RFC 850, with a two-digit year) and Sun Nov 6 08:49:37 1994 (asctime).

Timestamp.Unix converts POSIX epoch seconds (of_s and to_s, with the int64 versions of_s_int64 and to_s_int64) and milliseconds (of_ms, to_ms), and drops any fraction of the unit. The conversions go through Ptime spans, which count picoseconds, and never through floats. A double that holds today's epoch in seconds, about 1.73 x 10^9, has neighbours 2^-22 s apart, about 0.24 microseconds, so it cannot hold a span's precision and a conversion through it can round a time to the next value. codec_s and codec_ms are the JSON number codecs.

ptime represents POSIX time, and timestamp only adds format conversions to Ptime.t. ISO8601 and timedesc parse dates and times in general, while timestamp handles only the Internet protocol forms listed here and their JSON codecs.

Licence #

ISC. See LICENSE.md.