type t = int64 option type span = t let never = -1L let of_uint64_us us = if us = never then None else Some us let to_uint64_us = function None -> never | Some us -> us let to_s us = if us = never then None else let s = Int64.unsigned_div us 86_400_L in Some s module Span = struct type t = span let of_uint64_us = of_uint64_us let to_uint64_us = to_uint64_us let to_s = to_s end let compare = Int64.unsigned_compare let now () = let d, ps = Ptime_clock.now () |> Ptime.to_span |> Ptime.Span.to_d_ps in if d < 0 then Fmt.failwith "Ptime_clock.now negative ptime" else let d = Int64.(mul (of_int d) 86_400_L) in let us = Int64.(div ps 1_000_000_L) in Int64.add d us let add_span t span = let us = Int64.add t span in if compare t us > 0 then None else Some us let sub_span t span = let us = Int64.sub t span in if compare t us < 0 then None else Some us let diff a b = if compare a b < 0 then None else Some (Int64.sub a b) (* (* microseconds since the UNIX Epoch, or "never" if None *) let jsont = let number_or_never_jsont = let never = let dec s = match s with | "never" -> None | _ -> Jsont.Error.msg Jsont.Meta.none "unexpected string value" in let enc = function None -> "never" | _ -> assert false in Jsont.map ~dec ~enc Jsont.string in let number = let dec n = Ptime.of_float_s n in let enc = function Some n -> Ptime.to_float_s n | _ -> assert false in Jsont.map ~dec ~enc Jsont.number in let enc = function None -> never | Some _ -> number in Jsont.any ~dec_string:never ~dec_number:number ~enc () in let make t = t in Jsont.Object.map ~kind:"Timestamp" make |> Jsont.Object.mem "t_s" number_or_never_jsont ~enc:Fun.id |> Jsont.Object.finish (* UINT64_MAX represents "never". *) let bin = Bin.map Bin.neint64 decode_int64 encode_int64 let bin_nbo = Bin.map Bin.beint64 decode_int64 encode_int64 let caqti : Ptime.t option Caqti_type.t = let encode v = Ok (encode_int64 v) in let decode v = Ok (decode_int64 v) in Caqti_type.custom ~encode ~decode Caqti_type.int64 *)