From a80e61963756a28a3963a0442a8ccc1572518373 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Tue, 28 Jul 2026 14:35:24 +0200 Subject: fix(calendar): OF precedence/transfer + readings resolution; EF Pentecost octave Fixes found by validating the offline engine per-day vs the LiturgicalCalendar API (OF) and missalemeum (EF) across 2005-2050. OF calendar is now 0 real errors in the forward window (season/cycle already perfect). OF precedence/transfer (calendar): - Ash Wednesday and Holy Week Mon-Wed are band-2 privileged, so a coinciding feast (Chair of St Peter on Ash Wednesday) is suppressed, not observed. - Solemnities transfer out of Holy Week / the Easter octave: the Annunciation defers to the Monday after the 2nd Sunday of Easter; St Joseph is anticipated to the Saturday before Palm Sunday; the Nativity of St John the Baptist moves to Jun 23 when a Lord's solemnity (Sacred Heart / Corpus Christi) falls Jun 24. - Within a precedence band, a solemnity of the Lord/BVM outranks a saint's (dignity tiebreak) rather than losing an alphabetical slug tie. - Perpetua & Felicity corrected optional -> obligatory memorial. OF readings resolution (bible.OFRef + lectionary data): - Verse-accurate Hebrew->Vulgate psalm mapping incl. the split psalms (9/10, 114/115, 116, 147); "+" verse joins and abbreviated ranges ("127-28") normalized; single-chapter books (2/3 John, Jude) get chapter 1. - Cleaned harvest artifacts from of-lectionary.ini (descriptive-suffix gospels, "or Year A" alternates, "*"/"[Vulg.]"/bracket markers, slash abbreviations); Joel/Malachi/Zechariah/Esther book-versification citations fixed to Vulgate. - Split a merged Ps 15:10/11 row in vul.tsv. Result: 0 unresolvable OF readings over 2557 rendered days (cycles A/B/C, varied Easters). EF: the Octave of Pentecost (Whit Monday-Saturday) is red, not white. --- internal/calendar/temporal.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'internal/calendar/temporal.go') diff --git a/internal/calendar/temporal.go b/internal/calendar/temporal.go index b0dc653..1c8d74f 100644 --- a/internal/calendar/temporal.go +++ b/internal/calendar/temporal.go @@ -117,6 +117,15 @@ func ferialDay(season Season, slug string, col Colour, week int, privFeria bool) Cel: Celebration{Slug: slug, Rank: RankFerial, Colour: col, Layer: "temporal"}} } +// privFerialDay builds a band-2 privileged weekday (Ash Wednesday, Holy Week +// Monday-Wednesday): a ferial no sanctoral feast or memorial can displace (only +// a solemnity may, and solemnities transfer off it -- Table of Liturgical Days +// #2). Distinct from ferialDay's PrivFeria (band 9) Lenten/Advent weekdays. +func privFerialDay(season Season, slug string, col Colour, week int) temporalDay { + return temporalDay{Season: season, Colour: col, Week: week, Rank: RankFerial, Privileged: true, + Cel: Celebration{Slug: slug, Rank: RankFerial, Colour: col, Layer: "temporal"}} +} + // temporal computes the temporal identity of date under the given Selection. func temporal(date time.Time, sel Selection) temporalDay { date = date.UTC().Truncate(24 * time.Hour) @@ -180,11 +189,16 @@ func temporal(date time.Time, sel Selection) temporalDay { if sun { return sundayDay(Lent, "palm-sunday", Red, 6) } - return ferialDay(Lent, "holy-week-"+weekdayAbbr(wd), Violet, 6, true) + // Holy Week Mon-Wed are band-2 privileged: no feast/memorial is kept. + return privFerialDay(Lent, "holy-week-"+weekdayAbbr(wd), Violet, 6) case !date.Before(ashWed) && date.Before(palmSunday): // Lent - if !date.Before(ashWed) && date.Before(ashWed.AddDate(0, 0, 4)) { - // Ash Wednesday through the Saturday after (before Lent I). + if sameDay(date, ashWed) { + // Ash Wednesday is band-2 privileged (suppresses any coinciding feast). + return privFerialDay(Lent, "lent-after-ashes-wed", Violet, 0) + } + if date.Before(ashWed.AddDate(0, 0, 4)) { + // Thursday-Saturday after Ash Wednesday (before Lent I): band-9 privileged. return ferialDay(Lent, "lent-after-ashes-"+weekdayAbbr(wd), Violet, 0, true) } lent1 := nextWeekday(ashWed, time.Sunday) -- cgit v1.3