README

msgpack_datetime
https://sr.ht/~nabijaczleweli/msgpack_datetime
https://hexdocs.pm/msgpack_datetime/MsgpackDateTime.html
Unpack Elixir DateTimes from msgpack extension -1 timestamp fields

All three formats described in
  https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type
are supported for packing and unpacking (timestamp 32/64/96).

msgpack only tries the ext callbacks for tuples
(which is how Erlang structs are implemented) but packs maps (Elixir structs) as maps.
Thus, to pack, DateTime.now_utc(), you'd pack it as {MsgpackDateTime, DateTime.now_utc()},
and you'll get back {MsgpackDateTime, %DateTime{}} in return.
Example:
  dt = ~U[2025-12-10 12:53:25Z]
  :msgpack.pack({MsgpackDateTime, dt}, ext: MsgpackDateTime)
  === <<214, 255, 105, 57, 109, 69>>
  :msgpack.unpack("\x93\xC4\x06record\xD6\xFFi9mE\xCD\x01\xA4", ext: MsgpackDateTime)
  === {:ok, ["record", {MsgpackDateTime, dt}, 420]}

The MsgpackDateTime.StructWrap module contains functions to do this automatically
for terms containing maps and lists:
  :msgpack.pack(dt |> MsgpackDateTime.StructWrap.wrap(), ext: MsgpackDateTime)
  === <<214, 255, 105, 57, 109, 69>>
  {:ok, unpacked} = :msgpack.unpack("\\x93\\xC4\\x06record\\xD6\\xFFi9mE\\xCD\\x01\\xA4", ext: MsgpackDateTime)
  unpacked |> MsgpackDateTime.StructWrap.unwrap()
  === ["record", dt, 420]

https://hex.pm/packages/msgpack_datetime
  def deps do
    [
      {:msgpack_datetime, "~> 0.1"}
    ]
  end

Reproduce test data with:
  apt install libmsgpack-cxx-dev
  make
  ./testdata [dir]

Release tarballs are signed with nabijaczleweli@nabijaczleweli.xyz
  (pull with WKD, but 7D69 474E 8402 8C5C C0C4  4163 BCFD 0B01 8D26 58F1).
аnd stored in git notes as-if via the example program provided at
  https://man.sr.ht/git.sr.ht/#signing-tags-tarballs
and are thus available on the refs listing/tag page as .tar.gz.asc.