How to find Good Friday (or Easter) for any year:
This is Mikes original formula with full historical comments and a detailed description of what each step is doing. It will work just as it is, or you can use the short version. Both should give the exact same result.// FUNCTION: @GoodFridayHoliday
// LANGUAGE: Crystal Reports 8.5 / Crystal syntax
// REQUIRES: Functions; @yr
// RETURNS: dateVar: date of good friday
// DESCRIPTION:
// Calculates the date of Good Friday (Friday before Easter)
// CHANGE LOG:
// Written 6/28/03 by Mike Cook
numberVar yr := {@yr}; // The year for which to determine the date of Good Friday.
// The following calculation of the Date for Easter is based on Oudin's algorithm for
// determining the date of Easter and follows the algorithm given in the New Scientist
// magazine, issue No. 228 (Vol. 9) page 828 (March 1961). It was originally coded in
// Multics PL/1 by Dennis Capps in 9/80 to fix bug a in the easter calculation in a
// program called calendar originally written by Tom Van Vleck of MIT in 1972. It was
// converted to Crystal and modified to return the date of Good Friday by Mike Cook in
// 2003. The comments are mostly from the original PL/1.It should be valid for any date
// from 1583 to 4099, so we may have a year 4K issue.
Local numberVar a := yr Mod 19; // Find position of year in 19-year Lunar Cycle,
// called the Golden Number.
Local numberVar b := yr \ 100; // b is century number
Local numberVar c := yr Mod 100; // c is year number within century
Local numberVar d := b \ 4;
Local numberVar e := b Mod 4; // d, e and i, k are used in leap year adjustments.
Local numberVar i := c \ 4;
Local numberVar k := c Mod 4;
// The next step computes a correction factor used in the following step
// which computes the number of days between the spring equinox
// and the first full moon thereafter. The correction factor is needed
// to keep the approximation in line with the observed behavior of the moon.
// It moves the full moon date back by one day eight times in every 2500 years,
// in century years three apart, with four years at the end of the cycle.
// The constant 13 corrects the correction for the fact that this
// cycle was decreed to start in the year 1800.
Local numberVar g := (8 * b + 13) \ 25;
// Now the number of days after the equinox (21 March, by definition) that
// we find the next full moon. This is a number between 0 and 29.
// The term 19*a advances the full moon 19 days for each year of the
// Lunar Cycle, for a total of 361 days in the 19 years. The other 4.24 days
// are made up when a returns to zero on the next cycle. Thus, the
// full moon dates repeat every 19 years. The term b-d advances the
// date by one day for three out of every four century years, the
// years which are not leap years although divisible by 4.
// The term g is the correction factor calculated above, and 15
// adjusts this whole calculation to the actual conditions at that
// date on which the scheme began, probably in Oct of 1582.
Local numberVar h := ((19 * a) + b - d - g + 15) Mod 30;
// Now we are interested in how many days we have to wait after the
// full moon until we get a Sunday (which has to be definitely after
// the full moon). The following step calculates a number l which is
// one less than the number of days. Every ordinary year ends on the
// same day of the week on which it started; a leap year ends on the
// day of the week following the one on which it started. Thus, if
// it is known on what day of the week a date occurred in any year
// it is possible to calculate its day of the week in another year
// by marching through the week one day for each regular year and
// two for each leap year.
// The term k is the number of ordinary years
// since the last leap year; each such year brings the date of the
// full moon one day closer to Sunday, and so reduces the number of
// days to be waited (unless it goes negative, but modular arithmetic
// theory makes -1 := 6 where the modulus is 7).
// The term i is the number of leap years so far in the current century.
// each leap year has with it three ordinary years, and each such group
// advances the day of the week by 5 days. But in modulo 7 arithmetic
// subtracting 5 days is equivalent to adding 2 days. So we add
// two days for each group of four years in the current century.
// Since a century consists of 25 groups of four years, it advances
// the day of the week by 124 or 125 days depending on whether the
// century year is an ordinary or leap year. The remainders when
// these numbers are divided by seven are 5 and 6 respectively.
// The term e is the number of ordinary century years since the
// last leap century year. As with the groups of four years, we
// add two days for each rather than subtract 5 for each.
// Every fourth century year is a leap year; therefore,
// each group of four centuries advances the day of the week by
// 3*5+6 := 21 days, or 0 in modulo 7 arithmetic, and no
// term is necessary for time before the last leap century year.
// The constant term 32 adjusts the calculation for the day of the
// week of the equinox when the scheme was put into effect. It also
// is larger than necessary by 28 in order to assure that the
// subtractions of k and h never reduce the dividend below 0.
// Thus, mod(2*e + 2*i - k + 32, 7) gives one less than the number
// of days between the equinox and its following Sunday. But we need to
// calculate the number of days after the full moon. The term h,
// calculated in the previous step, gives the number of days after
// the equinox that the full moon occurs. Each of those days brings
// the full moon closer to the actual Sunday of Easter,
// so it reduces the number of days after the full moon until Easter.
// (Again, if h > 6, modular arithmetic theory readjusts the result to
// another cycle of 0 to 6, and here the constant 32 keeps the dividend > 0.)
Local numberVar l := ((2 * e) + (2 * i) - k + 32 - h) Mod 7;
// The calendar set up by Pope Gregory XIII and his advisor, the astronomer
// Clavius, provided for official full moon dates as well as matching
// the equinoxes and solstices with their nominal dates. But, since
// the period of the moon is not an exact number of days, some fudging
// was needed here as elsewhere in the calendar system. Some of the
// periods between successive full moons in the Lunar Cycle are 30 days,
// some 29 days. Clavius then arranged the periods carefully so
// that if a full moon fell on 20 March (the day before the equinox),
// the period following it would be of 29 days. The effect of this
// arrangement is that Easter can never occur later than 25 April.
// The above calculations assume uniform 30-day lunar periods. In rare
// cases (e.g., 1954 and 1981) one of these 29-day lunar periods causes
// the full moon to fall on a Saturday where a 30-day period would put
// it on a Sunday. The following step calculates the fudge factor for
// this situation. The result m is 0 if no fudging is necessary, or
// 1 if fudging is required.
Local numberVar m := (a + (11*h) + (19*l)) \ 433;
// Now we have calculated the number of days which will elapse between
// 21 march and Easter: h + (l + 1) - 7*m. The last two steps
// turn this into a month and day. In the first expression, the constant
// 90 assures that the the quotient will be at least 3 (= March).
// If the elapsed days exceed 9, then the quotient will be 4 (= April).
// In the second expression, if month := 3 then 33*month + 19 := 118 and the
// remainder of that part of the expression is 22; when month := 3,
// l + h - 7*m < 10, so 22 < day <= 31.
// If month := 4, 33*month := 132, and since h + l - 7*m > 9, the whole
// expression satisfies 5*32 := 160 < expr. The remainder is greater
// than 0 and less than 26.
// The following converts the number of days to Easter to the number of days
// to Good Friday: h + (l + 1) - 7*m -2. (2 days before Easter)
Local numberVar days_to_good_friday := h + l - (7*m) - 2;
Local numberVar mo := (days_to_good_friday + 90) \ 25;
Local numberVar da := (days_to_good_friday + (33 * mo) + 19) Mod 32;
cdate ( yr, mo, da) // Returns the date of Good Friday