The 1962 Roman Calendar Project

Wherein I attempt to calculate each day's liturgical information in the 1962 calendar with a program written in the Mathematica language. The 1962 calendar is used nowadays in the Extraordinary Form of the Roman Rite.

Also see the Roman Calendar Project blog at http://roman-calendar.blogspot.com/.

Table of Contents

The fundamental idea

The fundamental idea here is that there are two independent liturgical calendars running concurrently "on top of" our Gregorian wall calendars:

  • the seasonal calendar, whose days move through the Gregorian calendar with the date of Easter, and
  • the sanctoral calendar, whose days are permanently assigned to specific dates on the Gregorian calendar.

Every day in each calendar is assigned a rank. Often, a given Gregorian day will have two liturgical dates to be celebrated - one from the seasonal calendar and one from the sanctoral. The highest-ranking date wins and is celebrated that day; the other date is "commemorated" or moved to another day or ignored.

My approach to the problem is to:

  • find which day in the seasonal calendar is to be celebrated today,
  • look up today's date in the sanctoral calendar
  • adjudicate any conflicts between the two

Yes, I'm hiding some complexity. We'll get there.

First, some programming details

Absolute day numbering

I'll borrow some very handy day-name calculations from Reingold & Dershowitz's Calendrical Calculations. In order to use their algorithms as-is, I'll also set up a system in which we can number days sequentially from a remote epoch. Reingold & Dershowitz use the hypothetical Gregorian date of January 1, 1 A.D. as day 1, and all days are counted from there. To avoid potential leap-year problems with an extrapolated Gregorian calendar, I'll choose our day 1 to be shortly before the 1962 calendar went into effect, Saturday, January 2, 1960:

epoch = {1960, 1, 2};

Now we need a way to count days from this epoch. Fortunately, two Mathematica functions make this very easy: DateDifference and DatePlus:

absoluteFromGregorian[{year_Integer, month_Integer, day_Integer}] :=
  DateDifference[epoch, {year, month, day}]

gregorianFromAbsolute[abs_Integer] := 
  DatePlus[epoch, abs]

Here's how they're used. Today is July 14, 2009, 18091 days after our epoch in 1960:

In[2]:= absoluteFromGregorian[{2009, 7, 14}]
Out[2]= 18091

In[3]:= gregorianFromAbsolute[18091]
Out[3]= {2009, 7, 14}

If you prefer to think about converting one date 'to' another rather than 'from' another, we can define a couple of handy synonyms:

gregorianToAbsolute = absoluteFromGregorian;
absoluteToGregorian = gregorianFromAbsolute;

We get the same results:

In[4]:= gregorianToAbsolute[{2009, 7, 14}]
Out[4]= 18091

In[5]:= absoluteToGregorian[18091]
Out[5]= {2009, 7, 14}

Dayname functions

We'll use this notion of absolute day numbers to do day name calculations: when is the Sunday closest to November 30? When is the Sunday before November 1? When is the Wednesday following the seventh Sunday before Easter? Calendar aficionados will recognize these dates as the first Sunday of Advent, the last Sunday in October (on which is the celebration of Christ the King), and Ash Wednesday.

With these functions and the date of Easter, we can calculate every liturgical date on the calendar.

Setup

Here's our list of weekdays:

daynameList = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

Next, we find two pieces of information that will be needed for each of the dayname functions:

  • the absolute day number we'll be working from, and
  • the number of the day we're looking for (1 for Sunday, 2 for Monday, etc.); while we're at it, if the requested dayname isn't in daynameList, then there must have been a misspelling or something; report an error and exit the function.
daynameSetup[dayname_String, date_List] :=
  Module[{absdate, daynum}, Catch[
    absdate = DateDifference[epoch, date];
    daynum = Position[daynameList, dayname];
    daynum = If[Length[daynum] === 1,
      (* true clause *)
      daynum[[1, 1]],
      (* false clause *)
      Message[cathcal::dayspell, dayname]; Throw[]];
    {absdate, daynum}
  ]]
                      
cathcal::dayspell = "`1` is not a valid day name.";

And now to the dayname functions themselves. Each is taken from Ed Reingold's code in calendar.el.

daynameOnOrBefore

Ed Reingold notes in calendar.el that "[a]pplying this function to d+6 gives us the dayname on or after an absolute day d. Similarly, applying it to d+3 gives the dayname nearest to absolute date d, applying it to d-1 gives the dayname previous to absolute date d, and applying it to d+7 gives the dayname following absolute date d." That's how the other dayname functions work.

daynameOnOrBefore[dayname_String, date_List] :=
  Module[{absdate, daynum, res},
    {absdate, daynum} = daynameSetup[dayname, date];
    res = absdate - Mod[absdate - daynum, 7];
    DatePlus[epoch, res]
  ]

Here's a demonstration:

In[11]:= today = Take[DateList[], 3]
Out[11]= {2009, 7, 15}

In[12]:= ("The "<>#<>" on or before "<>DateString[today, "Date"]<>" is "<>DateString[daynameOnOrBefore[#, today], "Date"])& /@ daynameList//TableForm
Out[12]//TableForm= The Sunday on or before Wednesday 15 July 2009 is Sunday 12 July 2009
                    The Monday on or before Wednesday 15 July 2009 is Monday 13 July 2009
                    The Tuesday on or before Wednesday 15 July 2009 is Tuesday 14 July 2009
                    The Wednesday on or before Wednesday 15 July 2009 is Wednesday 15 July 2009
                    The Thursday on or before Wednesday 15 July 2009 is Thursday 9 July 2009
                    The Friday on or before Wednesday 15 July 2009 is Friday 10 July 2009
                    The Saturday on or before Wednesday 15 July 2009 is Saturday 11 July 2009

daynameOnOrAfter

daynameOnOrAfter[dayname_String, date_List] :=
  Module[{absdate, daynum, res},
    {absdate, daynum} = daynameSetup[dayname, date];
    absdate = absdate + 6;
    res = absdate - Mod[absdate - daynum, 7];
    DatePlus[epoch, res]
  ]

Here's a demonstration:

In[13]:= ("The "<>#<>" on or after "<>DateString[today, "Date"]<>" is "<>DateString[daynameOnOrAfter[#, today], "Date"])& /@ daynameList//TableForm
Out[13]//TableForm= The Sunday on or after Wednesday 15 July 2009 is Sunday 19 July 2009
                    The Monday on or after Wednesday 15 July 2009 is Monday 20 July 2009
                    The Tuesday on or after Wednesday 15 July 2009 is Tuesday 21 July 2009
                    The Wednesday on or after Wednesday 15 July 2009 is Wednesday 15 July 2009
                    The Thursday on or after Wednesday 15 July 2009 is Thursday 16 July 2009
                    The Friday on or after Wednesday 15 July 2009 is Friday 17 July 2009
                    The Saturday on or after Wednesday 15 July 2009 is Saturday 18 July 2009

daynameNearest

daynameNearest[dayname_String, date_List] :=
  Module[{absdate, daynum, res},
    {absdate, daynum} = daynameSetup[dayname, date];
    absdate = absdate + 3;
    res = absdate - Mod[absdate - daynum, 7];
    DatePlus[epoch, res]
  ]

Here's a demonstration:

In[14]:= ("The "<>#<>" nearest "<>DateString[today, "Date"]<>" is "<>DateString[daynameNearest[#, today], "Date"])& /@ daynameList//TableForm
Out[14]//TableForm= The Sunday nearest Wednesday 15 July 2009 is Sunday 12 July 2009
                    The Monday nearest Wednesday 15 July 2009 is Monday 13 July 2009
                    The Tuesday nearest Wednesday 15 July 2009 is Tuesday 14 July 2009
                    The Wednesday nearest Wednesday 15 July 2009 is Wednesday 15 July 2009
                    The Thursday nearest Wednesday 15 July 2009 is Thursday 16 July 2009
                    The Friday nearest Wednesday 15 July 2009 is Friday 17 July 2009
                    The Saturday nearest Wednesday 15 July 2009 is Saturday 18 July 2009

daynamePrevious

daynamePrevious[dayname_String, date_List] :=
  Module[{absdate, daynum, res},
    {absdate, daynum} = daynameSetup[dayname, date];
    absdate = absdate - 1;
    res = absdate - Mod[absdate - daynum, 7];
    DatePlus[epoch, res]
  ]

Here's a demonstration:

In[15]:= ("The "<>#<>" previous to "<>DateString[today, "Date"]<>" is "<>DateString[daynamePrevious[#, today], "Date"])& /@ daynameList//TableForm
Out[15]//TableForm= The Sunday previous to Wednesday 15 July 2009 is Sunday 12 July 2009
                    The Monday previous to Wednesday 15 July 2009 is Monday 13 July 2009
                    The Tuesday previous to Wednesday 15 July 2009 is Tuesday 14 July 2009
                    The Wednesday previous to Wednesday 15 July 2009 is Wednesday 8 July 2009
                    The Thursday previous to Wednesday 15 July 2009 is Thursday 9 July 2009
                    The Friday previous to Wednesday 15 July 2009 is Friday 10 July 2009
                    The Saturday previous to Wednesday 15 July 2009 is Saturday 11 July 2009

daynameFollowing

daynameFollowing[dayname_String, date_List] :=
  Module[{absdate, daynum, res},
    {absdate, daynum} = daynameSetup[dayname, date];
    absdate = absdate + 7;
    res = absdate - Mod[absdate - daynum, 7];
    DatePlus[epoch, res]
  ]

Here's a demonstration:

In[16]:= ("The "<>#<>" following "<>DateString[today, "Date"]<>" is "<>DateString[daynameFollowing[#, today], "Date"])& /@ daynameList//TableForm
Out[16]//TableForm= The Sunday following Wednesday 15 July 2009 is Sunday 19 July 2009
                    The Monday following Wednesday 15 July 2009 is Monday 20 July 2009
                    The Tuesday following Wednesday 15 July 2009 is Tuesday 21 July 2009
                    The Wednesday following Wednesday 15 July 2009 is Wednesday 22 July 2009
                    The Thursday following Wednesday 15 July 2009 is Thursday 16 July 2009
                    The Friday following Wednesday 15 July 2009 is Friday 17 July 2009
                    The Saturday following Wednesday 15 July 2009 is Saturday 18 July 2009

daynameDate

And finally, here are a couple of quick functions to find the dayname of a given Gregorian or absolute date:

daynameDate[date_List] := 
  Module[{mod},
    mod = Mod[absoluteFromGregorian[date], 7];
    If[mod === 0, "Saturday", Part[daynameList, mod]]];

daynameDate[absdate_Integer] := 
  Module[{mod},
    mod = Mod[absdate, 7];
    If[mod === 0, "Saturday", Part[daynameList, mod]]]

Here's a demonstration:

In[22]:= today = Take[DateList[], 3]
Out[22]= {2009, 7, 15}

In[23]:= DateString[today, "Date"]
Out[23]= Wednesday 15 July 2009

In[24]:= daynameDate[today]
Out[24]= Wednesday

In[25]:= daynameDate[absoluteFromGregorian[today]]
Out[25]= Wednesday

Easter

Easter is at the center of the seasonal calendar - all days from Septuagesima in February to all the Sundays after Pentecost are set distances from the date of Easter, and they all move around together as a unit through the Gregorian calendar with Easter at their center. Ven. John Henry Newman has an excellent explanation of this in his tract The Ordo de Tempore in the Roman Breviary.

So, let's calculate the date of Easter:

In[2]:= EasterDateList[2009]
Out[2]= {2009, 4, 12}

Definition

This definition is lifted directly from Ed Reingold's emacs lisp function holiday-easter-etc in emacs' holidays.el, and translated to Mathematica code. I left out his addition of 30 * century to the shifted epact, which is intended to keep it positive, since the shifted epact will never be negative in our practical use (I tested evey year between 1000AD and 9000AD and didn't find a negative value).

EasterDateList[year_Integer] :=
  Module[{century, shiftedEpact, adjustedEpact, paschalMoon},
    century = 1 + Quotient[year, 100];
    shiftedEpact = Mod[
      14
      + (11 Mod[year, 19]) (* age of moon for April 5 by Nicaean rule *)
      - Quotient[3 * century, 4] (* corrected for the Gregorian century rule *)
      + Quotient[5 + 8 * century, 25], (* corrected for Metonic cycle inaccuracy *)
      30];
    (* adjust for 29.5 day month *)
    adjustedEpact = 
      If[shiftedEpact === 0 || And[shiftedEpact === 1, 10 < Mod[year, 19]],
        (* true clause *)
        1 + shiftedEpact,
        (* false clause *)
        shiftedEpact];
    (* day after the full moon on or after March 21 *)
    paschalMoon = absoluteFromGregorian[{year, 4, 19}] - adjustedEpact;
    daynameOnOrBefore["Sunday", gregorianFromAbsolute[IntegerPart[paschalMoon + 7]]]
  ]

Mathematica functions used: Module, Quotient, Mod, If, || (Or), And, === (SameQ), < (Less), = (Set), IntegerPart.

Tests

As a test, let's compute a few recent Easter dates; compare the output to the dates given at http://aa.usno.navy.mil/data/docs/easter.php.

In[28]:= DateString[EasterDateList[#], "Date"]& /@ Range[2007, 2011]//TableForm
Out[28]//TableForm= Sunday 8 April 2007
                    Sunday 23 March 2008
                    Sunday 12 April 2009
                    Sunday 4 April 2010
                    Sunday 24 April 2011

A larger comparison can made with the dates found by Mathematica's Calendar package, which uses the different but related algorithm to find the date of Easter for a given year.

First, we note that when subtracting two identical date lists, the result is a list of 0s:

In[29]:= {2009, 7, 15} - {2009, 7, 15}
Out[29]= {0, 0, 0}

So let's find the date of Easter using these two methods, subtract the results from each other, and then remove all instances of {0, 0, 0}. If nothing is left, then each method found the same Easter dates. In the Calendar package, the date of Easter is given by the function EasterSunday[year].

In[34]:= (EasterDateList[#] - EasterSunday[#])& /@ Range[1962, 1965]
Out[34]= {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}

In[35]:= (EasterDateList[#] - EasterSunday[#])& /@ Range[1962, 1965] /. {0, 0, 0} -> Sequence[]
Out[35]= {}

In[36]:= (EasterDateList[#] - EasterSunday[#])& /@ Range[1962, 10000] /. {0, 0, 0} -> Sequence[]
Out[36]= {}

So EasterDateList is good for the next 8000 years, at least.

Principal dates of the year

The principalDates function

Now that we have all these functions, let's calculate the principal dates of the year. I could put in all of the Ember days and Rogation days, but you get the idea here.

principalDates[year_Integer] := 
  Module[{},
    easter = EasterDateList[year];

    advent1              = daynameNearest["Sunday", {year - 1, 11, 30}];
    advent2              = DatePlus[advent1, 1 * 7];
    advent3              = DatePlus[advent1, 2 * 7];
    emberWedAdvent       = daynameFollowing["Wednesday", advent3];
    emberFriAdvent       = daynameFollowing["Friday", advent3];
    emberSatAdvent       = daynameFollowing["Saturday", advent3];
    advent4              = DatePlus[advent1, 3 * 7];
    christmas            = {year - 1, 12, 25};
    christmasSunday      = daynameFollowing["Sunday", christmas];
    christmasOctave      = DatePlus[christmas, 1 * 7];
    (* The Sunday after January 1 and before January 6, if there is one; otherwise, January 2. *)
    holyName             = 
      If[absoluteFromGregorian[daynameOnOrAfter["Sunday", {year, 1, 2}]] <= absoluteFromGregorian[{year, 1, 5}],
      (* true *)
      daynameOnOrAfter["Sunday", {year, 1, 2}],
      (* false *)
      {year, 1, 2}];
    epiphany             = {year, 1, 6};
    holyFamily           = daynameFollowing["Sunday", epiphany];
    septuagesima         = DatePlus[easter, -9 * 7];
    sundaysPostEpiphany  = IntegerPart[DateDifference[daynameFollowing["Sunday", epiphany], septuagesima]/7];
    sexagesima           = DatePlus[easter, -8 * 7];
    quinquagesima        = DatePlus[easter, -7 * 7];
    ashWednesday         = daynameFollowing["Wednesday", DatePlus[easter, -7 * 7]];
    lent1                = DatePlus[easter, -6 * 7];
    lent2                = DatePlus[easter, -5 * 7];
    lent3                = DatePlus[easter, -4 * 7];
    lent4                = DatePlus[easter, -3 * 7];
    passionSunday        = DatePlus[easter, -2 * 7];
    palmSunday           = DatePlus[easter, -1 * 7];
    holyThursday         = daynamePrevious["Thursday", easter];
    goodFriday           = daynamePrevious["Friday", easter];
    easter               = easter;
    ascensionThursday    = daynameFollowing["Thursday", DatePlus[easter, 5 * 7]];
    pentecost            = DatePlus[easter, 7 * 7];
    trinitySunday        = DatePlus[easter, 8 * 7];
    corpusChristi        = daynameFollowing["Thursday", trinitySunday];
    (* be careful to use the Advent following Pentecost *)
    sundaysPostPentecost = IntegerPart[DateDifference[pentecost, DatePlus[daynameNearest["Sunday", {year, 11, 30}], -7]]/7];
    advent1ThisYear      = daynameNearest["Sunday", {year, 11, 30}];

    Print["First Sunday of Advent"<>": "<>DateString[advent1, "Date"]];
    Print["Second Sunday of Advent"<>": "<>DateString[advent2, "Date"]];
    Print["Third Sunday of Advent"<>": "<>DateString[advent3, "Date"]];
    Print["Ember Wednesday in Advent"<>": "<>DateString[emberWedAdvent, "Date"]];
    Print["Ember Friday in Advent"<>": "<>DateString[emberFriAdvent, "Date"]];
    Print["Ember Saturday in Advent"<>": "<>DateString[emberSatAdvent, "Date"]];
    Print["Fourth Sunday of Advent"<>": "<>DateString[advent4, "Date"]];
    Print["Christmas"<>": "<>DateString[christmas, "Date"]];
    Print["Sunday within the Octave of Christmas"<>": "<>DateString[christmasSunday, "Date"]];
    Print["Octave of Christmas"<>": "<>DateString[christmasOctave, "Date"]];
    Print["Feast of the Holy Name of Jesus"<>": "<>DateString[holyName, "Date"]];
    Print["Epiphany"<>": "<>DateString[epiphany, "Date"]];
    Print["Feast of the Holy Family"<>": "<>DateString[holyFamily, "Date"]];
    Print["Number of Sundays after Epiphany"<>": "<>ToString[sundaysPostEpiphany]];
    Print["Septuagesima"<>": "<>DateString[septuagesima, "Date"]];
    Print["Sexagesima"<>": "<>DateString[sexagesima, "Date"]];
    Print["Quinquagesima"<>": "<>DateString[quinquagesima, "Date"]];
    Print["Ash Wednesday"<>": "<>DateString[ashWednesday, "Date"]];
    Print["First Sunday of Lent"<>": "<>DateString[lent1, "Date"]];
    Print["Second Sunday of Lent"<>": "<>DateString[lent2, "Date"]];
    Print["Third Sunday of Lent"<>": "<>DateString[lent3, "Date"]];
    Print["Fourth Sunday of Lent"<>": "<>DateString[lent4, "Date"]];
    Print["Passion Sunday"<>": "<>DateString[passionSunday, "Date"]];
    Print["Palm Sunday"<>": "<>DateString[palmSunday, "Date"]];
    Print["Holy Thursday"<>": "<>DateString[holyThursday, "Date"]];
    Print["Good Friday"<>": "<>DateString[goodFriday, "Date"]];
    Print["Easter Sunday"<>": "<>DateString[easter, "Date"]];
    Print["Ascension"<>": "<>DateString[ascensionThursday, "Date"]];
    Print["Pentecost"<>": "<>DateString[pentecost, "Date"]];
    Print["Trinity"<>": "<>DateString[trinitySunday, "Date"]];
    Print["Corpus Christi"<>": "<>DateString[corpusChristi, "Date"]];
    Print["Number of Sundays after Pentecost"<>": "<>ToString[sundaysPostPentecost]];
    Print["First Sunday of Advent"<>": "<>DateString[advent1ThisYear, "Date"]];
  ]

My calculations for 2009

In[2]:= principalDates[2009]
First Sunday of Advent: Sunday 30 November 2008
Second Sunday of Advent: Sunday 7 December 2008
Third Sunday of Advent: Sunday 14 December 2008
Ember Wednesday in Advent: Wednesday 17 December 2008
Ember Friday in Advent: Friday 19 December 2008
Ember Saturday in Advent: Saturday 20 December 2008
Fourth Sunday of Advent: Sunday 21 December 2008
Christmas: Thursday 25 December 2008
Sunday within the Octave of Christmas: Sunday 28 December 2008
Octave of Christmas: Thursday 1 January 2009
Feast of the Holy Name of Jesus: Sunday 4 January 2009
Epiphany: Tuesday 6 January 2009
Feast of the Holy Family: Sunday 11 January 2009
Number of Sundays after Epiphany: 4
Septuagesima: Sunday 8 February 2009
Sexagesima: Sunday 15 February 2009
Quinquagesima: Sunday 22 February 2009
Ash Wednesday: Wednesday 25 February 2009
First Sunday of Lent: Sunday 1 March 2009
Second Sunday of Lent: Sunday 8 March 2009
Third Sunday of Lent: Sunday 15 March 2009
Fourth Sunday of Lent: Sunday 22 March 2009
Passion Sunday: Sunday 29 March 2009
Palm Sunday: Sunday 5 April 2009
Holy Thursday: Thursday 9 April 2009
Good Friday: Friday 10 April 2009
Easter Sunday: Sunday 12 April 2009
Ascension: Thursday 21 May 2009
Pentecost: Sunday 31 May 2009
Trinity: Sunday 7 June 2009
Corpus Christi: Thursday 11 June 2009
Number of Sundays after Pentecost: 25
First Sunday of Advent: Sunday 29 November 2009

A test against the Liber Usualis

Here's a function that finds the dates and numbers given in the "Table of Movable Feasts" in the 1997 St Bonaventure reprint of the 1953 Desclée Liber Usualis. Their table runs from 1997 to 2028.

The funny +-----+------ stuff helps my web formatting software build a nice table.

A quick function

liberUsualusTest[year_Integer] :=
  Module[{},
    easter = EasterDateList[year];
    septuagesima         = DatePlus[easter, -9 * 7];
    ashWednesday         = daynameFollowing["Wednesday", DatePlus[easter, -7 * 7]];
    ascensionThursday    = daynameFollowing["Thursday", DatePlus[easter, 5 * 7]];
    pentecost            = DatePlus[easter, 7 * 7];
    trinitySunday        = DatePlus[easter, 8 * 7];
    corpusChristi        = daynameFollowing["Thursday", trinitySunday];
    sundaysPostPentecost = IntegerPart[DateDifference[pentecost, DatePlus[daynameNearest["Sunday", {year, 11, 30}], -7]]/7];
    advent1ThisYear      = daynameNearest["Sunday", {year, 11, 30}];
    
    Print["|"<>
      ToString[year]<>"|"<>
      DateString[septuagesima, {"MonthNameShort", " ", "Day"}]<>"|"<>
      DateString[ashWednesday, {"MonthNameShort", " ", "Day"}]<>"|"<>
      DateString[easter, {"MonthNameShort", " ", "Day"}]<>"|"<>
      DateString[ascensionThursday, {"MonthNameShort", " ", "Day"}]<>"|"<>
      DateString[pentecost, {"MonthNameShort", " ", "Day"}]<>"|"<>
      DateString[corpusChristi, {"MonthNameShort", " ", "Day"}]<>"|"<>
      ToString[sundaysPostPentecost]<>"|"<>
      DateString[advent1ThisYear, {"MonthNameShort", " ", "Day"}]<>"|\n"<>
      "|------+--------+--------+--------+--------+--------+--------+----+--------|"];
  ]

My results

And here's the output of my function for the years 1997-2028:

YearSeptuaAsh WEasterAscenPenteCorpus#Advent
1997Jan 26Feb 12Mar 30May 08May 18May 2927Nov 30
1998Feb 08Feb 25Apr 12May 21May 31Jun 1125Nov 29
1999Jan 31Feb 17Apr 04May 13May 23Jun 0326Nov 28
2000Feb 20Mar 08Apr 23Jun 01Jun 11Jun 2224Dec 03
2001Feb 11Feb 28Apr 15May 24Jun 03Jun 1425Dec 02
2002Jan 27Feb 13Mar 31May 09May 19May 3027Dec 01
2003Feb 16Mar 05Apr 20May 29Jun 08Jun 1924Nov 30
2004Feb 08Feb 25Apr 11May 20May 30Jun 1025Nov 28
2005Jan 23Feb 09Mar 27May 05May 15May 2627Nov 27
2006Feb 12Mar 01Apr 16May 25Jun 04Jun 1525Dec 03
2007Feb 04Feb 21Apr 08May 17May 27Jun 0726Dec 02
2008Jan 20Feb 06Mar 23May 01May 11May 2228Nov 30
2009Feb 08Feb 25Apr 12May 21May 31Jun 1125Nov 29
2010Jan 31Feb 17Apr 04May 13May 23Jun 0326Nov 28
2011Feb 20Mar 09Apr 24Jun 02Jun 12Jun 2323Nov 27
2012Feb 05Feb 22Apr 08May 17May 27Jun 0726Dec 02
2013Jan 27Feb 13Mar 31May 09May 19May 3027Dec 01
2014Feb 16Mar 05Apr 20May 29Jun 08Jun 1924Nov 30
2015Feb 01Feb 18Apr 05May 14May 24Jun 0426Nov 29
2016Jan 24Feb 10Mar 27May 05May 15May 2627Nov 27
2017Feb 12Mar 01Apr 16May 25Jun 04Jun 1525Dec 03
2018Jan 28Feb 14Apr 01May 10May 20May 3127Dec 02
2019Feb 17Mar 06Apr 21May 30Jun 09Jun 2024Dec 01
2020Feb 09Feb 26Apr 12May 21May 31Jun 1125Nov 29
2021Jan 31Feb 17Apr 04May 13May 23Jun 0326Nov 28
2022Feb 13Mar 02Apr 17May 26Jun 05Jun 1624Nov 27
2023Feb 05Feb 22Apr 09May 18May 28Jun 0826Dec 03
2024Jan 28Feb 14Mar 31May 09May 19May 3027Dec 01
2025Feb 16Mar 05Apr 20May 29Jun 08Jun 1924Nov 30
2026Feb 01Feb 18Apr 05May 14May 24Jun 0426Nov 29
2027Jan 24Feb 10Mar 28May 06May 16May 2727Nov 28
2028Feb 13Mar 01Apr 16May 25Jun 04Jun 1525Dec 03

Results of the test

There seem to be two errors in the Movable Feast table in the 1997 reprint of the Liber Usualis:

  • For 2003, they list the first Sunday of Advent as November 23. Given that it's defined as the Sunday nearest November 30, this entry in the table should read "Nov 30".
  • For 2011, they list 24 Sundays after Pentecost. But the number of weeks between Pentecost, June 12 2011, and the Sunday before the start of Advent, November 20 2011, is 23: see http://www.wolframalpha.com/input/?i=20+November+2011+-+June+12+2011 (under "Time span:" click on "More forms").

Filling out the year

So now we have everything we need to find out what day it is in the liturgical calendar: we can find which day it is on the seasonal calendar and, from the Gregorian dat,e we know which day it is on the sanctoral calendar.

explain range thing and f/@range and things in f

Detailing each day

I know of two different approaches to the problem of calculating days on a liturgical calendar - Ken Bath's approach and mine, since those are the only two whose source code I've read.

Ken presents only the essential information about each day:

Weekday                  Mon Mar 16, 2009                   Purple 
                 Monday of the Third Week of Lent

so in his program, each day can be treated as an anonymous container to which the program assigns a seasonal color, a name and a type (here, weekday).

But if you want to present more detail (as I want to do), you'll have to treat each day as a detailed container with various proper texts, prayers, chants, a stational church, commentary, resource links, etc. So each day will need to be defined separately with all its various details and texts stored somewhere.

Resources

Links to information on the web.

Author: Bill White <minutiae@gmail.com>

Date: 2009-09-12 18:28:33 CDT

HTML generated by org-mode 6.29a in emacs 23