create procedure lib_date_easter_of_year ( ofyear smallint, method smallint) returns ( easter_date date) as declare variable easter_day smallint; declare variable easter_month smallint; declare variable yd smallint; declare variable ym smallint; declare variable a smallint; declare variable b smallint; declare variable c smallint; declare variable d smallint; declare variable e smallint; declare variable t smallint; begin /* Date Calculation of Easter Sunday Algorithm by Ron Mallen - http://www.assa.org.au/edm.html Method: 1 Original (calculation based on the Julian calendar, valid for years 326 ff.) 2 Orthodox ([1] converted to the equivalent Gregorian date, valid for years 1583 ... 4099) 3 Western (revised calculation based on [2], valid for years 1583 ... 4099) */ easter_date = null; if ( ( (method = 1) and (326 <= ofyear)) or ( (method between 2 and 3) and (ofyear between 1583 and 4099))) then begin yd = ofyear / 100; execute procedure lib_math_mod :ofyear, 19 returning_values :ym; if (method between 1 and 2) then begin execute procedure lib_math_mod 225 - (11 * :ym), 30 returning_values :a; a = a + 21; execute procedure lib_math_mod :a - 19, 7 returning_values :b; execute procedure lib_math_mod 40 - :yd, 7 returning_values :c; execute procedure lib_math_mod :ofyear, 100 returning_values :t; execute procedure lib_math_mod (:t / 4) + :t, 7 returning_values :d; execute procedure lib_math_mod 20 - :b - :c - :d, 7 returning_values :e; e = e + 1; easter_day = a + e; if (method = 2) then begin t = 10; if (1600 < ofyear) then t = t + yd - 16 - ((yd - 16) / 4); easter_day = easter_day + t; end end if (method = 3) then begin t = ((yd - 15 ) / 2) + 202 - (11 * ym); if (yd in (21, 24, 25, 27, 28, 29, 30, 31, 32, 34, 35, 38)) then t = t - 1; if (yd in (33, 36, 37, 39, 40)) then t = t - 2; execute procedure lib_math_mod :t, 30 returning_values :t; a = t + 21; if (t = 29) then a = a - 1; if ( (t = 28) and (10 < ym)) then a = a - 1; execute procedure lib_math_mod :a - 19, 7 returning_values :b; execute procedure lib_math_mod 40 - :yd, 4 returning_values :c; if (c = 3) then c = c + 1; if (1 < c) then c = c + 1; execute procedure lib_math_mod :ofyear, 100 returning_values :t; execute procedure lib_math_mod (:t / 4) + :t, 7 returning_values :d; execute procedure lib_math_mod 20 - :b - :c - :d, 7 returning_values :e; e = e + 1; easter_day = a + e; end if (61 < easter_day) then begin easter_day = easter_day - 61; easter_month = 5; end else if (31 < easter_day) then begin easter_day = easter_day - 31; easter_month = 4; end else easter_month = 3; easter_date = cast( ofyear || '-' || easter_month || '-' || easter_day as date); end suspend; end