75 lines
2.1 KiB
OCaml
75 lines
2.1 KiB
OCaml
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
|
|
*)
|