OCaml codecs for the Citation File Format (CFF)
1(*---------------------------------------------------------------------------
2 Copyright (c) 2026 The ocaml-cff programmers. All rights reserved.
3 SPDX-License-Identifier: ISC
4 ---------------------------------------------------------------------------*)
5
6(** Date handling for CFF.
7
8 CFF uses ISO 8601 date format ([YYYY-MM-DD]) for all date fields.
9 This module wraps {!Ptime.date} for date representation and provides
10 parsing and formatting functions.
11
12 {1 Date Fields in CFF}
13
14 CFF has several date-related fields at different levels:
15
16 {2 Root Level}
17
18 - [date-released]: When the software/dataset was released
19
20 {2 Reference Level}
21
22 - [date-accessed]: When an online resource was accessed
23 - [date-downloaded]: When a resource was downloaded
24 - [date-published]: Formal publication date
25 - [date-released]: Release date (for software references)
26
27 {2 Entity Level}
28
29 - [date-start]: Event start date (for conferences)
30 - [date-end]: Event end date (for conferences)
31
32 {1 Date Format}
33
34 All dates use ISO 8601 format: [YYYY-MM-DD]
35
36 {2 Examples}
37
38 {[
39 date-released: 2024-01-15
40 date-accessed: 2024-06-30
41 ]}
42
43 {1 Year-Only Dates}
44
45 For historical works or when only the year is known, use the [year]
46 field (an integer) instead of a full date. *)
47
48(** A date as [(year, month, day)] tuple.
49
50 The tuple contains:
51 - [year]: Four-digit year (e.g., [2024])
52 - [month]: Month number (1-12)
53 - [day]: Day of month (1-31) *)
54type t = Ptime.date
55
56(** Parse a date from [YYYY-MM-DD] format.
57
58 Returns [Error (`Invalid_date s)] if the string is not a valid date.
59 Validates that the date is a real calendar date (e.g., rejects Feb 30). *)
60val of_string : string -> (t, [> `Invalid_date of string ]) result
61
62(** Format a date as [YYYY-MM-DD]. *)
63val to_string : t -> string
64
65(** Extract the year component. *)
66val year : t -> int
67
68(** Extract the month component (1-12). *)
69val month : t -> int
70
71(** Extract the day component (1-31). *)
72val day : t -> int
73
74(** Date equality. *)
75val equal : t -> t -> bool
76
77(** Date comparison (chronological order). *)
78val compare : t -> t -> int
79
80(** Pretty-print a date in [YYYY-MM-DD] format. *)
81val pp : Format.formatter -> t -> unit
82
83(** JSON/YAML codec for dates.
84
85 Parses strings in [YYYY-MM-DD] format and serializes back to the
86 same format. *)
87val jsont : t Jsont.t