(** Proleptic Gregorian calendar dates over the supported domain 1583..9999. [t] is opaque; the internal representation is a day-count (rata die) so arithmetic and comparison are total and cheap. *) type t type weekday = Sun | Mon | Tue | Wed | Thu | Fri | Sat [@@deriving sexp] (** [make ~year ~month ~day] validates the date; rejects a month/day out of range and any year outside 1583..9999. *) val make : year:int -> month:int -> day:int -> (t, string) result val year : t -> int val month : t -> int val day : t -> int val weekday : t -> weekday (** [to_rata]/[of_rata] expose the underlying day-count (days since 1970-01-01); [of_rata] and [add_days] are unbounded total arithmetic (they may denote a year outside 1583..9999 — only [make] enforces the domain). *) val to_rata : t -> int val of_rata : int -> t val add_days : t -> int -> t val compare : t -> t -> int (** ISO-8601 rendering and validating parsing. [of_iso8601] enforces the same domain as {!make}. *) val to_iso8601 : t -> string val of_iso8601 : string -> (t, string) result val weekday_to_string : weekday -> string (** Sexp form is an ISO-8601 atom, e.g. [2026-04-05]. [t_of_sexp] validates and raises [Of_sexp_error] on a malformed or out-of-domain date; loaders convert that to a [result]. *) val t_of_sexp : Sexplib0.Sexp.t -> t val sexp_of_t : t -> Sexplib0.Sexp.t