calendar: compute real Easter dates and temporal-cycle seasons
resolveDay() no longer hardcodes season: 'trinitytide'. Easter is computed via the Anonymous Gregorian algorithm (verified against 16 known reference dates spanning 1583-2100); Advent/Christmastide/ Epiphanytide follow the Christmas-anchored rules (including Advent's "Sunday nearest Nov 30"); Septuagesima through Trinitytide come from easter-offsets.yml, reshaped from single named anchor points into real ranges plus single-day overrides for Corpus Christi and Sacred Heart. occurring feasts (calendar/feasts.ts) are still a stub — the sanctoral calendar and Double-vs-not ranking are a separate, larger project.
This commit is contained in:
+21
-5
@@ -14,6 +14,26 @@ export type Weekday =
|
||||
// actually resolves the "opinionated but configurable" tension: the opinion
|
||||
// (trinitytide) lives in editable data, not in a TS enum you'd recompile to
|
||||
// change.
|
||||
//
|
||||
// A real limitation this doesn't fully solve: a single `season` string can
|
||||
// only hold one mutually-exclusive value per day, but several independent
|
||||
// liturgical windows overlap without sharing boundaries. For example, on a
|
||||
// real day between Candlemas (Feb 2) and Ash Wednesday, Compline's Marian
|
||||
// antiphon should already be Ave Regina Caelorum, but Lent's Alleluia
|
||||
// suppression and hymn swap shouldn't have started yet — two things that
|
||||
// are both true at once, which one `season` value can't represent.
|
||||
//
|
||||
// Real season resolution now exists (calendar/temporal.ts, calendar/easter.ts),
|
||||
// and the Marian-antiphon case above is handled — but not by adding a
|
||||
// `season` value for it. hours/marian-antiphon.ts checks the real date
|
||||
// directly instead of going through `season` at all for that one window.
|
||||
// That's a fine, scoped fix for one known overlap; it isn't a general
|
||||
// solution. If another mechanism turns up with the same shape (a window
|
||||
// that doesn't nest inside one `season` bucket), reach for the same
|
||||
// pattern — a direct date check bypassing `season` — rather than trying to
|
||||
// force `season` to hold two truths at once. Only worth generalizing into
|
||||
// several independent named windows/flags on `LiturgicalDay` itself if a
|
||||
// third case shows up and the duplication starts to hurt.
|
||||
export type Season = string;
|
||||
|
||||
// Open-ended on purpose — the actual ranking scheme (double/semidouble/simple,
|
||||
@@ -35,11 +55,7 @@ export interface LiturgicalDay {
|
||||
/** ISO date, e.g. "2026-08-09" */
|
||||
date: string;
|
||||
weekday: Weekday;
|
||||
/**
|
||||
* Real season resolution depends on Easter's date (see calendar/easter.ts,
|
||||
* not implemented until milestone 4). Until then this is a placeholder and
|
||||
* must not be trusted by any hour's logic.
|
||||
*/
|
||||
/** Real temporal-cycle season, computed via calendar/temporal.ts. */
|
||||
season: Season;
|
||||
/** Always [] until milestone 4 wires up calendar/feasts.ts. */
|
||||
occurring: OccurringFeast[];
|
||||
|
||||
Reference in New Issue
Block a user