Holidays related to Easter: Difference between revisions
(→[[Holidays_related_to_Easter#ALGOL 68]]: Apologies for the stray ">" characters in GeSHi highlighed text. Algol68.php bug has been fixed and is awaiting installation.) |
(→[[Holidays_related_to_Easter#ALGOL 68]]: repackaged routines and constants so that can more easily be cut paste/reused as helper/utility functions) |
||
Line 17: | Line 17: | ||
Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. |
Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. |
||
--> |
--> |
||
<lang algol68> |
<lang algol68>MODE YEAR = INT, MONTH = INT, WEEK = INT, DAY = INT; |
||
MODE DATE = STRUCT(YEAR year, DAY year day, MONTH month, DAY month day, WEEK week, DAY week day); |
|||
FOR year FROM 2010 TO 2020 |
|||
DO |
|||
FORMAT mon fmt = $ c("Jan", "Feb", "Mar", "Apr", "May", "Jun", |
|||
printf (($l4d" "$, year)); |
|||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec")$, |
|||
INT month, day; |
|||
INT year months = 12; |
|||
PROC year days = (YEAR year)DAY: # Ignore 1752 for the moment # |
|||
IF month days(year, 2) = 28 THEN 365 ELSE 366 FI; |
|||
PROC month days = (YEAR year, MONTH month) INT: |
|||
(month | 31, |
|||
28 + (year %* 4 = 0 AND year %* 400 /= 0 | 1 | 0), |
|||
31, 30, 31, 30, 31, 31, 30, 31, 30, 31); |
|||
INT week days = 7; # France 1793 to 1805 had 10 day weeks! # |
|||
OP + = (DATE in date, DAY in days)DATE: |
|||
BEGIN |
|||
DAY days := in days; |
|||
DATE date := in date; |
|||
month day OF date +:= days; |
|||
WHILE days < 0 DO |
|||
year OF date -:= 1; |
|||
days +:= year days(year OF date) |
|||
OD; |
|||
WHILE month day OF date > month days(year OF date, month OF date) DO |
|||
month day OF date -:= month days(year OF date, month OF date); |
|||
month OF date +:= 1; |
|||
IF month OF date > year months THEN |
|||
month OF date -:= year months; |
|||
year OF date +:= 1 |
|||
FI |
|||
OD; |
|||
week day OF date := week day(date); |
|||
date |
|||
END; |
|||
OP +:= = (REF DATE date, DAY in days)DATE: |
|||
date := date + in days; |
|||
PROC easter = (YEAR year)DATE: |
|||
BEGIN |
BEGIN |
||
COMMENT |
COMMENT |
||
Easter date algorithm from J.M. Oudin (1940), reprinted in: |
Easter date algorithm from J.M. Oudin (1940), reprinted in: |
||
P.K. Seidelmann ed., "Explanatory Supplement to the Astronomical |
P.K. Seidelmann ed., "Explanatory Supplement to the Astronomical |
||
Almanac" [1992] (Chapter 12, "Calendars", by L.E. Doggett) |
Almanac" [1992] (Chapter 12, "Calendars", by L.E. Doggett) |
||
COMMENT |
COMMENT |
||
DATE date; year OF date := year; |
|||
INT c = year % 100, n = year %* 19; |
INT c = year % 100, n = year %* 19; |
||
INT i := (c - c % 4 - (c - (c - 17) % 25) % 3 + 19 * n + 15) %* 30; |
INT i := (c - c % 4 - (c - (c - 17) % 25) % 3 + 19 * n + 15) %* 30; |
||
i -:= (i % 28) * (1 - (i % 28) * (29 % (i + 1)) * ((21 - n) % 11)); |
i -:= (i % 28) * (1 - (i % 28) * (29 % (i + 1)) * ((21 - n) % 11)); |
||
INT l = i - (year + year % 4 + i + 2 - c + c % 4) %* 7; |
INT l = i - (year + year % 4 + i + 2 - c + c % 4) %* 7; |
||
month := 3 + (l + 40) % 44; |
month OF date := 3 + (l + 40) % 44; |
||
day := l + 28 - 31 * (month % 4) |
month day OF date := l + 28 - 31 * (month OF date % 4); |
||
week day OF date := week day(date); |
|||
date |
|||
END; |
END; |
||
PROC print date = (STRING holiday, INT year, month, day) VOID: |
|||
BEGIN |
|||
PROC weekday = (INT year0, month0, day0) INT: |
|||
# Zeller’s Congruence algorithm from 1887. # |
|||
BEGIN INT year := year0, month := month0, day := day0, c; |
|||
(month <= 2 | (month +:= 12, year -:= 1)); |
|||
c := year OVER 100; |
|||
year %*:= 100; |
|||
1 + (day + ((month + 1) * 26) OVER 10 |
|||
+ year + year OVER 4 + c OVER 4 - 2 * c) %* 7 |
|||
END; |
|||
print f (($g": " |
|||
c("Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri")z-dx |
|||
c("Jan", "Feb", "Mar", "Apr", "May", "Jun", |
|||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec")$, |
|||
holiday, weekday(year, month, day), day, month)) |
|||
END; |
|||
FORMAT week day fmt = $c("Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri")$; |
|||
# Print Easter date, always a Sunday. # |
|||
PROC week day = (DATE date)DAY: |
|||
print date ("Easter", year, month, day); print(", "); |
|||
# Zeller’s Congruence algorithm from 1887. # |
|||
PROC advance = (INT number) VOID: |
|||
BEGIN |
|||
INT year := year OF date, month := month OF date, month day := month day OF date, c; |
|||
(month | 31, |
|||
(month <= 2 | (month +:= 12, year -:= 1)); |
|||
c := year OVER 100; |
|||
31, 30, 31, 30, 31, 31, 30, 31, 30, 31); |
|||
year %*:= 100; |
|||
1 + (month day + ((month + 1) * 26) OVER 10 |
|||
+ year + year OVER 4 + c OVER 4 - 2 * c) %* 7 |
|||
END; |
|||
END; |
|||
FORMAT wdmdm fmt = $f(week day fmt)z-dxf(mon fmt)$, |
|||
MODE EASTERRELATED = STRUCT(DATE easter, ascension, pentecost, trinity, corpus christi); |
|||
PROC easter related init = (YEAR year)EASTERRELATED: |
|||
BEGIN |
|||
DATE date; |
|||
EASTERRELATED holidays; |
|||
# Easter date, always a Sunday. # |
|||
easter OF holidays := date := easter(year); |
|||
# Ascension day is 39 days after Easter.# |
# Ascension day is 39 days after Easter.# |
||
ascension OF holidays := ( date +:= 39); |
|||
advance (39); |
|||
print date ("Ascension", year, month, day); print(", "); |
|||
# Pentecost is 10 days after Ascension day.# |
# Pentecost is 10 days after Ascension day.# |
||
pentecost OF holidays := date +:= 10; |
|||
advance (10); |
|||
print date ("Pentecost", year, month, day); print(", "); |
|||
# Trinity is 7 days after Pentecost.# |
# Trinity is 7 days after Pentecost.# |
||
trinity OF holidays := date +:= 7; |
|||
advance (7); |
|||
print date ("Trinity", year, month, day); print(", "); |
|||
# Corpus Christi is 4 days after Trinity.# |
# Corpus Christi is 4 days after Trinity.# |
||
corpus christi OF holidays := date +:= 4; |
|||
advance (4); |
|||
holidays |
|||
print date ("Corpus", year, month, day) |
|||
END; |
|||
OD</lang> |
|||
FORMAT easter related fmt = $zzzd" Easter: "f(wdmdm fmt) ", Ascension: "f(wdmdm fmt) |
|||
", Pentecost: "f(wdmdm fmt) ", Trinity: "f(wdmdm fmt)", Corpus: "f(wdmdm fmt)$; |
|||
PROC easter related print = (YEAR year)VOID: |
|||
BEGIN |
|||
EASTERRELATED holidays = easter related init(year); |
|||
PROC wdmdm = (DATE date)STRUCT(DAY week day, DAY month day, MONTH month): |
|||
(week day OF date, month day OF date, month OF date); |
|||
printf((easter related fmt, |
|||
year, |
|||
wdmdm(easter OF holidays), |
|||
wdmdm(ascension OF holidays), |
|||
wdmdm(pentecost OF holidays), |
|||
wdmdm(trinity OF holidays), |
|||
wdmdm(corpus christi OF holidays), |
|||
$l$)) |
|||
END; |
|||
printf (($"Christian holidays, related to Easter, for each centuary start from 400 to 2100:"l$)); |
|||
FOR year FROM 400 BY 100 TO 2100 DO easter related print(year) OD; |
|||
printf (($l"Christian holidays, related to Easter, for years from 2010 to 2020:"l$)); |
|||
FOR year FROM 2010 TO 2020 DO easter related print(year) OD</lang> |
|||
Output: |
Output: |
||
<pre> |
<pre> |
||
Christian holidays, related to Easter, 2010 to 2020: |
|||
Christian holidays, related to Easter, for each centuary start from 400 to 2100: |
|||
0400 Easter: Sun 2 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 Jun |
|||
0500 Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun |
|||
0600 Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 1 Jun, Trinity: Sun 8 Jun, Corpus: Thu 12 Jun |
|||
0700 Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 3 Jun, Trinity: Sun 10 Jun, Corpus: Thu 14 Jun |
|||
0800 Easter: Sun 23 Apr, Ascension: Thu 1 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus: Thu 22 Jun |
|||
0900 Easter: Sun 28 Mar, Ascension: Thu 6 May, Pentecost: Sun 16 May, Trinity: Sun 23 May, Corpus: Thu 27 May |
|||
1000 Easter: Sun 30 Mar, Ascension: Thu 8 May, Pentecost: Sun 18 May, Trinity: Sun 25 May, Corpus: Thu 29 May |
|||
1100 Easter: Sun 8 Apr, Ascension: Thu 17 May, Pentecost: Sun 27 May, Trinity: Sun 3 Jun, Corpus: Thu 7 Jun |
|||
1200 Easter: Sun 9 Apr, Ascension: Thu 18 May, Pentecost: Sun 28 May, Trinity: Sun 4 Jun, Corpus: Thu 8 Jun |
|||
1300 Easter: Sun 18 Apr, Ascension: Thu 27 May, Pentecost: Sun 6 Jun, Trinity: Sun 13 Jun, Corpus: Thu 17 Jun |
|||
1400 Easter: Sun 20 Apr, Ascension: Thu 29 May, Pentecost: Sun 8 Jun, Trinity: Sun 15 Jun, Corpus: Thu 19 Jun |
|||
1500 Easter: Sun 1 Apr, Ascension: Thu 10 May, Pentecost: Sun 20 May, Trinity: Sun 27 May, Corpus: Thu 31 May |
|||
1600 Easter: Sun 2 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 Jun |
|||
1700 Easter: Sun 11 Apr, Ascension: Thu 20 May, Pentecost: Sun 30 May, Trinity: Sun 6 Jun, Corpus: Thu 10 Jun |
|||
1800 Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 1 Jun, Trinity: Sun 8 Jun, Corpus: Thu 12 Jun |
|||
1900 Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 3 Jun, Trinity: Sun 10 Jun, Corpus: Thu 14 Jun |
|||
2000 Easter: Sun 23 Apr, Ascension: Thu 1 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus: Thu 22 Jun |
|||
2100 Easter: Sun 28 Mar, Ascension: Thu 6 May, Pentecost: Sun 16 May, Trinity: Sun 23 May, Corpus: Thu 27 May |
|||
Christian holidays, related to Easter, for years from 2010 to 2020: |
|||
2010 Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun |
2010 Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun |
||
2011 Easter: Sun 24 Apr, Ascension: Thu 2 Jun, Pentecost: Sun 12 Jun, Trinity: Sun 19 Jun, Corpus: Thu 23 Jun |
2011 Easter: Sun 24 Apr, Ascension: Thu 2 Jun, Pentecost: Sun 12 Jun, Trinity: Sun 19 Jun, Corpus: Thu 23 Jun |
Revision as of 03:23, 29 June 2010
You are encouraged to solve this task according to the task description, using any language you may know.
Calculate the date of Easter, Ascension Thursday, Pentecost, Trinity Sunday & Corpus Christi feast.
As the example calculate for the first year of each century from 400 to 2100 CE and also for years 2010 to 2020 CE.
Note: From year 325 CE on, Easter Sunday is the Sunday following the first Ecclesiastical full moon not earlier than the equinox date in 325 — 21 March. The Ecclesiastical full moon does not always correspond to the astronomical full moon since in 325 fine details of Lunar dynamics were not yet fully understood.
ALGOL 68
Note: Code specimen extracted from Algol 68 Genie Documentation Part III - Example a68g programs. <lang algol68>MODE YEAR = INT, MONTH = INT, WEEK = INT, DAY = INT; MODE DATE = STRUCT(YEAR year, DAY year day, MONTH month, DAY month day, WEEK week, DAY week day);
FORMAT mon fmt = $ c("Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec")$,
INT year months = 12;
PROC year days = (YEAR year)DAY: # Ignore 1752 for the moment #
IF month days(year, 2) = 28 THEN 365 ELSE 366 FI;
PROC month days = (YEAR year, MONTH month) INT:
(month | 31, 28 + (year %* 4 = 0 AND year %* 400 /= 0 | 1 | 0), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
INT week days = 7; # France 1793 to 1805 had 10 day weeks! #
OP + = (DATE in date, DAY in days)DATE:
BEGIN DAY days := in days; DATE date := in date; month day OF date +:= days; WHILE days < 0 DO year OF date -:= 1; days +:= year days(year OF date) OD; WHILE month day OF date > month days(year OF date, month OF date) DO month day OF date -:= month days(year OF date, month OF date); month OF date +:= 1; IF month OF date > year months THEN month OF date -:= year months; year OF date +:= 1 FI OD; week day OF date := week day(date); date END;
OP +:= = (REF DATE date, DAY in days)DATE:
date := date + in days;
PROC easter = (YEAR year)DATE:
BEGIN COMMENT Easter date algorithm from J.M. Oudin (1940), reprinted in: P.K. Seidelmann ed., "Explanatory Supplement to the Astronomical Almanac" [1992] (Chapter 12, "Calendars", by L.E. Doggett) COMMENT DATE date; year OF date := year; INT c = year % 100, n = year %* 19; INT i := (c - c % 4 - (c - (c - 17) % 25) % 3 + 19 * n + 15) %* 30; i -:= (i % 28) * (1 - (i % 28) * (29 % (i + 1)) * ((21 - n) % 11)); INT l = i - (year + year % 4 + i + 2 - c + c % 4) %* 7; month OF date := 3 + (l + 40) % 44; month day OF date := l + 28 - 31 * (month OF date % 4); week day OF date := week day(date); date END;
FORMAT week day fmt = $c("Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri")$; PROC week day = (DATE date)DAY:
# Zeller’s Congruence algorithm from 1887. # BEGIN INT year := year OF date, month := month OF date, month day := month day OF date, c; (month <= 2 | (month +:= 12, year -:= 1)); c := year OVER 100; year %*:= 100; 1 + (month day + ((month + 1) * 26) OVER 10 + year + year OVER 4 + c OVER 4 - 2 * c) %* 7 END;
FORMAT wdmdm fmt = $f(week day fmt)z-dxf(mon fmt)$,
MODE EASTERRELATED = STRUCT(DATE easter, ascension, pentecost, trinity, corpus christi);
PROC easter related init = (YEAR year)EASTERRELATED: BEGIN
DATE date; EASTERRELATED holidays;
- Easter date, always a Sunday. #
easter OF holidays := date := easter(year);
- Ascension day is 39 days after Easter.#
ascension OF holidays := ( date +:= 39);
- Pentecost is 10 days after Ascension day.#
pentecost OF holidays := date +:= 10;
- Trinity is 7 days after Pentecost.#
trinity OF holidays := date +:= 7;
- Corpus Christi is 4 days after Trinity.#
corpus christi OF holidays := date +:= 4; holidays
END;
FORMAT easter related fmt = $zzzd" Easter: "f(wdmdm fmt) ", Ascension: "f(wdmdm fmt)
", Pentecost: "f(wdmdm fmt) ", Trinity: "f(wdmdm fmt)", Corpus: "f(wdmdm fmt)$;
PROC easter related print = (YEAR year)VOID: BEGIN
EASTERRELATED holidays = easter related init(year); PROC wdmdm = (DATE date)STRUCT(DAY week day, DAY month day, MONTH month): (week day OF date, month day OF date, month OF date); printf((easter related fmt, year, wdmdm(easter OF holidays), wdmdm(ascension OF holidays), wdmdm(pentecost OF holidays), wdmdm(trinity OF holidays), wdmdm(corpus christi OF holidays), $l$))
END;
printf (($"Christian holidays, related to Easter, for each centuary start from 400 to 2100:"l$)); FOR year FROM 400 BY 100 TO 2100 DO easter related print(year) OD;
printf (($l"Christian holidays, related to Easter, for years from 2010 to 2020:"l$)); FOR year FROM 2010 TO 2020 DO easter related print(year) OD</lang> Output:
Christian holidays, related to Easter, for each centuary start from 400 to 2100: 0400 Easter: Sun 2 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 Jun 0500 Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun 0600 Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 1 Jun, Trinity: Sun 8 Jun, Corpus: Thu 12 Jun 0700 Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 3 Jun, Trinity: Sun 10 Jun, Corpus: Thu 14 Jun 0800 Easter: Sun 23 Apr, Ascension: Thu 1 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus: Thu 22 Jun 0900 Easter: Sun 28 Mar, Ascension: Thu 6 May, Pentecost: Sun 16 May, Trinity: Sun 23 May, Corpus: Thu 27 May 1000 Easter: Sun 30 Mar, Ascension: Thu 8 May, Pentecost: Sun 18 May, Trinity: Sun 25 May, Corpus: Thu 29 May 1100 Easter: Sun 8 Apr, Ascension: Thu 17 May, Pentecost: Sun 27 May, Trinity: Sun 3 Jun, Corpus: Thu 7 Jun 1200 Easter: Sun 9 Apr, Ascension: Thu 18 May, Pentecost: Sun 28 May, Trinity: Sun 4 Jun, Corpus: Thu 8 Jun 1300 Easter: Sun 18 Apr, Ascension: Thu 27 May, Pentecost: Sun 6 Jun, Trinity: Sun 13 Jun, Corpus: Thu 17 Jun 1400 Easter: Sun 20 Apr, Ascension: Thu 29 May, Pentecost: Sun 8 Jun, Trinity: Sun 15 Jun, Corpus: Thu 19 Jun 1500 Easter: Sun 1 Apr, Ascension: Thu 10 May, Pentecost: Sun 20 May, Trinity: Sun 27 May, Corpus: Thu 31 May 1600 Easter: Sun 2 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 Jun 1700 Easter: Sun 11 Apr, Ascension: Thu 20 May, Pentecost: Sun 30 May, Trinity: Sun 6 Jun, Corpus: Thu 10 Jun 1800 Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 1 Jun, Trinity: Sun 8 Jun, Corpus: Thu 12 Jun 1900 Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 3 Jun, Trinity: Sun 10 Jun, Corpus: Thu 14 Jun 2000 Easter: Sun 23 Apr, Ascension: Thu 1 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus: Thu 22 Jun 2100 Easter: Sun 28 Mar, Ascension: Thu 6 May, Pentecost: Sun 16 May, Trinity: Sun 23 May, Corpus: Thu 27 May Christian holidays, related to Easter, for years from 2010 to 2020: 2010 Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun 2011 Easter: Sun 24 Apr, Ascension: Thu 2 Jun, Pentecost: Sun 12 Jun, Trinity: Sun 19 Jun, Corpus: Thu 23 Jun 2012 Easter: Sun 8 Apr, Ascension: Thu 17 May, Pentecost: Sun 27 May, Trinity: Sun 3 Jun, Corpus: Thu 7 Jun 2013 Easter: Sun 31 Mar, Ascension: Thu 9 May, Pentecost: Sun 19 May, Trinity: Sun 26 May, Corpus: Thu 30 May 2014 Easter: Sun 20 Apr, Ascension: Thu 29 May, Pentecost: Sun 8 Jun, Trinity: Sun 15 Jun, Corpus: Thu 19 Jun 2015 Easter: Sun 5 Apr, Ascension: Thu 14 May, Pentecost: Sun 24 May, Trinity: Sun 31 May, Corpus: Thu 4 Jun 2016 Easter: Sun 27 Mar, Ascension: Thu 5 May, Pentecost: Sun 15 May, Trinity: Sun 22 May, Corpus: Thu 26 May 2017 Easter: Sun 16 Apr, Ascension: Thu 25 May, Pentecost: Sun 4 Jun, Trinity: Sun 11 Jun, Corpus: Thu 15 Jun 2018 Easter: Sun 1 Apr, Ascension: Thu 10 May, Pentecost: Sun 20 May, Trinity: Sun 27 May, Corpus: Thu 31 May 2019 Easter: Sun 21 Apr, Ascension: Thu 30 May, Pentecost: Sun 9 Jun, Trinity: Sun 16 Jun, Corpus: Thu 20 Jun 2020 Easter: Sun 12 Apr, Ascension: Thu 21 May, Pentecost: Sun 31 May, Trinity: Sun 7 Jun, Corpus: Thu 11 Jun