aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/calendar/calendar.go44
-rw-r--r--internal/calendar/calendar_test.go24
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)
+ }
+}