Код:
(* http://www.tondering.dk/claus/cal/julperiod.php *)
PROCEDURE DateJulToJDN (IN d: Dates.Date): INTEGER;
VAR a, y, m: INTEGER;
BEGIN
a := (14 - d.month) DIV 12;
y := d.year + 4800 - a;
m := d.month + 12 * a - 3;
RETURN d.day + (153 * m + 2) DIV 5 + 365 * y + y DIV 4 - 32083
END DateJulToJDN;
(* http://www.tondering.dk/claus/cal/julperiod.php *)
PROCEDURE DateGregToJDN (IN d: Dates.Date): INTEGER;
VAR a, y, m: INTEGER;
BEGIN
a := (14 - d.month) DIV 12;
y := d.year + 4800 - a;
m := d.month + 12 * a - 3;
RETURN d.day + (153 * m + 2) DIV 5 + 365 * y + y DIV 4 - y DIV 100 + y DIV 400 - 32045
END DateGregToJDN;
(* http://www.tondering.dk/claus/cal/julperiod.php *)
PROCEDURE BCToDateJulGreg (b, c: INTEGER; OUT date: Dates.Date);
VAR d, e, m: INTEGER;
BEGIN
d := (4 * c + 3) DIV 1461;
e := c - (1461 * d) DIV 4;
m := (5 * e + 2) DIV 153;
date.day := e - (153 * m + 2) DIV 5 + 1;
date.month := m + 3 - 12 * (m DIV 10);
date.year := 100 * b + d - 4800 + m DIV 10
END BCToDateJulGreg;
(* http://www.tondering.dk/claus/cal/julperiod.php *)
PROCEDURE JDNToDateJul (jdn: INTEGER; OUT d: Dates.Date);
BEGIN
ASSERT(jdn >= 0, 20);
ASSERT(jdn <= 536838829, 21); (* 1465072.8.11 *)
BCToDateJulGreg(0, jdn + 32082, d)
END JDNToDateJul;
(* http://www.tondering.dk/claus/cal/julperiod.php *)
PROCEDURE JDNToDateGreg (jdn: INTEGER; OUT d: Dates.Date);
VAR a, b, c: INTEGER;
BEGIN
ASSERT(jdn >= 0, 20);
ASSERT(jdn <= 536838867, 21); (* 1465102.10.18 *)
a := jdn + 32044;
b := (4 * a + 3) DIV 146097;
c := a - (146097 * b) DIV 4;
BCToDateJulGreg(b, c, d)
END JDNToDateGreg;
(* Gauss *)
PROCEDURE AlexandrianEasterJul (year: INTEGER; OUT d: Dates.Date);
VAR a, b: INTEGER;
BEGIN
a := (19 * (year MOD 19) + 15) MOD 30;
b := (2 * (year MOD 4) + 4 * (year MOD 7) + 6 * a + 6) MOD 7;
IF a + b > 9 THEN
d.month := 4;
d.day := a + b - 9
ELSE
d.month := 3;
d.day := 22 + a + b
END;
d.year := year
END AlexandrianEasterJul;
(* year, d: Gregorian *)
PROCEDURE GetAlexandrianEasterDate* (year: INTEGER; OUT d: Dates.Date);
BEGIN
ASSERT(year >= 326);
ASSERT(year <= 10900);
(*
d.year := year; d.month := 3; d.day := 21;
JDNToDateJul(DateGregToJDN(d), d);
ASSERT(d.year = year, 100);
*)
AlexandrianEasterJul(year, d);
JDNToDateGreg(DateJulToJDN(d), d);
ASSERT(d.year = year, 101)
END GetAlexandrianEasterDate;