A Simple Easter Program
Refer to my page Why Yet Another Easter Algorithm? for more information on why I developed this Easter algorithm.
Here is the Python code for (Gregorian) Easter:
def Easter(year):
silver=year%19
cent=year//100
solar=cent-cent//4
lunar=(8*cent+13)//25
pfm=21+(19*silver+15+solar-lunar)%30
if pfm==50 or (pfm==49 and silver>10):
pfm=pfm-1
dow=(pfm+2+year+year//4-solar)%7
# If concerned with overflow replace
# first year with year%7 in dow
# calculation. This is not necessary
# in the Python version, but may be a
# concern in other languages in to
# which this function may be
# translated.
easter=pfm+7-dow
if easter>31:
return (4,easter-31)
else:
return (3,easter)
Here is the C code for (Gregorian) Easter:
#include <stdio.h>
#include <stdlib.h>
/* WARNING: This program does not check to see
* if its second argument exists, nor
* that it is an non-negative integer
*/
int main (int argc, char *argv[])
{
unsigned int year,silver,cent,solar,lunar,pfm,dow,easter;
year=(unsigned int) strtoul(argv[1],NULL,10);
silver=year%19;
cent=year/100;
solar=cent-cent/4;
lunar=(8*cent+13)/25;
pfm=21+(19*silver+15+solar-lunar)%30;
if (pfm==50 || (pfm==49 && silver>10))
pfm=pfm-1;
dow=(pfm+2+year%7+year/4-solar)%7;
/*
* year%7 rather than year to prevent
* overflows for years near maximum
*/
easter=pfm+7-dow;
if (easter>31)
printf("April %u\n",easter-31);
else
printf("March %u\n",easter);
return EXIT_SUCCESS;
}
This algorithm has a number of positive points:
No negative numbers are fed to the integer division and modulus operators for all years down to 0(inclusive) (note on year 0). Some algorithms use calculations of the lunar and solar corrections that can cause negative numbers to be fed to the integer division and modulus operators for some years; this is particularly common for years before 1583, when the current Gregorian algorithm for Easter was used nowhere. (See note on transition if this year seems to be incorrect.) With Python's guaranteed behavior for integer division and modulus, this is not usually a problem if one codes those algorithms in Python; Python just does what is usually the right thing in these cases. However, in some languages (eg, C) the integer division and modulus operators are not guaranteed to be correct for this purpose. (Refer to the Problems With the Div and Mod Operators With Negative Operands section in Julian Day Number Algorithms for more information on exactly what the problems are.)
Indeed, these programs if the order of the additions and subtractions is not altered never gives a negative number even as an intermediate result. So as shown in the C implementation one can assume that all numbers are non-negative.
Another positive point is that the Paschal Full Moon is calculated as a step in this algorithm. Remember the definition often given for Easter: the first Sunday after the first Full Moon which occurs on or after March 21. The first point to note is that these are Ecclesiastical Full Moons, which do not necessarily fall on the exact same dates as the true astronomical Full Moons. These Ecclesiastical Full Moons can be compared with the true astronomical Full Moons; though, in what time zone is a question that doesn't have an obvious answer.
Another positive point is that the algorithm is about as simple as it can be and still be correct for all non-negative years. I accomplish this by calculating the Paschal Full Moon directly without going though the intermediary of the epact; this is also the reason that that the solar correction is added and the lunar correction subtracted rather than the other way round: it proves to be simpler this way.
Indeed, if the integer division and modulus functions are defined correctly (as they are in Python, but not in C), then the the 5700000 year repeat cycle will persist even in the negative numbers. Though, I can't imagine why anyone would want to find Easter for negative years.
In addition refer to my page Why Yet Another Easter Algorithm? for other reasons that I regard this as the best Easter algorithm that I have seen.
What About Eastern Orthodox Easter?
I have a separate page, Calculating Orthodox Easter, on calculating the Julian and Orthodox Easters.
Footnotes
note on year 0: As I discuss the problems caused by the lack of a year zero in BC or BCE is Not Negative, it is clear that I am aware that in the standard historical year numbering there is no year 0; 1 BCE was immediately followed by 1 CE. However the algorithm implemented by the programs here, will "correctly" continue the pattern of the 5700000 year repeat cycle all the way down to an input of 0(inclusive). This allows analyses of patterns of Easter dates to be done with a loop that in Python like this: for year in range(5700000)
instead of having to do some offset to prevent "incorrect" early results from messing up the analysis.
note on transition: 1583 is correct; the first Gregorian Easter observed was in 1583. If this seems to be off by a year, you are almost certainly remembering the year of transition to the Gregorian calendar, which did occur in 1582; but it occurred in October of 1582. Easter was observed under the Julian system earlier in that year.