diff options
Diffstat (limited to 'internal/calendar')
| -rw-r--r-- | internal/calendar/calendar.go | 44 | ||||
| -rw-r--r-- | internal/calendar/calendar_test.go | 24 |
2 files changed, 65 insertions, 3 deletions
diff --git a/internal/calendar/calendar.go b/internal/calendar/calendar.go index 98dec43..e0f5217 100644 --- a/internal/calendar/calendar.go +++ b/internal/calendar/calendar.go @@ -6,11 +6,49 @@ import ( "time" ) -// Compute returns the Ordinary Form liturgical day for date under the given -// Selection, with the ordered layer stack supplying celebrations. It is pure -// and total: any valid Gregorian date yields a LiturgicalDay. +// Compute returns the liturgical day for date under the given Selection, with +// the ordered layer stack supplying celebrations. It is pure and total: any +// valid Gregorian date yields a LiturgicalDay. Selection.Form "old" computes the +// Extraordinary Form (1962); anything else computes the Ordinary Form. func Compute(date time.Time, sel Selection, layers []Layer) LiturgicalDay { date = date.UTC().Truncate(24 * time.Hour) + if sel.Form == "old" { + return computeEF(date, sel, layers) + } + return computeOF(date, sel, layers) +} + +// computeEF computes the Extraordinary Form (1962) day. +func computeEF(date time.Time, sel Selection, layers []Layer) LiturgicalDay { + td := temporalEF(date) + merged := mergeLayers(layers) + cands := []candidate{{Cel: td.Cel, Temporal: true, Season: td.Season}} + for slug, rc := range merged { + cel := buildCelebration(slug, rc) + when, ok := celebrationDate(cel, date.Year(), sel) + if !ok { + continue + } + if sameDay(when, date) { + cands = append(cands, candidate{Cel: cel, Temporal: false, Season: td.Season}) + } + } + obs, others := pickEF(cands) + day := LiturgicalDay{ + Date: date, Season: td.Season, Week: td.Week, Weekday: date.Weekday(), + Observed: obs.Cel, Colour: colourOf(obs, td), ObservedBand: precedenceEF(obs), + } + for _, o := range others { + if o.Temporal { + continue + } + day.Others = append(day.Others, o.Cel) + } + return day +} + +// computeOF computes the Ordinary Form day. +func computeOF(date time.Time, sel Selection, layers []Layer) LiturgicalDay { td := temporal(date, sel) merged := mergeLayers(layers) diff --git a/internal/calendar/calendar_test.go b/internal/calendar/calendar_test.go index 909f1d8..28dba9e 100644 --- a/internal/calendar/calendar_test.go +++ b/internal/calendar/calendar_test.go @@ -37,3 +37,27 @@ func TestComputeCycles(t *testing.T) { t.Errorf("2025 weekday cycle = %s want I", got.WeekdayCycle) } } + +func TestComputeEF(t *testing.T) { + sel := DefaultSelection() + sel.Form = "old" + // an EF layer with a I-class feast on 2025-08-15 (Assumption) + layer := Layer{ID: "tridentine", Type: "universal", Cels: map[string]RawCelebration{ + "assumption": {Fields: map[string]string{ + "date": "08-15", "rank": "class-1", "colour": "white", "name.en": "Assumption BVM", + }, Variants: map[string]map[string]string{}}, + }} + got := Compute(d("2025-08-15"), sel, []Layer{layer}) + if got.Observed.Slug != "assumption" || got.Observed.Rank != RankClass1 { + t.Fatalf("EF 2025-08-15 observed = %q/%v want assumption/class-1", got.Observed.Slug, got.Observed.Rank) + } + // the EF season on 2025-08-15 is Time after Pentecost (not OF's "ordinary") + if got.Season != TimeAfterPentecost { + t.Errorf("EF season = %s want time-after-pentecost", got.Season) + } + // OF path unchanged for the same date + ofDay := Compute(d("2025-08-15"), DefaultSelection(), []Layer{layer}) + if ofDay.Season != Ordinary { + t.Errorf("OF season = %s want ordinary", ofDay.Season) + } +} |
