Carter's algorithm for calculating Easter Sunday

There is a short algorithm circulating on the Internet for calculating the calendar date of Easter Sunday, and while it only works for the years 1900 to 2099 of the Gregorian calendar, it’s still sufficient enough in practice. The following is Carter's algorithm (notice that division only uses integers, e.g. 23/5 = 4 ; also, the operator '%' denotes that it only wants the remainder (modulo) from the division.

The original Carter algorithm for the years 1900 to 2099
b = 225 - 11 * (year % 19)
d = (b - 21) % 30 + 21
if d is greater than 48, then d = d - 1
e = (year + year / 4 + d + 1) % 7
q = d + 7 - e
if q is less than 32, then Easter Sunday is q of March
otherwise, Easter Sunday is (q - 31) of April

I couldn’t find anything about the author, only that the algorithm was published via the Royal Greenwich Observatory in 1996, and a copy of that publication is available via the Internet archive: Information Leaflet No. 57: 'The Date of Easter'. It appears that the algorithm was created in historically recent times, because the author uses techniques ideally suited for computers. In the following text, we’ll derive the algorithm for the Julian calendar, then for a selection of centuries in the Gregorian calendar. We’ll also look for possible improvements and simplifications wherever they make themselves evident. Finally, we’ll adjust the algorithm for all the years in the Gregorian calendar; unfortunately, I don’t know if the author originally did this, too.

Algorithm for the Julian calendar

For this analysis, we’ll first need to simplify the situation and start from the ground up by building a similar algorithm for the Julian calendar. To help with this, we’ll make a table of ecclesiastical full moons in the Julian calendar. The penultimate column always contains the March date that the full moon occurs on (if the March date falls on an April date, simply add 31 to that date; e.g. 12 April = 43 March). In the last column, we’ll calculate the difference in days between the cyclic full moon and 21 March (the church's official date set for the beginning of spring).

year % 19Ecclesiastical
full moon
MarchDays from
March 21
0Apr 53615
1Mar 25254
2Apr 134423
3Apr 23312
4Mar 22221
5Apr 104120
6Mar 30309
7Apr 184928
8Apr 73817
9Mar 27276
10Apr 154625
11Apr 43514
12Mar 24243
13Apr 124322
14Apr 13211
15Mar 21210
16Apr 94019
17Mar 29298
18Apr 174827

The series of numbers in the last column starts at 15, then gradually decreases by intervals of 11. If the result after the subtraction is ever less than 0, then 30 is added to the total, and so on. From this, we get this series of numbers using a fairly simple calculation:

(15 - 11 × (year % 19)) % 30

Unfortunately, in practice, we immediately encounter a problem, and that’s a negative divisor error from when the formula attempts to determine the remainder after dividing by 30. Depending on the programming language being used, the computer will often return an incorrect result. For example, the Python programming language correctly returns:

(-23) % 5
2

But PHP and Javascript, for example, spit out a negative result, which is not a good sign. This can be prevented by adding a constant that provides a suitable multiple for the divisor, that way the remainder after division won’t affect the calculation:

(-23) % 5, (-23 + 25) % 5
-3, 2

In this case, we helped with the constant. Its minimum size can be found as follows: the expression '11 × (year % 19)'. This expression can take on a maximum of 198 (e.g. the year 2013 took on this maximum size, because 2013 % 19 = 18; next multiply this number by 11; this gives us 11 x 18 = 198). Next, subtract 15 (198 - 15 = 183). Now, find the next multiple of 30 (do not round down). In this case, the next highest multiple of 30 would be the number 210. From there, we can safely add this number to the expression without affecting the size of the remainder after division.

(225 - 11 × (year % 19)) % 30

Note: we will generate the same series of numbers using the Gaussian formula, which is more elegant, because it does its calculation without the added necessity of constants:

(15 + 19 × (year % 19)) % 30

The author of the algorithm was interested in the March date of the full moon (in the table above it is in the penultimate column), which we get by simply adding the number 21. The author calculated the whole calculation in two lines, so we will do the same for the Julian calculation:

b = 225 - 11 × (year % 19)
d = b % 30 + 21

There are only 19 possible values of d in the Julian calendar (see the penultimate column of the table above). Now, it’s necessary to find out the day of the week for the ecclesiastical full moon, which we denote as e. For Sunday, e = 0, for Monday, e = 1, and so on till Saturday, e = 6:

e = (year + year / 4 + d) % 7

Finally, we find the March date of Easter Sunday as follows:

q = d + 7 - e

And that's it! The result looks like this:

Carter's algorithm for the Julian calendar
b = 225 - 11 * (year % 19)
d = b % 30 + 21
e = (year + year / 4) % 7
q = d + 7 - e
if q is less than 32, then Easter Sunday is q of March
otherwise, Easter Sunday is (q - 31) of April

Algorithm for the Gregorian calendar

This is how we can apply Carter's formula to the Julian calendar. In the Gregorian calendar, the situation is complicated by the shift of ecclesiastical new moons by seven days and ten days due to the reform, as well as by the changing solar and lunar correction in different centuries. Another complexity is the special treatment of epact 25. First, we need to derive an algorithm for the years 1583 to 1699 of the Gregorian calendar, setting the solar and lunar correction during these years as equal to 0. A series of ecclesiastical full moons now begins seven days later (10 days that were released during the reform minus 3 days shift ecclesiastical full moon). The formula for its generation then looks like the following:

(22 - 11 × (year % 19)) % 30

To prevent the occurrence of a negative number, we’ll use the constant again, which can now have 180 added to it. The result then looks like this:

b = 202 - 11 x (year % 19)
d = b % 30 + 21

Here's the problem: expression d, which displays the March date of the ecclesiastical full moon, can take values from 0 to 50 (29 + 21). If it has a value of 50, it means that a ecclesiastical new moon would occur on 19 April, which is unacceptable (there are only 19 different values of d in the Julian calendar, and this high a value is not one of them). In the Gregorian calendar, therefore, the latest ecclesiastical full moons are 'shrunk', see the table:

depactEcclesiastical
full moon
4727April 16
4826April 17
4925/25April 17/18
5024April 18

If the value of d = 50, then it’s necessary to reduce this value by one day, with the value of d = 49 (i.e. epact 25) to prevent its occurrence in the above mentioned years:

if d is equal to 50, then d = d - 1

Regarding the omitted ten days, we must also adjust the formula for determining the day of the week of the ecclesiastical full moon.

e = (year + year / 4 + d - 10) % 7

The rest is the same:

Carter's algorithm for the years 1583 - 1699
b = 202 - 11 * (year % 19)
d = b % 30 + 21
if d is equal to 50, then d = 49
e = (year + year / 4 + d - 10) % 7
q = d + 7 - e
if q is less than 32, then Easter Sunday is q of March
otherwise, Easter Sunday is (q - 31) of April

Similarly, we adjust the algorithm for the years 1900 to 2099, in these years the solar correction is equal to 3 and the monthly correction is equal to 1. The constant in the expression b is increased by the difference between the solar and lunar correction, i.e. by 2:

b = 204 - 11 × (year % 19)

The expression for calculating the day of the week is reduced by the solar correction, i.e. by 3:

e = (year + year / 4 + d - 13) % 7

Again, we must also decrease the value of d for epacts 24 and 25 (with an earlier date of the ecclesiastical full moon). The result will look like this then:

Carter's algorithm for the years 1900 to 2099
b = 204 - 11 * (year % 19)
d = b % 30 + 21
if d is greater than 48, then d = d - 1
e = (year + year / 4 + d - 13) % 7
q = d + 7 - e
if q is less than 32, then Easter Sunday is q of March
otherwise, Easter Sunday is (q - 31) of April

The attentive reader will now be amazed to find that we have derived a slightly different algorithm than the one at the beginning of the page. The difference is that the author of the algorithm subtracts the number 21 from b when calculating d, so the constant in the calculation of b must be increased:

b = 225 - 11 * (year % 19)
d = (b - 21) % 30 + 21

It’s unclear why the author did it; it's completely useless! Another small difference is in how the constant is subtracted when calculating e. Here, the thirteen-day difference between calendars is subtracted, so the author adds 1. He added 14 to -13, which is a multiple of 7, and as we already know, when calculating the remainder after dividing by 7, this superfluous difference does not matter at all. In this case, it’s unnecessary, as the expression in parentheses will certainly not be negative, but it does look better:

e = (year + year / 4 + d + 1) % 7

Now it remains to apply Carter's formula for all years of the Gregorian calendar, with a few lines to be added to accommodate the calculation of the solar and lunar corrections. Meanwhile, this special behavior needs to be addressed in epact 25 as well.

Carter's algorithm for all years of the Gregorian calendar
a = year % 19
k = year / 100
s = k - k / 4 - 12
m = 8 * (k - 14) / 25
b = 202 + s - m - 11 * a
d = b % 30 + 21
if d is equal to 49 and also 'a' is greater than 10, then d = d - 1
if d is equal to 50, then d = d - 1
e = (year + year / 4 + d - 10 - s) % 7
q = d + 7 - e
if q is less than 32, then Easter Sunday is q of March
otherwise, Easter Sunday is (q - 31) of April

If we use the mentioned Gaussian improvement of the calculation of the ecclesiastical full moon, we can shorten the calculation of d to a single line, without needing to calculate b:

d = (19 * a + 22 + s - m) % 30 + 21

The essence of the algorithm is the same as it is not only for the Gaussian algorithm, but also for others. We calculate the direct position of the ecclesiastical full moon, without the need to calculate an epact. The following Sunday is then set as Easter Sunday. That said, adjustments will be necessary depending on the century in the Gregorian calendar.