Problem Description

This program accurately displays the  date of Easter for any year since the establishment of the Gregorian calendar  in 1582.  It uses an algorithm  from Volume 3 of "The Art of Computer Programming" set of books written by Donald Knuth.  

Background and Techniques

Easter dates are more complicated than one would image.  Here's a simplified version as I understand it:  

Traditionally we celebrate Easter  in the spring, on a Sunday, after the Spring equinox.   The Church fathers, the Anglican church I believe, decided to make it the first Sunday after the first full moon after the Vernal Equinox on March 21.  The catch was that the Vernal Equinox isn't always on March 21 and determining that first full moon date was difficult. They wanted a method (an algorithm!) that was simple and would work for a long time.  So they assumed that the equinox would be on March 20, and made a table of "Ecclesiastical" Full Moon (EFM) dates that was always within a few days of astronomical full moon dates but could be specified in a table of reasonable size.  The  first EFM after March 20 is called the Paschal Full Moon  (PFM) for reasons I couldn't determine. (Oh - just ran across it - Pascha is the Hebrew name for Passover.)  The first Sunday after the PFM is officially Easter in any year.   The preceeding description doesn't quite seem to match this description found at a US Naval Observatory web site but may produce the same result:

"The actual conditions to determine the date for Easter are (1) Easter must be on a Sunday; (2) this Sunday must follow the 14th day of the paschal moon; (3) the paschal moon is that of which the 14th day (full moon) falls on or next follows the day of the vernal equinox; and (4) the equinox is fixed in the calendar as March 21. Easter can never occur before March 22 or later than April 25." 

There is discussion  between the Catholic church and the World Council of Churches that Easter dates be changed to the Sunday after the 2nd Saturday in April (or the second Sunday in April, or at least based on astronomical full moon dates).   So the whole problem may get easier in a century  or so - they have only been discussing it since 1960.   

The source code assumes the Western standard calculation method based on Gregorian calendar.  It  includes a second project, EasterCheck, that matches Knuth's algorithm against a second algorithm I found on the Web.  It does this for a range of years at start-up time.  (They match.)   I would have left this check in the original program, but stripped it back out just to keep the code as short  as possible.

Running/Exploring the Program 

Suggestions for Further Study

The above discussion didn't  touch on the Julian vs Gregorian differences, or the Othodox vs Anglican methods, or the Council of Nicea, or the Metonic cycle or Astarte and Ostare, ancient goddesses of fertility.  

As usual, you can spend many happy hours on the Web learning about Easter, it's origins and the intricacies of the algorithms (did I mention the 19 year Metonic cycle?).  Just search on "Easter date" or "Easter algorithm" to get started. 

 

Maybe add other holidays like New Year's,  Independence Day, and Christmas  to the program.   (Or the holidays celebrated in your country.)   Actually, if you change the date display format to include day of week, these might be even useful.  Perhaps display a list of holiday days and dates after the user selects a year.    

If you'd like to add holidays that depend on the day of week count in a month (the 1st Monday, the 4th Thursday, etc.), how would you go about it?  

Delphi has a DayOfWeek function that returns an integer between 1 and 7 with 1-Sunday and 7=Saturday.  I'd probably start by getting the day of week for the 1st day of the month in question, then calculate the number of days add to get to the 1st occurrence of the day you want, then add 7 for each additional week to get to the desired occurrence (2nd, 3rd, 4th).   So to get to the 4th Thursday, for example, code something like:

Nov1:=StrToDate('11/1/2000');

First:=DayOfWeek(Nov1);

DaysToThurs:=5-First; 

{If Nov 1 was Fri or Sat, then add a week}

If DaysToThurs < 0 then DaysToThurs:=DaysToThurs+7;

Thanksgiving:= Nov1+DaysToThurs+21;