Recommended library for parsing and printing RFC5322 time?

What is the recommended library for parsing and printing UTC timestamps RFC5322 formatted times?

In particular, are there any libraries that provide an out of the box analogue (and parser) for: Date.prototype.toUTCString() - JavaScript | MDN

It seems like the main popular libraries for handling dates/times in OCaml are Calendar and Ptime, but having experimented with them, they don’t handle parsing/printing out UTC timestamps RFC5322 formatted times.

I was able to find a parser for UTC timestamps RFC5322 formatted times that I can vendor from the OCaml-webmachine repository, but not yet sure how to print them at the moment:

Does there exist an out-of-the-box library for this case?

If not, how can I pretty print UTC timestamps RFC5322 formatted times using Ptime or Calendar?

Thanks.

Note sure exactly what you mean by “UTC timestamps” but given your link, why did you think it would ?

Ptime never claimed to support something else than RFC 3339 timestamps, I don’t see what’s incorrect here. Your format is simply not supported by Ptime. (Sorry to be so nitpicky on these words).

If you only need to print them I’m pretty sure it should be easy to do that from this representation and this function.

If you can use ISO timestamps (toISOString) instead, there’s a library
called ISO8601 to parse them. They might also be in the more specific
subset that Ptime.of_rfc3339 accepts.

Firstly, thanks for the quick response.

Thanks for the pointers to the functions -barring no out-of-the-box library, I did plan to pretty print them myself, so these references will likely cut down the time I spend on implementation.

I really don’t suppose it would be too difficult to print out the timestamps myself, it’s just that it would require reading and implementing the RFC, and then worrying about if I had handled all the edge cases myself, hence I was asking whether there was any existing library/prior project that had ran into this issue already.

Sorry to nitpick on your response - I wasn’t trying to pick on Ptime in particular or trying to make the claim that it should support conversions to this format, my reason for referencing Ptime was simply because it seemed to be a popular choice for encoding times in OCaml (hence why I also pointed to calendar).

From searching online, it seems many other programming languages have conversion functions to this format as part of their ecosystem, so I wanted to double check whether others had run into this problem before, because it could be very likely that there is some implementation of this function hiding in some existing OCaml codebase somewhere that I may have missed.

I’m parsing/consuming the output of external servers, so I’m hesitant to change the date format in case other things fail.

Okay, reading the MDN page I linked to, if the documentation is accurate, then I suppose it won’t be too much hassle to write my own printer, and I can just leech of the work of the OCaml-webmachine people (thx) for the parser.

Www, dd Mmm yyyy hh:mm:ss GMT

Well that doesn’t entail that you have to make it sound like Ptime has bugs in parsing a format it never claimed to parse.

Sorry, mea culpa, I’ve edited my initial post to avoid that inference, which was not my intention.

1 Like

If anyone runs into this problem themselves:

  • for parsing - vendor the ocaml-webmachine parser
  • for printing:

let to_utc_string t =
  let www = 
    Ptime.weekday t |> function `Sat -> "Sat" |`Fri -> "Fri" |`Mon -> "Mon" |`Wed -> "Wed" |`Sun -> "Sun" |`Tue -> "Tue" |`Thu -> "Thu" in
  let ((yyyy,mmm,dd), ((hh,mm,ss), _)) = Ptime.to_date_time t  in
  let mmm = match mmm with
    | 1 -> "Jan" | 2 -> "Feb" | 3 -> "Mar" | 4 -> "Apr" | 5 -> "May"
    | 6 -> "Jun" | 7 -> "Jul" | 8 -> "Aug" | 9 -> "Sep" | 10 -> "Oct"
    | 11 -> "Nov" | 12 -> "Dec" | _ -> assert false in
  Printf.sprintf "%s, %02d %s %04d %02d:%02d:%02d GMT"
    www dd mmm yyyy hh mm ss

seems to do the trick.

1 Like

For parsing, wouldn’t OCaml library : Scanf also work?

# let dt = "Tue, 01 Mar 2022 12:21:00 GMT"
# Scanf.sscanf dt "%3s, %03d %3s %4d %02d:%02d:%02d GMT" @@ fun wd dd mmm yyyy hh mm ss ->
  wd, dd, mmm, yyyy, hh, mm, ss;;
- : string * int * string * int * int * int * int =
("Tue", 1, "Mar", 2022, 12, 21, 0)
3 Likes

Nice @yawaramin. I bet though that the problem is that for parsing you might not face only GMT timestamps, and then you need get into the business of interpreting named time zones…

For machines these timestamps with non-normalized data and named time zones should really die.

2 Likes

Yeah in retrospect I probably jumped too quickly to comment. I see now webmachine is basically using scanf with some more transformation and error checking.

I still don’t know what a “UTC timestamp” really is, but you might want to also consider timedesc, part of timere. It parses and prints ISO 8601, supports time zones, includes other representations such as Date and ISO_week, and can be extended with timere to add powerful functionality for reasoning about time.

Apologies, maybe that was my poor use of terminology, and it seems like quite a few posts have commented on that.

To clarify, as described at the MDN docs I linked to, I meant a string encoding a time conforming to RFC 7231: RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content

To avoid further confusion, I can quote the relevant section below:

7.1.1.1. Date/Time Formats

Prior to 1995, there were three different formats commonly used by servers to communicate timestamps. For compatibility with old implementations, all three are defined here.

The preferred format is a fixed-length and single-zone subset of the date and time specification used by the Internet Message Format [RFC5322].

HTTP-date = IMF-fixdate / obs-date

An example of the preferred format is

Sun, 06 Nov 1994 08:49:37 GMT ; IMF-fixdate

I guess RFC5322 is the particular time format that I was trying to handle.