aboutsummaryrefslogtreecommitdiff
path: root/internal/calendar/temporal_ef.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/calendar/temporal_ef.go')
-rw-r--r--internal/calendar/temporal_ef.go48
1 files changed, 42 insertions, 6 deletions
diff --git a/internal/calendar/temporal_ef.go b/internal/calendar/temporal_ef.go
index 3d6c72c..e8630b9 100644
--- a/internal/calendar/temporal_ef.go
+++ b/internal/calendar/temporal_ef.go
@@ -35,7 +35,13 @@ func efColour(s Season) Colour {
}
// efSeason returns the 1962 season for date, by chronological date boundaries.
-func efSeason(date time.Time, y int, easter time.Time) Season {
+// efSlugSeason is the season used to NAME slugs and NUMBER weeks. It is not
+// always the liturgical season: 6-13 January is liturgically Christmas Time
+// (RG 72, see efSeason) while its days are still named and numbered from
+// Epiphany, which is what the lectionary keys and every downstream consumer
+// expect. Splitting the two is the whole point -- before this, one function
+// served both and the wrong boundary in one was the wrong boundary in both.
+func efSlugSeason(date time.Time, y int, easter time.Time) Season {
adventThis := adventStart(y)
christmasThis := time.Date(y, 12, 25, 0, 0, 0, 0, time.UTC)
jan6 := time.Date(y, 1, 6, 0, 0, 0, 0, time.UTC)
@@ -86,10 +92,34 @@ func efSunday(season Season, slug string, col Colour, rank Rank, week int) tempo
// temporalEF computes the 1962 temporal identity of date. Season is exact
// (oracle-validated); ranks/weeks are best-effort for display.
+// efSeason is the LITURGICAL season, which is what the colour follows.
+//
+// It differs from efSlugSeason on exactly one window. RG 72: "Tempus
+// natalicium decurrit a I Vesperis Nativitatis Domini usque ad diem 13
+// ianuarii INCLUSIVE" -- Christmas Time runs to 13 January, so 6-13 January is
+// the Epiphany SECTION OF Christmas Time, not the start of Time after
+// Epiphany. RG 119(a) backs the same boundary from the colour side, white
+// "usque ad expletum tempus Epiphaniae". Those eight days were coming out
+// green because this distinction did not exist.
+//
+// The slug season is deliberately left alone there: the days keep their
+// Epiphany names and week numbers, which is what the lectionary keys and the
+// generated downstream tables are built on. colitur, which models the two
+// axes separately from the start, does the same -- season christmastide,
+// slug ef-time-after-epiphany-sunday-1.
+func efSeason(date time.Time, y int, easter time.Time) Season {
+ if s := efSlugSeason(date, y, easter); s == TimeAfterEpiphany &&
+ date.Month() == time.January && date.Day() <= 13 {
+ return Christmas
+ }
+ return efSlugSeason(date, y, easter)
+}
+
func temporalEF(date time.Time) temporalDay {
date = date.UTC().Truncate(24 * time.Hour)
y := date.Year()
easter := Easter(y)
+ slugSeason := efSlugSeason(date, y, easter)
season := efSeason(date, y, easter)
col := efColour(season)
// The Octave of Pentecost (Whit Monday through the Ember Saturday, easter+50
@@ -130,7 +160,9 @@ func temporalEF(date time.Time) temporalDay {
case date.Month() == time.January && date.Day() == 1:
return efCel(Christmas, "ef-circumcision", White, RankClass1, 0)
case date.Month() == time.January && date.Day() == 6:
- return efCel(TimeAfterEpiphany, "ef-epiphany", White, RankClass1, 0)
+ // Christmas, not TimeAfterEpiphany: RG 72 puts Epiphany INSIDE Christmas
+ // Time, which runs to 13 January. The slug is unchanged.
+ return efCel(Christmas, "ef-epiphany", White, RankClass1, 0)
case sameDay(date, easter.AddDate(0, 0, -46)):
return efCel(Lent, "ef-ash-wednesday", Violet, RankClass1, 0)
case sameDay(date, easter.AddDate(0, 0, -14)):
@@ -161,7 +193,7 @@ func temporalEF(date time.Time) temporalDay {
// Sundays vs ferias of the current season.
if sun {
- week := efWeek(date, season, y, easter)
+ week := efWeek(date, slugSeason, y, easter)
rank := RankClass2
sundayColour := col
if season == Advent || season == Lent {
@@ -196,14 +228,18 @@ func temporalEF(date time.Time) temporalDay {
return efSunday(TimeAfterPentecost, "ef-time-after-epiphany-sunday-"+strconv.Itoa(e), Green, rank, e)
}
}
- return efSunday(season, "ef-"+string(season)+"-sunday-"+strconv.Itoa(week), sundayColour, rank, week)
+ // Season reported liturgically, slug named from the slug season -- the
+ // same split the resumed-Sunday branch just above already makes for
+ // its own reason ("Season stays time-after-pentecost; the Epiphany
+ // slug only routes the readings").
+ return efSunday(season, "ef-"+string(slugSeason)+"-sunday-"+strconv.Itoa(week), sundayColour, rank, week)
}
// The days between Ash Wednesday and the 1st Sunday of Lent have their own
// proper Masses (not part of a numbered Lenten week).
if season == Lent && date.Before(easter.AddDate(0, 0, -42)) {
return efCel(Lent, "ef-lent-after-ashes-"+weekdayLower(date), Violet, RankClass3, 0)
}
- week := efWeek(date, season, y, easter)
+ week := efWeek(date, slugSeason, y, easter)
rank := RankClass4 // per-annum feria
if season == Advent || season == Lent || season == Passiontide {
// III class ferias (1960 rubrics): Advent to Dec 16, and Lent/Passiontide.
@@ -240,7 +276,7 @@ func temporalEF(date time.Time) temporalDay {
// Unique ferial slug (season-week-weekday) so proper ferias (Lent, Advent,
// Holy Week, Ember days) can key their own readings; green-season ferias
// simply have no lectionary entry and fall back to the Sunday.
- return efCel(season, "ef-"+string(season)+"-"+strconv.Itoa(week)+"-"+weekdayLower(date), col, rank, week)
+ return efCel(season, "ef-"+string(slugSeason)+"-"+strconv.Itoa(week)+"-"+weekdayLower(date), col, rank, week)
}
// thirdSundayOfSeptember returns the third Sunday in September of year y.