···11-type t = Ptime.date
22-33-let parse s =
44- (* Try parsing as RFC 3339 (which may include time) *)
55- match Ptime.of_rfc3339 s with
66- | Ok (ptime, _, _) -> Some (Ptime.to_date ptime)
77- | Error _ ->
88- (* Try parsing as just a date string YYYY-MM-DD *)
99- match String.split_on_char '-' s with
1010- | [year_s; month_s; day_s] -> (
1111- try
1212- let year = int_of_string year_s in
1313- let month = int_of_string month_s in
1414- let day = int_of_string day_s in
1515- if month >= 1 && month <= 12 && day >= 1 && day <= 31 then
1616- Some (year, month, day)
1717- else None
1818- with Failure _ -> None)
1919- | _ -> None
2020-2121-let format (year, month, day) =
2222- Printf.sprintf "%04d-%02d-%02d" year month day
2323-2424-let pp ppf t = Format.pp_print_string ppf (format t)
2525-2626-let to_string = format
2727-let of_string = parse
2828-2929-let today () =
3030- let open Unix in
3131- let tm = localtime (time ()) in
3232- (tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday)
3333-3434-let jsont =
3535- let kind = "ISO 8601 date" in
3636- let doc = "An ISO 8601 date string (YYYY-MM-DD)" in
3737- let dec s =
3838- match parse s with
3939- | Some t -> t
4040- | None ->
4141- Jsont.Error.msgf Jsont.Meta.none "%s: invalid ISO 8601 date: %S" kind s
4242- in
4343- let enc = format in
4444- Jsont.map ~kind ~doc ~dec ~enc Jsont.string
-52
lib/schema/sortal_schema_date.mli.unused
···11-(** ISO 8601 date handling for contact data.
22-33- Provides parsing, formatting, and jsont combinators for ISO 8601 dates.
44- Time components in parsed strings are ignored, only the date is extracted.
55-66- @see <https://www.iso.org/iso-8601-date-and-time-format.html> ISO 8601 *)
77-88-type t = Ptime.date
99-(** [t] represents a date as (year, month, day) tuple. *)
1010-1111-val jsont : t Jsont.t
1212-(** [jsont] is a bidirectional JSON type for ISO 8601 dates.
1313-1414- On decode: accepts JSON strings in ISO 8601 date format (e.g., "2024-11-03")
1515- or RFC 3339 format with times (e.g., "2024-11-03T10:30:00Z"), extracting
1616- only the date component.
1717-1818- On encode: produces dates in YYYY-MM-DD format.
1919-2020- {b Example:}
2121- {[
2222- let date = (2024, 11, 3) in
2323- Jsont_bytesrw.encode_string Date.jsont date
2424- (* Returns: "2024-11-03" *)
2525- ]} *)
2626-2727-val parse : string -> t option
2828-(** [parse s] parses an ISO 8601 date string.
2929-3030- Accepts various formats:
3131- - "2024-11-03" (date only)
3232- - "2024-11-03T10:30:00Z" (RFC 3339 with time, extracts date)
3333- - "2024-11-03T10:30:00-08:00" (with timezone, extracts date)
3434-3535- Returns [None] if the string is not a valid date format. *)
3636-3737-val format : t -> string
3838-(** [format t] formats a date as ISO 8601 (YYYY-MM-DD).
3939-4040- {b Example output:} ["2024-11-03"] *)
4141-4242-val pp : Format.formatter -> t -> unit
4343-(** [pp ppf t] pretty prints a date in ISO 8601 format. *)
4444-4545-val to_string : t -> string
4646-(** [to_string t] is an alias for {!format}. *)
4747-4848-val of_string : string -> t option
4949-(** [of_string s] is an alias for {!parse}. *)
5050-5151-val today : unit -> t
5252-(** [today ()] returns today's date in the local timezone. *)