Saturday, March 22, 2008

Calculating Easter

It's Easter weekend, and as promised we're going to write a function to calculate when Easter occurs for a given year. Easter is a strange holiday in that it jumps around the calendar between March and April. This is because it is tied to the lunar cycle. Easter occurs on the first Sunday after the Paschal full moon.


ASP

  1. function dateEaster(someYear)
  2.     Dim goldenNumber
  3.     Dim solarCorrection
  4.     Dim lunarCorrection
  5.     Dim paschalFullMoon
  6.     Dim dominicalNumber
  7.     Dim difference
  8.     Dim dayEaster
  9.     goldenNumber = (someYear Mod 19) + 1
  10.     if someYear <= 1752 then
  11.         ' Julian calendar
  12.         dominicalNumber = (someYear + (someYear / 4) + 5) Mod 7
  13.         paschalFullMoon = (3 - (11 * goldenNumber) - 7) Mod 30
  14.     else
  15.         ' Gregorian calendar
  16.         dominicalNumber = (someYear + (someYear / 4) - (someYear / 100) + (someYear / 400)) Mod 7
  17.         solarCorrection = (someYear - 1600) / 100 - (someYear - 1600) / 400
  18.         lunarCorrection = (((someYear - 1400) / 100) * 8) / 25
  19.         paschalFullMoon = (3 - 11 * goldenNumber + solarCorrection - lunarCorrection) Mod 30
  20.     end if
  21.     do until dominicalNumber > 0
  22.         dominicalNumber = dominicalNumber + 7
  23.     loop
  24.     do until paschalFullMoon > 0
  25.         paschalFullMoon = paschalFullMoon + 30
  26.     loop
  27.     if paschalFullMoon = 29 or (paschalFullMoon = 28 and goldenNumber > 11) then
  28.         paschalFullMoon = paschalFullMoon - 1
  29.     end if
  30.     difference = (4 - paschalFullMoon - dominicalNumber) Mod 7
  31.     if difference < 0 then
  32.         difference = difference + 7
  33.     end if
  34.     dayEaster = paschalFullMoon + difference + 1
  35.     if dayEaster < 11 then
  36.         ' Easter occurs in March.
  37.         dateEaster = DateSerial(someYear, 3, dayEaster + 21)
  38.     else
  39.         ' Easter occurs in April.
  40.         dateEaster = DateSerial(someYear, 4, dayEaster - 10)
  41.     end if
  42. end function

PHP

  1. function dateEaster($someYear)
  2. {
  3.     $goldenNumber = fmod($someYear, 19) + 1;
  4.     if ($someYear <= 1752)
  5.     {
  6.         // Julian calendar
  7.         $dominicalNumber = fmod($someYear + ($someYear / 4) + 5, 7);
  8.         $paschalFullMoon = fmod(3 - (11 * $goldenNumber) - 7, 30);
  9.     }
  10.     else
  11.     {
  12.         // Gregorian calendar
  13.         $dominicalNumber = fmod($someYear + ($someYear / 4) - ($someYear / 100) + ($someYear / 400), 7);
  14.         $solarCorrection = ($someYear - 1600) / 100 - ($someYear - 1600) / 400;
  15.         $lunarCorrection = ((($someYear - 1400) / 100) * 8) / 25;
  16.         $paschalFullMoon = fmod(3 - 11 * $goldenNumber + $solarCorrection - $lunarCorrection, 30);
  17.     }
  18.     while ($dominicalNumber < 0)
  19.     {
  20.         $dominicalNumber += 7;
  21.     }
  22.     while ($paschalFullMoon < 0)
  23.     {
  24.         $paschalFullMoon += 30;
  25.     }
  26.     if ($paschalFullMoon == 29 || ($paschalFullMoon == 28 && $goldenNumber > 11))
  27.     {
  28.         $paschalFullMoon--;
  29.     }
  30.     $difference = fmod(4 - $paschalFullMoon - $dominicalNumber, 7);
  31.     if ($difference < 0)
  32.     {
  33.         $difference += 7;
  34.     }
  35.     $dayEaster = $paschalFullMoon + $difference + 1;
  36.     if ($dayEaster < 11)
  37.     {
  38.         // Easter occurs in March.
  39.         $dateEaster = mktime(0, 0, 0, 3, $dayEaster + 21, $someYear);
  40.     }
  41.     else
  42.     {
  43.         // Easter occurs in April.
  44.         $dateEaster = mktime(0, 0, 0, 4, $dayEaster - 10, $someYear);
  45.     }
  46.     return $dateEaster;
  47. }

We can calculate the other ecclesiastical holidays by offsetting the date of Easter with the number of days between Easter and the holiday we're looking for.


ASP

  1. function dateGoodFriday(someYear)
  2.     dateGoodFriday = DateAdd("d", -2, dateEaster(someYear))
  3. end function
  4. function datePalmSunday(someYear)
  5.     datePalmSunday = DateAdd("d", -7, dateEaster(someYear))
  6. end function
  7. function dateAshWednesday(someYear)
  8.     dateAshWednesday = DateAdd("d", -46, dateEaster(someYear))
  9. end function
  10. function dateAscensionDay(someYear)
  11.     dateAscensionDay = DateAdd("d", 39, dateEaster(someYear))
  12. end function
  13. function datePentecost(someYear)
  14.     datePentecost = DateAdd("d", 49, dateEaster(someYear))
  15. end function

PHP

  1. function dateGoodFriday($someYear)
  2. {
  3.     $easter = getDate(dateEaster($someYear));
  4.     return mktime(0, 0, 0, $easter[mon], $easter[mday] - 2, $easter[year]);
  5. }
  6. function datePalmSunday($someYear)
  7. {
  8.     $easter = getDate(dateEaster($someYear));
  9.     return mktime(0, 0, 0, $easter[mon], $easter[mday] - 7, $easter[year]);
  10. }
  11. function dateAshWednesday($someYear)
  12. {
  13.     $easter = getDate(dateEaster($someYear));
  14.     return mktime(0, 0, 0, $easter[mon], $easter[mday] - 46, $easter[year]);
  15. }
  16. function dateAscensionDay($someYear)
  17. {
  18.     $easter = getDate(dateEaster($someYear));
  19.     return mktime(0, 0, 0, $easter[mon], $easter[mday] + 39, $easter[year]);
  20. }
  21. function datePentecost($someYear)
  22. {
  23.     $easter = getDate(dateEaster($someYear));
  24.     return mktime(0, 0, 0, $easter[mon], $easter[mday] + 49, $easter[year]);
  25. }

No comments: