diff options
Diffstat (limited to 'lib/kernel/date_spec.mli')
| -rw-r--r-- | lib/kernel/date_spec.mli | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/lib/kernel/date_spec.mli b/lib/kernel/date_spec.mli index 3fe9625..70a3030 100644 --- a/lib/kernel/date_spec.mli +++ b/lib/kernel/date_spec.mli @@ -1,9 +1,45 @@ -(** A sanctoral entry's date expression. *) -type t = Fixed of { month : int; day : int } [@@deriving sexp] +(** A sanctoral entry's date expression. + + [Fixed] is a civil (month, day) that recurs every year. The other two move: + [Easter_offset] is a signed day count from the rite's own Easter, and + [Nth_weekday] is the nth (or nth-from-last) given weekday of a month. + + Sunday-relative forms ("the Sunday on or after 2 November") are + deliberately absent: nothing in this repository needs one yet, and the same + mechanism admits them when something does. *) +type t = + | Fixed of { month : int; day : int } + | Easter_offset of int + | Nth_weekday of { month : int; nth : int; weekday : Date.weekday } +[@@deriving sexp] (** Validates against the leap-year maximum, so 29 February is constructible. *) val fixed : month:int -> day:int -> (t, string) result -(** [None] when the spec does not occur in that year (29 February in a common - year) or falls outside the supported domain. *) -val resolve : t -> year:int -> Date.t option +(** Rejects an offset further than a year from Easter in either direction -- + past that, a spec is a data error rather than a calendar. Deliberately + generous: Septuagesima is Easter-63 and Time after Pentecost runs well past + Easter+180. *) +val easter_offset : int -> (t, string) result + +(** [nth] is 1-based forward, or negative from the end ([-1] is the last). + Rejects [nth = 0] (meaningless), [|nth| > 5] (no month has six of any + weekday), and a month outside 1..12. *) +val nth_weekday : month:int -> nth:int -> weekday:Date.weekday -> (t, string) result + +(** [resolve spec ~year ~easter] is the civil date [spec] denotes in [year], + where [easter] is that year's Easter as the RITE reckons it -- supplied by + the caller, never computed here, since {!Computus} ships both Gregorian and + Julian and choosing one in the kernel would be silently wrong for a + Julian-reckoning rite. + + [None] means "this spec does not occur in that year", per variant: + - [Fixed]: 29 February in a common year, or a date outside 1583..9999. + - [Easter_offset]: the resolved date falls outside 1583..9999. This is + reachable at the domain edges -- {!Date.add_days} is unbounded total + arithmetic and will happily denote a date outside the domain. + - [Nth_weekday]: the month has no such occurrence (a fifth Sunday it + lacks). + + Total: never raises on any in-range year, for any constructible spec. *) +val resolve : t -> year:int -> easter:Date.t -> Date.t option |
