summaryrefslogtreecommitdiff
path: root/lib/kernel/date.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/date.ml')
-rw-r--r--lib/kernel/date.ml25
1 files changed, 24 insertions, 1 deletions
diff --git a/lib/kernel/date.ml b/lib/kernel/date.ml
index 525b35b..cf5aabd 100644
--- a/lib/kernel/date.ml
+++ b/lib/kernel/date.ml
@@ -1,4 +1,4 @@
-type weekday = Sun | Mon | Tue | Wed | Thu | Fri | Sat
+type weekday = Sun | Mon | Tue | Wed | Thu | Fri | Sat [@@deriving sexp]
(* Internal representation: rata die = days since 1970-01-01 (proleptic
Gregorian). Howard Hinnant's civil<->days algorithm; OCaml's `/` truncates
@@ -56,3 +56,26 @@ let weekday t =
(* rata 0 = 1970-01-01 = Thursday (index 4 with Sun=0). *)
let w = (((t + 4) mod 7) + 7) mod 7 in
[| Sun; Mon; Tue; Wed; Thu; Fri; Sat |].(w)
+
+let weekday_to_string = function
+ | Sun -> "sunday" | Mon -> "monday" | Tue -> "tuesday" | Wed -> "wednesday"
+ | Thu -> "thursday" | Fri -> "friday" | Sat -> "saturday"
+
+let to_iso8601 t = Printf.sprintf "%04d-%02d-%02d" (year t) (month t) (day t)
+
+let of_iso8601 s =
+ match String.split_on_char '-' s with
+ | [ y; m; d ]
+ when String.length y = 4 && String.length m = 2 && String.length d = 2 -> (
+ match (int_of_string_opt y, int_of_string_opt m, int_of_string_opt d) with
+ | Some year, Some month, Some day -> make ~year ~month ~day
+ | _ -> Error (Printf.sprintf "date %S: not an ISO-8601 date" s))
+ | _ -> Error (Printf.sprintf "date %S: expected YYYY-MM-DD" s)
+
+let sexp_of_t t = Sexplib0.Sexp_conv.sexp_of_string (to_iso8601 t)
+
+let t_of_sexp sexp =
+ let s = Sexplib0.Sexp_conv.string_of_sexp sexp in
+ match of_iso8601 s with
+ | Ok t -> t
+ | Error msg -> Sexplib0.Sexp_conv.of_sexp_error msg sexp