Holidays related to Easter
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Calculate the dates of:
- Easter
- Ascension Thursday
- Pentecost
- Trinity Sunday
- Corpus Christi feast (for Catholic)
- All Saints' Sunday (for Orthodox)
As an example, calculate for the first year of each century from;
- years 400 to 2100 CE and for
- years 2010 to 2020 CE.
- Note
From the year 325 CE on, Easter Sunday has been defined as the first Sunday after the first full moon on or after the day of the March equinox. However, the actual astronomical values for the moments of the full moon and equinox are not used. Instead, approximations are used, the first one being that the equinox is assumed to fall on March 21st every year. The tracking of the moon phases is similarly done with relatively straightforward arithmetic (compared to the sort required for astronomical accuracy) which amounts to maintaining a lunisolar calendar in parallel to our standard purely-solar one.
When Pope Gregory reformed the Catholic calendar in 1582 CE, the drifting of Easter with respect to the seasons was the driving motivation, and the rules for determining it (called the computus) were altered to correct that drift. Catholic nations adopted both the new calendar and the new computus right away, while Western Protestant nations adopted them more gradually over the next 350 years or so. Eventually, even nations dominated by the Eastern Orthodox church adopted a similar calendar reform (the Revised Julian calendar), so pretty much the whole world agrees on what day it is for civil purposes. But the Eastern churches never adopted the corresponding Easter rule changes; they still use the original Julian calendar and computus to determine the date of what is known in the West as "Orthodox Easter". Therefore, your output should indicate which computus was used to calculate the dates and, at least for historical dates where the calendar can't be assumed or is location-dependent, which calendar those dates are given in.
You may find algorithms on the Computus Wikipedia page. Some of the results:
In the year 400 CE, Easter Sunday was April 1st (in the contemporary Julian calendar), making Ascension Thursday May 10th and Pentecost May 20th. It is ahistorical to give a date so far back for either Trinity Sunday or Corpus Christi, neither of which were observed until centuries later, but they would have been May 27th and 31st. If you extend the modern civil calendar back that far, those days are instead assigned the subsequent dates: Easter on April 2nd, Ascension on May 11th, Pentecost on May 21st.
Skipping forward to the year 2100 CE, assuming the rules don't change between now and then, the Western churches will observe Easter on March 28, Ascension Thursday May 6th, Pentecost May 16th, Trinity Sunday May 23rd and Corpus Christi May 27th. Heading East, the Orthodox rules place Easter on April 18 in the original Julian calendar; the corresponding civil date is May 2nd. That puts the Ascension on June 10th and Pentecost June 20th. Orthodox Trinity Sunday is the same day as Pentecost, but they observe All Saints' Sunday the following week, June 27th. Corpus Christi is a purely Catholic date that has no Orthodox version.
- Test values of Easter dates
Year | Orthodox | Catholic | Calendar |
---|---|---|---|
400 | 01 Apr | — | Jul. |
800 | 19 Apr | — | Jul. |
1200 | 09 Apr | — | Jul. |
2000 | 30 Apr | 23 Apr | Gr. |
2020 | 19 Apr | 12 Apr | Gr. |
360 Assembly
For maximum compatibility, this program uses only the basic instruction set (S/360) and two ASSIST macros (XDECO, XPRNT) to keep the code as short as possible.
* Holidays related to Easter 29/05/2016
HOLIDAYS CSECT
USING HOLIDAYS,R13 base register
B 72(R15) skip savearea
DC 17F'0' savearea
STM R14,R12,12(R13) prolog
ST R13,4(R15) "
ST R15,8(R13) "
LR R13,R15 "
LA R9,2 nn=2
LOOPNN C R9,=F'2' if nn=2
BNE NN2
NN1 MVC I1,=F'400' i1=400
MVC I2,=F'2100' i2=2100
MVC I3,=F'100' i3=100
B NN3
NN2 MVC I1,=F'2010' i1=2010
MVC I2,=F'2020' i2=2020
MVC I3,=F'1' i3=1
NN3 MVC PG(L'PGT),PGT pg=pgt
L R1,I1 i1
XDECO R1,XDEC edit i1
MVC PG+24(4),XDEC+8 output i1
L R1,I2 i2
XDECO R1,XDEC edit i2
MVC PG+32(4),XDEC+8 output i2
L R1,I3 i3
XDECO R1,XDEC edit i3
MVC PG+42(3),XDEC+9 output i3
XPRNT PG,L'PGT print buffer
L R6,I1 y=i1
LOOPY C R6,I2 do y=i1 to i2 by i3
BH ELOOPY leave y
LR R4,R6 y
SRDA R4,32 ~
D R4,=F'19' /19
ST R4,A a=y//19
LR R4,R6 y
SRDA R4,32 ~
D R4,=F'100' /100
ST R5,B b=y/100
ST R4,C c=y//100
L R4,B b
SRDA R4,32 ~
D R4,=F'4' /4
ST R5,D d=b/4
ST R4,E e=b//4
L R4,B b
LA R4,8(R4) +8
SRDA R4,32 ~
D R4,=F'25' /25
ST R5,F f=(b+8)/25
L R4,B b
S R4,F -f
LA R4,1(R4) +1
SRDA R4,32 ~
D R4,=F'3' /3
ST R5,G g=(b-f+1)/3
L R5,A a
M R4,=F'19' *19
LR R4,R5 .
A R4,B +b
S R4,D -d
S R4,G -g
LA R4,15(R4) +15
SRDA R4,32 ~
D R4,=F'30' /30
ST R4,H h=(19*a+b-d-g+15)//30
L R4,C c
SRDA R4,32 ~
D R4,=F'4' /4
ST R5,I i=c/4
ST R4,K k=c//4
L R4,E e
SLA R4,1 <<1 <=> *2
LA R4,32(R4) +32
L R2,I i
SLA R2,1 <<1 <=> *2
AR R2,R4 32+2*e+2*i
S R2,H -h
S R2,K -k
SRDA R2,32 ~
D R2,=F'7' /7
ST R2,L l=(32+2*e+2*i-h-k)//7
L R5,H h
M R4,=F'11' *11
A R5,A +a
L R3,L l
M R2,=F'22' *22
AR R3,R5 a+11*h+22*l
LR R4,R3 .
SRDA R4,32 ~
D R4,=F'451' /451
ST R5,M m=(a+11*h+22*l)/451
L R2,H h
A R2,L +l
L R5,M m
M R4,=F'7' *7
SR R2,R5 (h+l)-(7*m)
LA R2,114(R2) +114
ST R2,N n=h+l-7*m+114
L R4,N n
SRDA R4,32 ~
D R4,=F'31' /31
ST R5,XM xm=n/31
LA R4,1(R4) +1
ST R4,XD xd=n//31+1
LA R10,PG pgi=0
MVC PG,=CL84' ' pg=' '
XDECO R6,XDEC edit y
MVC 0(4,R10),XDEC+8 output y
LA R10,4(R10) pgi=pgi+3
LA R8,5 loop counter for loopi
LA R7,1 i=1
LOOPI LR R1,R7 do i=1 to 5; r1=i
SLA R1,1 *2
LH R2,OFFSET-2(R1) offset(i)
L R4,XD xd
AR R4,R2 wd=xd+offset(i)
WHILE L R1,XM xm
SLA R1,1 *2
LH R2,DAYS-2(R1) days(xm)
CR R4,R2 while wd>days(xm)
BNH WEND leave while
SR R4,R2 wd=wd-days(xm)
L R2,XM xm
LA R2,1(R2) xm+1
ST R2,XM xm=xm+1
B WHILE loop while
WEND ST R4,XD xd=wd
LA R10,1(R10) pgi=pgi+1
LR R1,R7 i
MH R1,=AL2(L'HOLIDAY) *9
LA R14,HOLIDAY-9(R1) @holiday(i)
MVC 0(L'HOLIDAY,R10),0(R14) output holiday(i)
LA R10,9(R10) pgi=pgi+9
L R1,XD xd
XDECO R1,XDEC edit xd
MVC 0(3,R10),XDEC+9 output xd
LA R10,3(R10) pgi=pgi+3
L R1,XM xm
MH R1,=AL2(L'MONTH) *3
LA R14,MONTH-3(R1) @month(xm)
MVC 0(L'MONTH,R10),0(R14) output month(xm)
LA R10,3(R10) pgi=pgi+3
LA R7,1(R7) i+1
BCT R8,LOOPI next i
XPRNT PG,L'PG print buffer
A R6,I3 y=y+i3
B LOOPY next y
ELOOPY BCT R9,LOOPNN next nn
L R13,4(0,R13) epilog
LM R14,R12,12(R13) "
XR R15,R15 "
BR R14 exit
A DS F a=y//19
B DS F b=y/100
C DS F c=y//100
D DS F d=b/4
E DS F e=b//4
F DS F f=(b+8)/25
G DS F g=(b-f+1)/3
H DS F h=(19*a+b-d-g+15)//30
I DS F i=c/4
K DS F k=c//4
L DS F l=(32+2*e+2*i-h-k)//7
M DS F m=(a+11*h+22*l)/451
N DS F n=h+l-7*m+114
XM DS F month
XD DS F day
I1 DS F from year i1
I2 DS F to year i2
I3 DS F step year i3
MONTH DC CL3'jan',CL3'feb',CL3'mar',CL3'apr',CL3'may',CL3'jun'
DAYS DC H'31',H'28',H'31',H'30',H'31',H'30'
HOLIDAY DC CL9'Easter',CL9'Ascension',CL9'Pentecost'
DC CL9'Trinity',CL9'Corpus'
OFFSET DC H'0',H'39',H'10',H'7',H'4'
PGT DC CL45'Christian holidays from .... to .... step ...'
PG DC CL84' ' buffer
XDEC DS CL12 temp for edit
YREGS
END HOLIDAYS
- Output:
Christian holidays from 400 to 2100 step 100 400 Easter 2apr Ascension 11may Pentecost 21may Trinity 28may Corpus 1jun 500 Easter 4apr Ascension 13may Pentecost 23may Trinity 30may Corpus 3jun 600 Easter 13apr Ascension 22may Pentecost 1jun Trinity 8jun Corpus 12jun 700 Easter 15apr Ascension 24may Pentecost 3jun Trinity 10jun Corpus 14jun 800 Easter 23apr Ascension 1jun Pentecost 11jun Trinity 18jun Corpus 22jun 900 Easter 28mar Ascension 6may Pentecost 16may Trinity 23may Corpus 27may 1000 Easter 30mar Ascension 8may Pentecost 18may Trinity 25may Corpus 29may 1100 Easter 8apr Ascension 17may Pentecost 27may Trinity 3jun Corpus 7jun 1200 Easter 9apr Ascension 18may Pentecost 28may Trinity 4jun Corpus 8jun 1300 Easter 18apr Ascension 27may Pentecost 6jun Trinity 13jun Corpus 17jun 1400 Easter 20apr Ascension 29may Pentecost 8jun Trinity 15jun Corpus 19jun 1500 Easter 1apr Ascension 10may Pentecost 20may Trinity 27may Corpus 31may 1600 Easter 2apr Ascension 11may Pentecost 21may Trinity 28may Corpus 1jun 1700 Easter 11apr Ascension 20may Pentecost 30may Trinity 6jun Corpus 10jun 1800 Easter 13apr Ascension 22may Pentecost 1jun Trinity 8jun Corpus 12jun 1900 Easter 15apr Ascension 24may Pentecost 3jun Trinity 10jun Corpus 14jun 2000 Easter 23apr Ascension 1jun Pentecost 11jun Trinity 18jun Corpus 22jun 2100 Easter 28mar Ascension 6may Pentecost 16may Trinity 23may Corpus 27may Christian holidays from 2010 to 2020 step 1 2010 Easter 4apr Ascension 13may Pentecost 23may Trinity 30may Corpus 3jun 2011 Easter 24apr Ascension 2jun Pentecost 12jun Trinity 19jun Corpus 23jun 2012 Easter 8apr Ascension 17may Pentecost 27may Trinity 3jun Corpus 7jun 2013 Easter 31mar Ascension 9may Pentecost 19may Trinity 26may Corpus 30may 2014 Easter 20apr Ascension 29may Pentecost 8jun Trinity 15jun Corpus 19jun 2015 Easter 5apr Ascension 14may Pentecost 24may Trinity 31may Corpus 4jun 2016 Easter 27mar Ascension 5may Pentecost 15may Trinity 22may Corpus 26may 2017 Easter 16apr Ascension 25may Pentecost 4jun Trinity 11jun Corpus 15jun 2018 Easter 1apr Ascension 10may Pentecost 20may Trinity 27may Corpus 31may 2019 Easter 21apr Ascension 30may Pentecost 9jun Trinity 16jun Corpus 20jun 2020 Easter 12apr Ascension 21may Pentecost 31may Trinity 7jun Corpus 11jun
Ada
Ada.Calendar can only handle years in the range 1901 to 2399.
with Ada.Calendar.Arithmetic;
with Ada.Calendar.Formatting;
with Ada.Text_IO;
procedure Main is
use Ada.Calendar;
use Arithmetic;
function Get_Easter (Year : Year_Number) return Time is
A : Integer := Year mod 19;
B : Integer := Year / 100;
C : Integer := Year mod 100;
D : Integer := B / 4;
E : Integer := B mod 4;
F : Integer := (B + 8) / 25;
G : Integer := (B - F + 1) / 3;
H : Integer := (19 * A + B - D - G + 15) mod 30;
I : Integer := C / 4;
K : Integer := C mod 4;
L : Integer := (32 + 2 * E + 2 * I - H - K) mod 7;
M : Integer := (A + 11 * H + 22 * L) / 451;
N : Integer := H + L - 7 * M + 114;
begin
return Time_Of (Year, N / 31, N mod 31 + 1, 43200.0);
end Get_Easter;
procedure Print_Easter (Year : Year_Number) is
Days_To_Ascension : constant Day_Count := 39;
Days_To_Pentecost : constant Day_Count := 49;
Days_To_Trinity : constant Day_Count := 56;
Days_To_Corpus : constant Day_Count := 60;
Easter : Time := Get_Easter (Year);
begin
Ada.Text_IO.Put (Integer'Image (Year));
Ada.Text_IO.Put (": Easter: " &
Formatting.Image (Easter) (6 .. 10));
Ada.Text_IO.Put (", Ascension: " &
Formatting.Image (Easter + Days_To_Ascension) (6 .. 10));
Ada.Text_IO.Put (", Pentecost: " &
Formatting.Image (Easter + Days_To_Pentecost) (6 .. 10));
Ada.Text_IO.Put (", Trinity: " &
Formatting.Image (Easter + Days_To_Trinity) (6 .. 10));
Ada.Text_IO.Put_Line (", Corpus: " &
Formatting.Image (Easter + Days_To_Corpus) (6 .. 10));
end Print_Easter;
begin
Ada.Text_IO.Put_Line
("Christian holidays, related to Easter, for years from 2010 to 2020 CE:");
for I in 2010 .. 2020 loop
Print_Easter (I);
end loop;
end Main;
output:
Christian holidays, related to Easter, for years from 2010 to 2020 CE: 2010: Easter: 04-04, Ascension: 05-13, Pentecost: 05-23, Trinity: 05-30, Corpus: 06-03 2011: Easter: 04-24, Ascension: 06-02, Pentecost: 06-12, Trinity: 06-19, Corpus: 06-23 2012: Easter: 04-08, Ascension: 05-17, Pentecost: 05-27, Trinity: 06-03, Corpus: 06-07 2013: Easter: 03-31, Ascension: 05-09, Pentecost: 05-19, Trinity: 05-26, Corpus: 05-30 2014: Easter: 04-20, Ascension: 05-29, Pentecost: 06-08, Trinity: 06-15, Corpus: 06-19 2015: Easter: 04-05, Ascension: 05-14, Pentecost: 05-24, Trinity: 05-31, Corpus: 06-04 2016: Easter: 03-27, Ascension: 05-05, Pentecost: 05-15, Trinity: 05-22, Corpus: 05-26 2017: Easter: 04-16, Ascension: 05-25, Pentecost: 06-04, Trinity: 06-11, Corpus: 06-15 2018: Easter: 04-01, Ascension: 05-10, Pentecost: 05-20, Trinity: 05-27, Corpus: 05-31 2019: Easter: 04-21, Ascension: 05-30, Pentecost: 06-09, Trinity: 06-16, Corpus: 06-20 2020: Easter: 04-12, Ascension: 05-21, Pentecost: 05-31, Trinity: 06-07, Corpus: 06-11
ALGOL 68
Note: Base code specimen extracted from Algol 68 Genie Documentation Part III - Example a68g programs.
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")$,
FORMAT week day fmt = $c("Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri")$;
PROC year days = (YEAR year)DAY: # Ignore 1752 CE for the moment #
( month days(year, 2) = 28 | 365 | 366 );
PROC month days = (YEAR year, MONTH month) DAY:
( month | 31,
28 + ABS (year MOD 4 = 0 AND year MOD 100 /= 0 OR year MOD 400 = 0),
31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
MONTH year months = 12;
DAY week days = 7; # France 1793 to 1805 had 10 day weeks! #
OP + = (DATE in date, DAY in days)DATE:
BEGIN # todo: eliminate loops, handle year <= 1752 #
DAY days := in days;
DATE date := in date;
# Normalize the days to be less then 1 year #
WHILE days < 0 DO
year OF date -:= 1;
days +:= year days(year OF date)
OD;
WHILE days > year days(year OF date) DO
days -:= year days(year OF date);
year OF date +:= 1
OD;
month day OF date +:= days;
# Normalize the days to be the same month #
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 OVER 100, n = year MOD 19; # 19 years: Metonic cycle #
INT i := (c - c OVER 4 - (c - (c - 17) OVER 25) OVER 3 + 19 * n + 15) MOD 30;
i -:= (i OVER 28) * (1 - (i OVER 28) * (29 OVER (i + 1)) * ((21 - n) OVER 11));
INT l = i - (year + year OVER 4 + i + 2 - c + c OVER 4) MOD 7;
month OF date := 3 + (l + 40) OVER 44;
month day OF date := l + 28 - 31 * (month OF date OVER 4);
week day OF date := week day(date);
date
END;
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 MODAB 100;
1 + (month day + ((month + 1) * 26) OVER 10
+ year + year OVER 4 + c OVER 4 - 2 * c) MOD 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;
# Note: Y10K bug here... :-) #
FORMAT easter related fmt = $g(-4)" 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 centennial from 400 to 2100 CE:"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 CE:"l$));
FOR year FROM 2010 TO 2020 DO easter related print(year) OD
Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 CE: 400 Easter: Sun 2 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 Jun 500 Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun 600 Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 1 Jun, Trinity: Sun 8 Jun, Corpus: Thu 12 Jun 700 Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 3 Jun, Trinity: Sun 10 Jun, Corpus: Thu 14 Jun 800 Easter: Sun 23 Apr, Ascension: Thu 1 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus: Thu 22 Jun 900 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 CE: 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
Arturo
holidayOffsets: #[
"Easter": 0
"Ascension": 39
"Pentecost": 49
"Trinity": 56
"C/Christi": 60
]
easterDate: function [year][
a: year % 19
b: year / 100
c: year % 100
d: b / 4
e: b % 4
f: (b + 8) / 25
g: (1 + b - f) / 3
h: (((b - d) - g) + 15 + 19 * a) % 30
i: c / 4
k: c % 4
l: (32 + (2 * e) + ((2 * i) - h) - k) % 7
m: (a + (11 * h) + (22 * l)) / 451
n: h + (l - (7 * m)) + 114
month: n / 31
day: (n % 31) + 1
return to :date .format:"d-M-YYYY" ~"|day|-|month|-|year|"
]
outputHolidays: function [year][
edate: easterDate year
prints pad to :string year 4
prints " "
loop holidayOffsets [holiday, offset][
newDate: after.days:offset edate
s: to :string .format:"dd MMM" newDate
prints pad.center s size holiday
prints " "
]
print ""
]
print "Year Easter Ascension Pentecost Trinity C/Christi"
print " CE Sunday Thursday Sunday Sunday Thursday "
print "---- ------ --------- ---------- ------- ---------"
loop range.step:100 400 2100 => outputHolidays
print ""
loop 2010..2020 => outputHolidays
- Output:
Year Easter Ascension Pentecost Trinity C/Christi CE Sunday Thursday Sunday Sunday Thursday ---- ------ --------- ---------- ------- --------- 400 02 Apr 11 May 21 May 28 May 01 Jun 500 04 Apr 13 May 23 May 30 May 03 Jun 600 13 Apr 22 May 01 Jun 08 Jun 12 Jun 700 15 Apr 24 May 03 Jun 10 Jun 14 Jun 800 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 900 28 Mar 06 May 16 May 23 May 27 May 1000 30 Mar 08 May 18 May 25 May 29 May 1100 08 Apr 17 May 27 May 03 Jun 07 Jun 1200 09 Apr 18 May 28 May 04 Jun 08 Jun 1300 18 Apr 27 May 06 Jun 13 Jun 17 Jun 1400 20 Apr 29 May 08 Jun 15 Jun 19 Jun 1500 01 Apr 10 May 20 May 27 May 31 May 1600 02 Apr 11 May 21 May 28 May 01 Jun 1700 11 Apr 20 May 30 May 06 Jun 10 Jun 1800 13 Apr 22 May 01 Jun 08 Jun 12 Jun 1900 15 Apr 24 May 03 Jun 10 Jun 14 Jun 2000 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 2100 28 Mar 06 May 16 May 23 May 27 May 2010 04 Apr 13 May 23 May 30 May 03 Jun 2011 24 Apr 02 Jun 12 Jun 19 Jun 23 Jun 2012 08 Apr 17 May 27 May 03 Jun 07 Jun 2013 31 Mar 09 May 19 May 26 May 30 May 2014 20 Apr 29 May 08 Jun 15 Jun 19 Jun 2015 05 Apr 14 May 24 May 31 May 04 Jun 2016 27 Mar 05 May 15 May 22 May 26 May 2017 16 Apr 25 May 04 Jun 11 Jun 15 Jun 2018 01 Apr 10 May 20 May 27 May 31 May 2019 21 Apr 30 May 09 Jun 16 Jun 20 Jun 2020 12 Apr 21 May 31 May 07 Jun 11 Jun
BASH
#! /bin/bash
# Carter's calendar algorithm: https://web.archive.org/web/19990117015544/http://www.ast.cam.ac.uk/pubinfo/leaflets/easter/easter.html
set -e
easter() {
(( year=$1 ))
if [[ year -gt 2099 ]]
then
echo "Error year This algorithm does not work after 2099."
exit 1
fi
(( day = 225 - 11 * (year % 19) ))
while (( day > 50 ))
do
(( day -= 30 ))
done
if (( day > 48 ))
then
(( --day ))
fi
(( day = day + 7 - (year + year/4 + day + 1) % 7 ))
echo $day
}
for year in {1998..2100}
do
(( day=$( easter $year ) ))
if (( day < 32 ))
then
printf "%d-%02d-%02d\n" $year 3 $day
else
(( day -= 31 ))
printf "%d-%02d-%02d\n" $year 4 $day
fi
done
2020-04-12 2021-04-04 2022-04-17 2023-04-09 2024-03-31 2025-04-20 2026-04-05 2027-03-28 2028-04-16 2029-04-01 2030-04-21 2031-04-13 .. 2087-04-20 2088-04-11 2089-04-03 2090-04-16 2091-04-08 2092-03-30 2093-04-12 2094-04-04 2095-04-24 2096-04-15 2097-03-31 2098-04-20 2099-04-12
BBC BASIC
As discussed on the Talk page, the task is not well defined for historical dates because the change from the Julian to the Gregorian calendar happened on different dates in different regions. Therefore only dates from 1800 onwards are output, by which time most countries (particularly those likely to celebrate the Christian Easter) had adopted the Gregorian calendar.
INSTALL @lib$+"DATELIB"
PRINT "Year Easter Ascension Pentecost Trinity Corpus"
FOR year% = 1800 TO 2100 STEP 100
e% = FNeaster(year%) : f$ = "dd MMM"
PRINT ;year%, FN_date$(e%,f$), FN_date$(e%+39,f$), \
\ FN_date$(e%+49,f$), FN_date$(e%+56,f$), FN_date$(e%+60,f$)
NEXT
PRINT
FOR year% = 2010 TO 2020
e% = FNeaster(year%) : f$ = "dd MMM"
PRINT ;year%, FN_date$(e%,f$), FN_date$(e%+39,f$), \
\ FN_date$(e%+49,f$), FN_date$(e%+56,f$), FN_date$(e%+60,f$)
NEXT
END
DEF FNeaster(year%)
LOCAL a%, b%, c%, d%, e%
a% = year% MOD 19
b% = year% >>> 2
c% = b% DIV 25 + 1
d% = (c% * 3) >>> 2
e% = ((a% * 19) - ((c% * 8 + 5) DIV 25) + d% + 15) MOD 30
e% += (29578 - a% - e% * 32) >>> 10
e% -= ((year% MOD 7) + b% - d% + e% + 2) MOD 7
d% = e% >>> 5
= FN_mjd(e% - d% * 31, d% + 3, year%)
Output:
Year Easter Ascension Pentecost Trinity Corpus 1800 13 Apr 22 May 01 Jun 08 Jun 12 Jun 1900 15 Apr 24 May 03 Jun 10 Jun 14 Jun 2000 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 2100 28 Mar 06 May 16 May 23 May 27 May 2010 04 Apr 13 May 23 May 30 May 03 Jun 2011 24 Apr 02 Jun 12 Jun 19 Jun 23 Jun 2012 08 Apr 17 May 27 May 03 Jun 07 Jun 2013 31 Mar 09 May 19 May 26 May 30 May 2014 20 Apr 29 May 08 Jun 15 Jun 19 Jun 2015 05 Apr 14 May 24 May 31 May 04 Jun 2016 27 Mar 05 May 15 May 22 May 26 May 2017 16 Apr 25 May 04 Jun 11 Jun 15 Jun 2018 01 Apr 10 May 20 May 27 May 31 May 2019 21 Apr 30 May 09 Jun 16 Jun 20 Jun 2020 12 Apr 21 May 31 May 07 Jun 11 Jun
bc
These programs use several extensions: else
branch, print
statement, logical boolean operators, and long names.
Western holidays
This program switches calendar from Julian to Gregorian during October 1582. Its algorithm takes from Kalendar-Formeln by Zeller (1886).
scale = 0
/* Format d days after March 21. Assumes March, April, May or June. */
define format(d) {
if (d > 80) { print " Jun ", d - 71
} else if (d > 71) { print " Jun 0", d - 71
} else if (d > 49) { print " May ", d - 40
} else if (d > 40) { print " May 0", d - 40
} else if (d > 19) { print " Apr ", d - 10
} else if (d > 10) { print " Apr 0", d - 10
} else { print " Mar ", d + 21
}
}
/*
* For year n, print Easter and related holidays.
* Assumes n >= 1, scale = 0.
*/
define easter(n) {
auto a, b, d, e, j
/*
* Calculate e = day of Easter, following the 1886 paper,
* Kalender-Formeln (Calendar Formulae) by Chr. Zeller.
* http://www.merlyn.demon.co.uk/zel-1886.htm
*
* With bc, p % 7 gives the wrong result when p < 0. To give the
* correct result, this code uses "+ 6 * j" where one might have
* used "- j". This works because because 6 == -1 (mod 7).
*/
if (n < 1583) {
/* Julian calendar (before October 1582) */
b = (19 * (n % 19) + 15) % 30
d = (b + n + n / 4) % 7
} else {
/* Gregorian calendar (after October 1582) */
j = n / 100
a = n % 19
b = (19 * a + 15 + j - (8 * j + 13) / 25 - j / 4) % 30
d = (b + n + n / 4 + 6 * j + j / 4 + 2) % 7
if (d == 0 && (b == 29 || (b == 28 && a > 10))) d = 7
}
e = b + 7 - d /* This counts days after 21 March. */
if(n < 1000) " "
print n
z = format(e) /* Easter */
z = format(e + 39) /* Ascension Thursday */
z = format(e + 49) /* Pentecost */
z = format(e + 56) /* Trinity Sunday */
z = format(e + 60) /* Corpus Christi */
print "\n"
}
print " Easter Ascension Trinity Corpus\n"
print " AD Sunday Thursday Pentecost Sunday Christi\n"
for (year = 400; year <= 2000; year += 100) z = easter(year)
for (year = 2010; year <= 2020; year += 1) z = easter(year)
z = easter(2100)
quit
- Output:
Easter Ascension Trinity Corpus AD Sunday Thursday Pentecost Sunday Christi 400 Apr 01 May 10 May 20 May 27 May 31 500 Apr 02 May 11 May 21 May 28 Jun 01 600 Apr 10 May 19 May 29 Jun 05 Jun 09 700 Apr 11 May 20 May 30 Jun 06 Jun 10 800 Apr 19 May 28 Jun 07 Jun 14 Jun 18 900 Apr 20 May 29 Jun 08 Jun 15 Jun 19 1000 Mar 31 May 09 May 19 May 26 May 30 1100 Apr 01 May 10 May 20 May 27 May 31 1200 Apr 09 May 18 May 28 Jun 04 Jun 08 1300 Apr 10 May 19 May 29 Jun 05 Jun 09 1400 Apr 18 May 27 Jun 06 Jun 13 Jun 17 1500 Apr 19 May 28 Jun 07 Jun 14 Jun 18 1600 Apr 02 May 11 May 21 May 28 Jun 01 1700 Apr 11 May 20 May 30 Jun 06 Jun 10 1800 Apr 13 May 22 Jun 01 Jun 08 Jun 12 1900 Apr 15 May 24 Jun 03 Jun 10 Jun 14 2000 Apr 23 Jun 01 Jun 11 Jun 18 Jun 22 2010 Apr 04 May 13 May 23 May 30 Jun 03 2011 Apr 24 Jun 02 Jun 12 Jun 19 Jun 23 2012 Apr 08 May 17 May 27 Jun 03 Jun 07 2013 Mar 31 May 09 May 19 May 26 May 30 2014 Apr 20 May 29 Jun 08 Jun 15 Jun 19 2015 Apr 05 May 14 May 24 May 31 Jun 04 2016 Mar 27 May 05 May 15 May 22 May 26 2017 Apr 16 May 25 Jun 04 Jun 11 Jun 15 2018 Apr 01 May 10 May 20 May 27 May 31 2019 Apr 21 May 30 Jun 09 Jun 16 Jun 20 2020 Apr 12 May 21 May 31 Jun 07 Jun 11 2100 Mar 28 May 06 May 16 May 23 May 27
Eastern holidays
This program switches calendar from Julian to Gregorian during March 1924. Pentecost and Trinity Sunday are the same day; All Saints' Sunday is the next Sunday.
scale = 0
/* Format d days after March 21. Assumes March, April, May or June. */
define format(d) {
if (d > 80) { print " Jun ", d - 71
} else if (d > 71) { print " Jun 0", d - 71
} else if (d > 49) { print " May ", d - 40
} else if (d > 40) { print " May 0", d - 40
} else if (d > 19) { print " Apr ", d - 10
} else if (d > 10) { print " Apr 0", d - 10
} else { print " Mar ", d + 21
}
}
/*
* For year n, print Easter and related holidays.
* Assumes n >= 1, scale = 0.
*/
define easter(n) {
auto a, b, d, e, j
/*
* Calculate e = day of Easter, following the 1886 paper,
* Kalender-Formeln (Calendar Formulae) by Chr. Zeller.
* http://www.merlyn.demon.co.uk/zel-1886.htm
*/
b = (19 * (n % 19) + 15) % 30
d = (b + n + n / 4) % 7
e = b + 7 - d /* This counts days after 21 March. */
/*
* Starting at 1924 March 10 (Julian) / March 23 (Gregorian),
* change to the Gregorian calendar. Easter 1924 is April 27,
* after this change.
*/
if (n >= 1924) {
/* This formula only works from March to December. */
e += n / 100 - n / 400 - 2
}
if(n < 1000) " "
print n
z = format(e) /* Easter */
z = format(e + 39) /* Ascension Thursday */
z = format(e + 49) /* Pentecost */
z = format(e + 56) /* All Saints' Sunday */
print "\n"
}
print " Easter Ascension All\n"
print " AD Sunday Thursday Pentecost Saints\n"
for (year = 400; year <= 2000; year += 100) z = easter(year)
for (year = 2010; year <= 2020; year += 1) z = easter(year)
z = easter(2100)
quit
- Output:
Easter Ascension All AD Sunday Thursday Pentecost Saints 400 Apr 01 May 10 May 20 May 27 500 Apr 02 May 11 May 21 May 28 600 Apr 10 May 19 May 29 Jun 05 700 Apr 11 May 20 May 30 Jun 06 800 Apr 19 May 28 Jun 07 Jun 14 900 Apr 20 May 29 Jun 08 Jun 15 1000 Mar 31 May 09 May 19 May 26 1100 Apr 01 May 10 May 20 May 27 1200 Apr 09 May 18 May 28 Jun 04 1300 Apr 10 May 19 May 29 Jun 05 1400 Apr 18 May 27 Jun 06 Jun 13 1500 Apr 19 May 28 Jun 07 Jun 14 1600 Mar 23 May 01 May 11 May 18 1700 Mar 31 May 09 May 19 May 26 1800 Apr 08 May 17 May 27 Jun 03 1900 Apr 09 May 18 May 28 Jun 04 2000 Apr 30 Jun 08 Jun 18 Jun 25 2010 Apr 04 May 13 May 23 May 30 2011 Apr 24 Jun 02 Jun 12 Jun 19 2012 Apr 15 May 24 Jun 03 Jun 10 2013 May 05 Jun 13 Jun 23 Jun 30 2014 Apr 20 May 29 Jun 08 Jun 15 2015 Apr 12 May 21 May 31 Jun 07 2016 May 01 Jun 09 Jun 19 Jun 26 2017 Apr 16 May 25 Jun 04 Jun 11 2018 Apr 08 May 17 May 27 Jun 03 2019 Apr 28 Jun 06 Jun 16 Jun 23 2020 Apr 19 May 28 Jun 07 Jun 14 2100 May 02 Jun 10 Jun 20 Jun 27
Befunge
Follows the same basic algorithm as C#, D, Java and many more.
First two rows initialise the set of years to be processed; second two output the header; the main algorithm starts on row six.
037*>1- : 9`#v_2*4+>1-:3`#v_v
^\+*"(2":< ^\*"d":< >$ v
v"Pentcst"9"Trinity"9"Corpus"+550<
>9"nsnecsA"9"retsaE"9"raeY">:#,_$v
MarAprMayJun
v-/4::/"d"\*/2"&"%/2"&"::,9.:_@#:<
>\:8+55*/-1+3/-35*++65*%00p::"d"v,
v:%7+*84+*2%4/"d"\-g00-%4\*2/4:%<+
>10p","2/*00g56+*+\"&"2/%+19"2"*v5
v \+55\7\4\0+/2","-\+g01g00*7/+<5
>"'"\>:9\>:156*+`!#v_156*+-\3v>$$^
+9,^ ^\+3\-*65_v#`*65:\+ <^_
*84,g4+1,g4:+1,g4:\< >:#\!#.^#,
- Output:
Year Easter Ascensn Pentcst Trinity Corpus 400 Apr 2 May 11 May 21 May 28 Jun 1 500 Apr 4 May 13 May 23 May 30 Jun 3 600 Apr 13 May 22 Jun 1 Jun 8 Jun 12 700 Apr 15 May 24 Jun 3 Jun 10 Jun 14 800 Apr 23 Jun 1 Jun 11 Jun 18 Jun 22 900 Mar 28 May 6 May 16 May 23 May 27 1000 Mar 30 May 8 May 18 May 25 May 29 1100 Apr 8 May 17 May 27 Jun 3 Jun 7 1200 Apr 9 May 18 May 28 Jun 4 Jun 8 1300 Apr 18 May 27 Jun 6 Jun 13 Jun 17 1400 Apr 20 May 29 Jun 8 Jun 15 Jun 19 1500 Apr 1 May 10 May 20 May 27 May 31 1600 Apr 2 May 11 May 21 May 28 Jun 1 1700 Apr 11 May 20 May 30 Jun 6 Jun 10 1800 Apr 13 May 22 Jun 1 Jun 8 Jun 12 1900 Apr 15 May 24 Jun 3 Jun 10 Jun 14 2000 Apr 23 Jun 1 Jun 11 Jun 18 Jun 22 2100 Mar 28 May 6 May 16 May 23 May 27 2010 Apr 4 May 13 May 23 May 30 Jun 3 2011 Apr 24 Jun 2 Jun 12 Jun 19 Jun 23 2012 Apr 8 May 17 May 27 Jun 3 Jun 7 2013 Mar 31 May 9 May 19 May 26 May 30 2014 Apr 20 May 29 Jun 8 Jun 15 Jun 19 2015 Apr 5 May 14 May 24 May 31 Jun 4 2016 Mar 27 May 5 May 15 May 22 May 26 2017 Apr 16 May 25 Jun 4 Jun 11 Jun 15 2018 Apr 1 May 10 May 20 May 27 May 31 2019 Apr 21 May 30 Jun 9 Jun 16 Jun 20 2020 Apr 12 May 21 May 31 Jun 7 Jun 11
C
#include <stdio.h>
typedef int year_t, month_t, week_t, day_t;
typedef struct{
year_t year; /* day_t year_day, */
month_t month; day_t month_day;/*
week_t week, */ day_t week_day; } date_t;
const char *mon_fmt[] = {0, "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
const char *week_day_fmt[] = {0, "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri"};
day_t month_days(year_t year, month_t month)
{ day_t days[]={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
return (month==2) ? 28 + (( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0) : days[month];
}
day_t year_days(year_t year) /* Ignore 1752 CE for the moment */
{ return (month_days(year, 2) == 28) ? 365 : 366; }
month_t year_months = 12;
week_t week_days = 7; /* France 1793 to 1805 had 10 day weeks! */
date_t plusab(date_t *date, day_t days)
{ /* todo: eliminate loops, handle year <== 1752 */
/* Normalize the days to be less then 1 year */
while(days < 0){
date->year -= 1;
days += year_days(date->year);
};
while(days > year_days(date->year)){
days -= year_days(date->year);
date->year += 1;
};
date->month_day += days;
/* Normalize the days to be the same month */
while(date->month_day > month_days(date->year, date->month)){
date->month_day -= month_days(date->year, date->month);
date->month += 1;
if(date->month > year_months){
date->month -= year_months;
date->year += 1;
}
}
date->week_day = week_day(*date);
return *date;
}
date_t easter (year_t year)
{
/*
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)
*/
date_t date; date.year = year;
int c = year / 100, n = year % 19; /* 19 years: Metonic cycle */
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;
date.month = 3 + (l + 40) / 44;
date.month_day = l + 28 - 31 * (date.month / 4);
date.week_day = week_day(date);
return date;
}
day_t week_day (date_t date)
/* Zeller’s Congruence algorithm from 1887. */
{
int year = date.year, month = date.month, month_day = date.month_day, c;
if(month <= 2){month += 12; year -= 1;}
c = year / 100;
year %= 100;
return 1 + ((month_day + ((month + 1) * 26) / 10
+ year + year / 4 + c / 4 - 2 * c) % 7 + 7) % 7;
}
#define wdmdm_fmt "%s %2d %s"
typedef struct{date_t easter, ascension, pentecost, trinity, corpus_christi;}easter_related_t;
easter_related_t easter_related_init (year_t year)
{
date_t date;
easter_related_t holidays;
/* Easter date, always a Sunday. */
holidays.easter = date = easter(year);
/* Ascension day is 39 days after Easter.*/
holidays.ascension = plusab(&date, 39);
/* Pentecost is 10 days after Ascension day.*/
holidays.pentecost = plusab(&date, 10);
/* Trinity is 7 days after Pentecost.*/
holidays.trinity = plusab(&date, 7);
/* Corpus Christi is 4 days after Trinity.*/
holidays.corpus_christi = plusab(&date, 4);
return holidays;
}
/* note: y10k bug here... :-) */
#define easter_related_fmt "%4d Easter: "wdmdm_fmt", Ascension: "wdmdm_fmt\
", Pentecost: "wdmdm_fmt", Trinity: "wdmdm_fmt", Corpus: "wdmdm_fmt"\n"
void easter_related_print(year_t year)
{
easter_related_t holidays = easter_related_init(year);
#define wdmdm(date) week_day_fmt[date.week_day], date.month_day, mon_fmt[date.month]
printf(easter_related_fmt, year,
wdmdm(holidays.easter), wdmdm(holidays.ascension), wdmdm(holidays.pentecost),
wdmdm(holidays.trinity), wdmdm(holidays.corpus_christi));
}
int main(){
year_t year;
printf ("Christian holidays, related to Easter, for each centennial from 400 to 2100 CE:\n");
for(year=400; year<=2100; year+=100){ easter_related_print(year); }
printf ("\nChristian holidays, related to Easter, for years from 2010 to 2020 CE:\n");
for(year=2010; year<=2020; year++){ easter_related_print(year); }
return 0;
}
Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 CE: 400 Easter: Sun 2 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 Jun 500 Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun 600 Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 1 Jun, Trinity: Sun 8 Jun, Corpus: Thu 12 Jun 700 Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 3 Jun, Trinity: Sun 10 Jun, Corpus: Thu 14 Jun 800 Easter: Sun 23 Apr, Ascension: Thu 1 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus: Thu 22 Jun 900 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 CE: 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
C#
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Linq;
internal class Program
{
private static readonly OrderedDictionary _holidayOffsets = new OrderedDictionary
{
{"Easter", 0},
{"Ascension", 39},
{"Pentecost", 49},
{"Trinity", 56},
{"Corpus", 60},
};
static void Main(string[] args)
{
Console.WriteLine("Christian holidays, related to Easter, for each centennial from 400 to 2100 CE:");
for (int year = 400; year <= 2100; year += 100)
OutputHolidays(year);
Console.WriteLine();
Console.WriteLine("Christian holidays, related to Easter, for years from 2010 to 2020 CE:");
for (int year = 2010; year <= 2020; year += 1)
OutputHolidays(year);
}
static void OutputHolidays(int year)
{
var easter = CalculateEaster(year);
var holidays = from kp in _holidayOffsets.OfType<DictionaryEntry>()
let holiday = easter.AddDays(Convert.ToInt32(kp.Value))
select kp.Key + ": " + string.Format("{0,2:ddd} {0,2:%d} {0:MMM}", holiday);
Console.WriteLine("{0,4} {1}", year, string.Join(", ", holidays.ToArray()));
}
static DateTime CalculateEaster(int year)
{
var a = year % 19;
var b = year / 100;
var c = year %100;
var d = b / 4;
var e = b % 4;
var f = (b + 8) / 25;
var g = (b - f + 1) / 3;
var h = (19 * a + b - d - g + 15) % 30;
var i = c / 4;
var k = c % 4;
var l = (32 + 2 * e + 2 * i - h - k) % 7;
var m = (a + 11 * h + 22 * l) / 451;
var numerator = h + l - 7 * m + 114;
var month = numerator / 31;
var day = (numerator % 31) + 1;
return new DateTime(year, month, day);
}
}
Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 CE: 400 Easter: Sun 2 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 Jun 500 Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun 600 Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 1 Jun, Trinity: Sun 8 Jun, Corpus: Thu 12 Jun 700 Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 3 Jun, Trinity: Sun 10 Jun, Corpus: Thu 14 Jun 800 Easter: Sun 23 Apr, Ascension: Thu 1 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus: Thu 22 Jun 900 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 CE: 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
C++
#include <chrono>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <vector>
std::chrono::year_month_day date_of_easter(const int32_t& year) {
const int32_t a = year % 19;
const int32_t b = year / 100;
const int32_t c = year % 100;
const int32_t d = b / 4;
const int32_t e = b % 4;
const int32_t f = ( b + 8 ) / 25;
const int32_t g = ( b - f + 1 ) / 3;
const int32_t h = ( 19 * a + b - d - g + 15 ) % 30;
const int32_t i = c / 4;
const int32_t k = c % 4;
const int32_t l = ( 32 + 2 * e + 2 * i - h - k ) % 7;
const int32_t m = ( a + 11 * h + 22 * l ) / 451;
const int32_t n = h + l - 7 * m + 114;
const unsigned int month = n / 31;
const unsigned int day = ( n % 31 ) + 1;
return { std::chrono::year{year}, std::chrono::month{month}, std::chrono::day{day} };
}
void display(const int32_t& year, const std::vector<int32_t>& holiday_offsets) {
std::chrono::year_month_day easter = date_of_easter(year);
std::cout << std::setw(4) << year;
for ( const int32_t& holiday_offset : holiday_offsets ) {
std::chrono::year_month_day date = std::chrono::sys_days(easter) + std::chrono::days{holiday_offset};
std::cout << std::setw(7) << date.day() << std::setw(4) << date.month();
}
std::cout << std::endl;
}
int main() {
const std::vector<int32_t> holiday_offsets{ 0, 39, 49, 56, 60 };
std::cout << "Year Easter Ascension Pentecost Trinity Corpus Christi" << std::endl;
std::cout << " CE Sunday Thursday Sunday Sunday Thursday " << std::endl;
std::cout << "---- ------ --------- --------- ------- --------------" << std::endl;
for ( int32_t year = 400; year <= 2100; year += 100 ) {
display(year, holiday_offsets);
}
std::cout << std::endl;
for ( int32_t year= 2010; year <= 2020; ++year ) {
display(year, holiday_offsets);
}
}
- Output:
Year Easter Ascension Pentecost Trinity Corpus Christi CE Sunday Thursday Sunday Sunday Thursday ---- ------ --------- --------- ------- -------------- 400 02 Apr 11 May 21 May 28 May 01 Jun 500 04 Apr 13 May 23 May 30 May 03 Jun 600 13 Apr 22 May 01 Jun 08 Jun 12 Jun 700 15 Apr 24 May 03 Jun 10 Jun 14 Jun 800 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 900 28 Mar 06 May 16 May 23 May 27 May 1000 30 Mar 08 May 18 May 25 May 29 May 1100 08 Apr 17 May 27 May 03 Jun 07 Jun 1200 09 Apr 18 May 28 May 04 Jun 08 Jun 1300 18 Apr 27 May 06 Jun 13 Jun 17 Jun 1400 20 Apr 29 May 08 Jun 15 Jun 19 Jun 1500 01 Apr 10 May 20 May 27 May 31 May 1600 02 Apr 11 May 21 May 28 May 01 Jun 1700 11 Apr 20 May 30 May 06 Jun 10 Jun 1800 13 Apr 22 May 01 Jun 08 Jun 12 Jun 1900 15 Apr 24 May 03 Jun 10 Jun 14 Jun 2000 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 2100 28 Mar 06 May 16 May 23 May 27 May 2010 04 Apr 13 May 23 May 30 May 03 Jun 2011 24 Apr 02 Jun 12 Jun 19 Jun 23 Jun 2012 08 Apr 17 May 27 May 03 Jun 07 Jun 2013 31 Mar 09 May 19 May 26 May 30 May 2014 20 Apr 29 May 08 Jun 15 Jun 19 Jun 2015 05 Apr 14 May 24 May 31 May 04 Jun 2016 27 Mar 05 May 15 May 22 May 26 May 2017 16 Apr 25 May 04 Jun 11 Jun 15 Jun 2018 01 Apr 10 May 20 May 27 May 31 May 2019 21 Apr 30 May 09 Jun 16 Jun 20 Jun 2020 12 Apr 21 May 31 May 07 Jun 11 Jun
COBOL
identification division.
program-id. Easter.
environment division.
configuration section.
repository.
function date-of-integer intrinsic
function integer-of-date intrinsic
function mod intrinsic.
data division.
working-storage section.
77 days pic 9(2).
77 a pic 9(2).
77 b pic 9(2).
77 c pic 9(2).
77 d pic 9(2).
77 e pic 9(2).
77 f pic 9(2).
77 g pic 9(2).
77 h pic 9(2).
77 i pic 9(2).
77 k pic 9(2).
77 l pic 9(2).
77 m pic 9(2).
77 week-day pic 9(1).
77 numerator pic 9(4).
77 integer-date pic 9(18).
01 month-tab value "JanFebMarAprMayJunJulAugSepOctNovDec".
05 month-abreviated pic x(3) occurs 12.
01 week-day-tab value "SunMonTueWedThuFriSat".
05 week-day-abreviated pic x(3) occurs 7.
01 easter-date pic 9(8).
01 filler redefines easter-date.
05 easter-year pic 9(4).
05 easter-month pic 9(2).
05 easter-day pic 9(2).
01 holiday-date pic 9(8).
01 filler redefines holiday-date.
05 holiday-year pic 9(4).
05 holiday-month pic 9(2).
05 holiday-day pic 9(2).
01 edt-date.
05 edt-week-day pic x(3).
05 filler pic x value space.
05 edt-day pic z(2).
05 filler pic x value space.
05 edt-month pic x(3).
procedure division.
main.
display "Christian holidays, related to Easter, for each centennial from 1700 to 2100 CE:"
perform varying easter-year from 1700 by 100 until easter-year > 2100
perform output-holydays
end-perform
display " "
display "Christian holidays, related to Easter, for years from 2010 to 2020 CE:"
perform varying easter-year from 2010 by 1 until easter-year > 2020
perform output-holydays
end-perform
display " "
stop run
.
output-holydays.
display easter-year " " no advancing
perform calculate-easter
move 0 to days
perform add-days
display " Easter: " edt-date no advancing
move 39 to days
perform add-days
display " Ascension: " edt-date no advancing
move 49 to days
perform add-days
display " Pentecost: " edt-date no advancing
move 56 to days
perform add-days
display " Trinity: " edt-date no advancing
move 60 to days
perform add-days
display " Corpus: " edt-date
.
calculate-easter.
compute a = mod(easter-year, 19)
compute b = easter-year / 100
compute c = mod(easter-year, 100)
compute d = b / 4
compute e = mod(b, 4)
compute f = (b + 8) / 25
compute g = (b - f + 1) / 3
compute h = mod((19 * a + b - d - g + 15), 30)
compute i = c / 4
compute k = mod(c, 4)
compute l = mod((32 + 2 * e + 2 * i - h - k), 7)
compute m = (a + 11 * h + 22 * l) / 451
compute numerator = h + l - 7 * m + 114
compute easter-month = numerator / 31
compute easter-day = mod(numerator, 31) + 1
.
add-days.
if days = 0
move easter-date to holiday-date
move 1 to week-day
else
compute holiday-date = date-of-integer(integer-of-date(easter-date) + days)
compute week-day = mod(integer-of-date(easter-date) + days, 7) + 1
end-if
move week-day-abreviated(week-day) to edt-week-day
move month-abreviated(holiday-month) to edt-month
move holiday-day to edt-day
.
- Output:
Implemented the task for 1700 and greater years because COBOL is a Business language and their routines only works after Day zero that is equals to 00:00:00 31 December 1600
Christian holidays, related to Easter, for each centennial from 1700 to 2100 CE: 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 CE: 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
Common Lisp
; Easter sunday. Result is a list '(month day)
;
; See:
; Jean Meeus, "Astronomical Formulae for Calculators",
; 4th edition, Willmann-Bell, 1988, p.31
(defun easter (year)
(let (a b c d e f g h i k l m n p)
(setq a (rem year 19))
(multiple-value-setq (b c) (floor year 100))
(multiple-value-setq (d e) (floor b 4))
(setq f (floor (+ b 8) 25))
(setq g (floor (- b f -1) 3))
(setq h (rem (+ (* 19 a) (- b d g) 15) 30))
(multiple-value-setq (i k) (floor c 4))
(setq l (rem (+ 32 e e i (- i h k)) 7))
(setq m (floor (+ a (* 11 h) (* 22 l)) 451))
(multiple-value-setq (n p) (floor (+ h l (- 114 (* 7 m))) 31))
(list n (1+ p))))
D
import std.stdio, std.datetime;
void printEasterRelatedHolidays(in int year) {
static struct Holyday {
string name;
int offs;
}
static immutable Holyday[] holidayOffsets = [{"Easter", 0},
{"Ascension", 39},
{"Pentecost", 10},
{"Trinity", 7},
{"Corpus", 4}];
// Calculate Easter.
Date date;
{
immutable a = year % 19;
immutable b = year / 100;
immutable c = year %100;
immutable d = b / 4;
immutable e = b % 4;
immutable f = (b + 8) / 25;
immutable g = (b - f + 1) / 3;
immutable h = (19 * a + b - d - g + 15) % 30;
immutable i = c / 4;
immutable k = c % 4;
immutable l = (32 + 2 * e + 2 * i - h - k) % 7;
immutable m = (a + 11 * h + 22 * l) / 451;
immutable n = h + l - 7 * m + 114;
immutable month = n / 31;
immutable day = (n % 31) + 1;
date = Date(year, month, day);
}
writef("%4d ", year);
foreach (immutable hd; holidayOffsets) {
date += days(hd.offs);
writef("%s: %2d %s ", hd.name, date.day, date.month);
}
writeln();
}
void main() {
writeln("Christian holidays, related to Easter," ~
" for each centennial from 400 to 2100 CE:");
for (int y = 400; y <= 2100; y += 100)
printEasterRelatedHolidays(y);
writeln("\nChristian holidays, related to Easter," ~
" for years from 2010 to 2020 CE:");
foreach (immutable y; 2010 .. 2021)
printEasterRelatedHolidays(y);
}
- Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 CE: 400 Easter: 2 apr Ascension: 11 may Pentecost: 21 may Trinity: 28 may Corpus: 1 jun 500 Easter: 4 apr Ascension: 13 may Pentecost: 23 may Trinity: 30 may Corpus: 3 jun 600 Easter: 13 apr Ascension: 22 may Pentecost: 1 jun Trinity: 8 jun Corpus: 12 jun 700 Easter: 15 apr Ascension: 24 may Pentecost: 3 jun Trinity: 10 jun Corpus: 14 jun 800 Easter: 23 apr Ascension: 1 jun Pentecost: 11 jun Trinity: 18 jun Corpus: 22 jun 900 Easter: 28 mar Ascension: 6 may Pentecost: 16 may Trinity: 23 may Corpus: 27 may 1000 Easter: 30 mar Ascension: 8 may Pentecost: 18 may Trinity: 25 may Corpus: 29 may 1100 Easter: 8 apr Ascension: 17 may Pentecost: 27 may Trinity: 3 jun Corpus: 7 jun 1200 Easter: 9 apr Ascension: 18 may Pentecost: 28 may Trinity: 4 jun Corpus: 8 jun 1300 Easter: 18 apr Ascension: 27 may Pentecost: 6 jun Trinity: 13 jun Corpus: 17 jun 1400 Easter: 20 apr Ascension: 29 may Pentecost: 8 jun Trinity: 15 jun Corpus: 19 jun 1500 Easter: 1 apr Ascension: 10 may Pentecost: 20 may Trinity: 27 may Corpus: 31 may 1600 Easter: 2 apr Ascension: 11 may Pentecost: 21 may Trinity: 28 may Corpus: 1 jun 1700 Easter: 11 apr Ascension: 20 may Pentecost: 30 may Trinity: 6 jun Corpus: 10 jun 1800 Easter: 13 apr Ascension: 22 may Pentecost: 1 jun Trinity: 8 jun Corpus: 12 jun 1900 Easter: 15 apr Ascension: 24 may Pentecost: 3 jun Trinity: 10 jun Corpus: 14 jun 2000 Easter: 23 apr Ascension: 1 jun Pentecost: 11 jun Trinity: 18 jun Corpus: 22 jun 2100 Easter: 28 mar Ascension: 6 may Pentecost: 16 may Trinity: 23 may Corpus: 27 may Christian holidays, related to Easter, for years from 2010 to 2020 CE: 2010 Easter: 4 apr Ascension: 13 may Pentecost: 23 may Trinity: 30 may Corpus: 3 jun 2011 Easter: 24 apr Ascension: 2 jun Pentecost: 12 jun Trinity: 19 jun Corpus: 23 jun 2012 Easter: 8 apr Ascension: 17 may Pentecost: 27 may Trinity: 3 jun Corpus: 7 jun 2013 Easter: 31 mar Ascension: 9 may Pentecost: 19 may Trinity: 26 may Corpus: 30 may 2014 Easter: 20 apr Ascension: 29 may Pentecost: 8 jun Trinity: 15 jun Corpus: 19 jun 2015 Easter: 5 apr Ascension: 14 may Pentecost: 24 may Trinity: 31 may Corpus: 4 jun 2016 Easter: 27 mar Ascension: 5 may Pentecost: 15 may Trinity: 22 may Corpus: 26 may 2017 Easter: 16 apr Ascension: 25 may Pentecost: 4 jun Trinity: 11 jun Corpus: 15 jun 2018 Easter: 1 apr Ascension: 10 may Pentecost: 20 may Trinity: 27 may Corpus: 31 may 2019 Easter: 21 apr Ascension: 30 may Pentecost: 9 jun Trinity: 16 jun Corpus: 20 jun 2020 Easter: 12 apr Ascension: 21 may Pentecost: 31 may Trinity: 7 jun Corpus: 11 jun
Delphi
program Holidays_related_to_Easter;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
type
THollyday = record
name: string;
offs: Integer;
end;
const
Holyday: array[0..4] of THollyday = ((
name: 'Easter';
offs: 0
), (
name: 'Ascension';
offs: 39
), (
name: 'Pentecost';
offs: 10
), (
name: 'Trinity';
offs: 7
), (
name: 'Corpus';
offs: 4
));
function Easter(year: Integer): TDateTime;
begin
var a := year mod 19;
var b := year div 100;
var c := year mod 100;
var d := b div 4;
var e := b mod 4;
var f := (b + 8) div 25;
var g := (b - f + 1) div 3;
var h := (19 * a + b - d - g + 15) mod 30;
var i := c div 4;
var k := c mod 4;
var l := (32 + 2 * e + 2 * i - h - k) mod 7;
var m := (a + 11 * h + 22 * l) div 451;
var n := h + l - 7 * m + 114;
var month := n div 31;
var day := (n mod 31) + 1;
Result := EncodeDate(year, month, day);
end;
procedure PrintEasterRelatedHolidays(year: Integer);
var
y, m, d: word;
fmt: TFormatSettings;
begin
fmt := TFormatSettings.Create('en-US'); // just for use english name of month
var date := Easter(year);
write(year: 4, ' ');
for var hd in Holyday do
begin
date := date + hd.offs;
var dt := FormatDateTime('dd mmmm', date, fmt);
write(format('%s: %s ', [hd.name, dt]));
end;
writeln;
end;
begin
writeln('Christian holidays, related to Easter,' +
' for each centennial from 400 to 2100 CE:');
for var y := 4 to 21 do
printEasterRelatedHolidays(y * 100);
writeln(#10'Christian holidays, related to Easter,' +
' for years from 2010 to 2020 CE:');
for var y := 2010 to 2020 do
printEasterRelatedHolidays(y);
readln;
end.
Elixir
defmodule Holiday do
@offsets [ Easter: 0, Ascension: 39, Pentecost: 49, Trinity: 56, Corpus: 60 ]
@mon { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }
def easter_date(year) do
a = rem(year, 19)
b = div(year, 100)
c = rem(year, 100)
d = div(b, 4)
e = rem(b, 4)
f = div((b + 8), 25)
g = div((b - f + 1), 3)
h = rem((19*a + b - d - g + 15), 30)
i = div(c, 4)
k = rem(c, 4)
l = rem((32 + 2*e + 2*i - h - k), 7)
m = div((a + 11*h + 22*l), 451)
numerator = h + l - 7*m + 114
month = div(numerator, 31)
day = rem(numerator, 31) + 1
{year, month, day}
end
defp holidays(year) do
IO.write String.rjust("#{year}:", 5)
gday = :calendar.date_to_gregorian_days(easter_date(year))
Enum.map_join(Keyword.values(@offsets), fn d ->
{_year, month, day} = :calendar.gregorian_days_to_date(gday + d)
String.rjust("#{day} #{elem(@mon, month-1)}", 11)
end)
end
def task do
IO.puts "Year:" <> Enum.map_join(Keyword.keys(@offsets), &String.rjust("#{&1}",11))
Enum.each(Enum.take_every(400..2100, 100), fn year -> IO.puts holidays(year) end)
IO.puts ""
Enum.each(2010..2020, fn year -> IO.puts holidays(year) end)
end
end
Holiday.task
- Output:
Year: Easter Ascension Pentecost Trinity Corpus 400: 2 Apr 11 May 21 May 28 May 1 Jun 500: 4 Apr 13 May 23 May 30 May 3 Jun 600: 13 Apr 22 May 1 Jun 8 Jun 12 Jun 700: 15 Apr 24 May 3 Jun 10 Jun 14 Jun 800: 23 Apr 1 Jun 11 Jun 18 Jun 22 Jun 900: 28 Mar 6 May 16 May 23 May 27 May 1000: 30 Mar 8 May 18 May 25 May 29 May 1100: 8 Apr 17 May 27 May 3 Jun 7 Jun 1200: 9 Apr 18 May 28 May 4 Jun 8 Jun 1300: 18 Apr 27 May 6 Jun 13 Jun 17 Jun 1400: 20 Apr 29 May 8 Jun 15 Jun 19 Jun 1500: 1 Apr 10 May 20 May 27 May 31 May 1600: 2 Apr 11 May 21 May 28 May 1 Jun 1700: 11 Apr 20 May 30 May 6 Jun 10 Jun 1800: 13 Apr 22 May 1 Jun 8 Jun 12 Jun 1900: 15 Apr 24 May 3 Jun 10 Jun 14 Jun 2000: 23 Apr 1 Jun 11 Jun 18 Jun 22 Jun 2100: 28 Mar 6 May 16 May 23 May 27 May 2010: 4 Apr 13 May 23 May 30 May 3 Jun 2011: 24 Apr 2 Jun 12 Jun 19 Jun 23 Jun 2012: 8 Apr 17 May 27 May 3 Jun 7 Jun 2013: 31 Mar 9 May 19 May 26 May 30 May 2014: 20 Apr 29 May 8 Jun 15 Jun 19 Jun 2015: 5 Apr 14 May 24 May 31 May 4 Jun 2016: 27 Mar 5 May 15 May 22 May 26 May 2017: 16 Apr 25 May 4 Jun 11 Jun 15 Jun 2018: 1 Apr 10 May 20 May 27 May 31 May 2019: 21 Apr 30 May 9 Jun 16 Jun 20 Jun 2020: 12 Apr 21 May 31 May 7 Jun 11 Jun
Erlang
-module(holidays).
-export([task/0]).
offsets(easter) -> 0;
offsets(ascension) -> 39;
offsets(pentecost) -> 49;
offsets(trinity) -> 56;
offsets(corpus) -> 60.
month(Month) ->
element(Month, { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" } ).
easter_date(Year) ->
A = Year rem 19,
B = Year div 100,
C = Year rem 100,
D = B div 4,
E = B rem 4,
F = (B + 8) div 25,
G = (B - F + 1) div 3,
H = (19*A + B - D - G + 15) rem 30,
I = C div 4,
K = C rem 4,
L = (32 + 2*E + 2*I - H - K) rem 7,
M = (A + 11*H + 22*L) div 451,
Numerator = H + L - 7*M + 114,
Month = Numerator div 31,
Day = Numerator rem 31 + 1,
{Year, Month, Day}.
holidays() ->
[ easter, ascension, pentecost, trinity, corpus ].
holidays(Year) ->
io:format("~4w:", [Year]),
Gday = calendar:date_to_gregorian_days(easter_date(Year)),
holidays(Gday, holidays()).
holidays(_, []) ->
io:format("~n");
holidays(Gday, [H | T]) ->
Offset = offsets(H),
{_Year, Month, Day} = calendar:gregorian_days_to_date(Gday + Offset),
io:format("~6w ~3s", [Day, month(Month)]),
holidays(Gday, T).
title([]) ->
io:format("~n");
title([H | T]) ->
io:format(" ~9s", [H]),
title(T).
task() ->
io:format("Year:"),
title(holidays()),
task(400, 2100, 100),
task(2010, 2020, 1).
task(Year, Max, _) when Year > Max ->
io:format("~n");
task(Year, Max, Step) ->
holidays(Year),
task(Year+Step, Max, Step).
- Output:
1> holidays:task(). Year: easter ascension pentecost trinity corpus 400: 2 Apr 11 May 21 May 28 May 1 Jun 500: 4 Apr 13 May 23 May 30 May 3 Jun 600: 13 Apr 22 May 1 Jun 8 Jun 12 Jun 700: 15 Apr 24 May 3 Jun 10 Jun 14 Jun 800: 23 Apr 1 Jun 11 Jun 18 Jun 22 Jun 900: 28 Mar 6 May 16 May 23 May 27 May 1000: 30 Mar 8 May 18 May 25 May 29 May 1100: 8 Apr 17 May 27 May 3 Jun 7 Jun 1200: 9 Apr 18 May 28 May 4 Jun 8 Jun 1300: 18 Apr 27 May 6 Jun 13 Jun 17 Jun 1400: 20 Apr 29 May 8 Jun 15 Jun 19 Jun 1500: 1 Apr 10 May 20 May 27 May 31 May 1600: 2 Apr 11 May 21 May 28 May 1 Jun 1700: 11 Apr 20 May 30 May 6 Jun 10 Jun 1800: 13 Apr 22 May 1 Jun 8 Jun 12 Jun 1900: 15 Apr 24 May 3 Jun 10 Jun 14 Jun 2000: 23 Apr 1 Jun 11 Jun 18 Jun 22 Jun 2100: 28 Mar 6 May 16 May 23 May 27 May 2010: 4 Apr 13 May 23 May 30 May 3 Jun 2011: 24 Apr 2 Jun 12 Jun 19 Jun 23 Jun 2012: 8 Apr 17 May 27 May 3 Jun 7 Jun 2013: 31 Mar 9 May 19 May 26 May 30 May 2014: 20 Apr 29 May 8 Jun 15 Jun 19 Jun 2015: 5 Apr 14 May 24 May 31 May 4 Jun 2016: 27 Mar 5 May 15 May 22 May 26 May 2017: 16 Apr 25 May 4 Jun 11 Jun 15 Jun 2018: 1 Apr 10 May 20 May 27 May 31 May 2019: 21 Apr 30 May 9 Jun 16 Jun 20 Jun 2020: 12 Apr 21 May 31 May 7 Jun 11 Jun ok
Factor
Factor already has an easter
word in its calendar
vocabulary, but is has been re-implemented here as it seems in the spirit of the task.
USING: calendar formatting io kernel locals math math.ranges
sequences ;
! Calculate Easter.
:: my-easter ( year -- timestamp )
year 19 mod :> a
year 100 /i :> b
year 100 mod :> c
b 4 /i :> d
b 4 mod :> e
b 8 + 25 /i :> f
b f - 1 + 3 /i :> g
19 a * b + d - g - 15 + 30 mod :> h
c 4 /i :> i
c 4 mod :> k
32 2 e * + 2 i * + h - k - 7 mod :> l
a 11 h * + 22 l * + 451 /i :> m
h l + 7 m * - 114 + :> n
n 31 /i :> month
n 31 mod 1 + :> day
year month day <date> ;
: show-related ( timestamp days-offset -- )
days time+ " %d %b " strftime write ;
: holidays ( from to step -- )
"Year Easter Ascension Pentecost Trinity Corpus" print
<range> [
dup "%4d: " printf my-easter
{ 0 39 49 56 60 } [ show-related ] with each nl
] each ;
400 2100 100 holidays nl
2010 2020 1 holidays
- Output:
Year Easter Ascension Pentecost Trinity Corpus 400: 02 Apr 11 May 21 May 28 May 01 Jun 500: 04 Apr 13 May 23 May 30 May 03 Jun 600: 13 Apr 22 May 01 Jun 08 Jun 12 Jun 700: 15 Apr 24 May 03 Jun 10 Jun 14 Jun 800: 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 900: 28 Mar 06 May 16 May 23 May 27 May 1000: 30 Mar 08 May 18 May 25 May 29 May 1100: 08 Apr 17 May 27 May 03 Jun 07 Jun 1200: 09 Apr 18 May 28 May 04 Jun 08 Jun 1300: 18 Apr 27 May 06 Jun 13 Jun 17 Jun 1400: 20 Apr 29 May 08 Jun 15 Jun 19 Jun 1500: 01 Apr 10 May 20 May 27 May 31 May 1600: 02 Apr 11 May 21 May 28 May 01 Jun 1700: 11 Apr 20 May 30 May 06 Jun 10 Jun 1800: 13 Apr 22 May 01 Jun 08 Jun 12 Jun 1900: 15 Apr 24 May 03 Jun 10 Jun 14 Jun 2000: 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 2100: 28 Mar 06 May 16 May 23 May 27 May Year Easter Ascension Pentecost Trinity Corpus 2010: 04 Apr 13 May 23 May 30 May 03 Jun 2011: 24 Apr 02 Jun 12 Jun 19 Jun 23 Jun 2012: 08 Apr 17 May 27 May 03 Jun 07 Jun 2013: 31 Mar 09 May 19 May 26 May 30 May 2014: 20 Apr 29 May 08 Jun 15 Jun 19 Jun 2015: 05 Apr 14 May 24 May 31 May 04 Jun 2016: 27 Mar 05 May 15 May 22 May 26 May 2017: 16 Apr 25 May 04 Jun 11 Jun 15 Jun 2018: 01 Apr 10 May 20 May 27 May 31 May 2019: 21 Apr 30 May 09 Jun 16 Jun 20 Jun 2020: 12 Apr 21 May 31 May 07 Jun 11 Jun
Forth
variable year
: ea_a year @ 19 mod ;
: ea_b year @ 100 / ;
: ea_c year @ 100 mod ;
: ea_d ea_b 4 / ;
: ea_e ea_b 4 mod ;
: ea_f ea_b 8 + 25 / ;
: ea_g ea_b ea_f - 1 + 3 / ;
: ea_h 19 ea_a * ea_b + ea_d - ea_g - 15 + 30 mod ;
: ea_i ea_c 4 / ;
: ea_k ea_c 4 mod ;
: ea_l 32 2 ea_e * + 2 ea_i * + ea_h - ea_k - 7 mod ;
: ea_m ea_a 11 ea_h * + 22 ea_i * + 451 / ;
: ea_numerator ea_h ea_l + 7 ea_m * - 114 + ;
: ea_month ea_numerator 31 / ;
: ea_day ea_numerator 31 mod 1 + ;
: bs ( -- backspace )
8 emit ;
: monthname ( monthnum -- name )
case
1 of ." Jan" endof
2 of ." Feb" endof
3 of ." Mar" endof
4 of ." Apr" endof
5 of ." May" endof
6 of ." Jun" endof
7 of ." Jul" endof
8 of ." Aug" endof
9 of ." Sep" endof
10 of ." Oct" endof
11 of ." Nov" endof
12 of ." Dec" endof
dup . ." wrong input"
endcase
;
: eastern ( year -- )
dup year ! . bs ." :" space ea_day . bs space ea_month monthname ;
: main
cr .\" year: eastern" cr 2200 400
DO i eastern cr 100
+LOOP
cr 2021 2010
DO i eastern cr
LOOP
;
Output:
year: eastern 400: 2 Apr 500: 4 Apr 600: 13 Apr 700: 15 Apr 800: 23 Apr 900: 28 Mar 1000: 30 Mar 1100: 8 Apr 1200: 9 Apr 1300: 18 Apr 1400: 20 Apr 1500: 1 Apr 1600: 2 Apr 1700: 11 Apr 1800: 13 Apr 1900: 15 Apr 2000: 23 Apr 2100: 28 Mar 2010: 4 Apr 2011: 24 Apr 2012: 8 Apr 2013: 31 Mar 2014: 20 Apr 2015: 5 Apr 2016: 27 Mar 2017: 16 Apr 2018: 1 Apr 2019: 21 Apr 2020: 12 Apr
Fortran
subroutine easter(year,month,day)
c Easter sunday
c
c Input
c year
c Output
c month
c day
c
c See:
c Jean Meeus, "Astronomical Formulae for Calculators",
c 4th edition, Willmann-Bell, 1988, p.31
implicit integer(a-z)
a=mod(year,19)
b=year/100
c=mod(year,100)
d=b/4
e=mod(b,4)
f=(b+8)/25
g=(b-f+1)/3
h=mod(19*a+b-d-g+15,30)
i=c/4
k=mod(c,4)
l=mod(32+2*e+2*i-h-k,7)
m=(a+11*h+22*l)/451
n=h+l-7*m+114
month=n/31
day=mod(n,31)+1
end
FreeBASIC
#include "datetime.bi"
#include "string.bi"
Dim Shared As Integer anno, mes, dia
Type mytype
f As String*9
d As Short
End Type
Dim Shared fechas(1 To 5) As mytype => {("Easter ",0),_
("Ascension",39),("Pentecost",49),("Trinity ",56),("Corpus ",60)}
Function Pascua(anno As Short) As Double
Dim As Short a, b, c, d, e
Dim As Short f, g, h, i, k
Dim As Short l, m, n
a = anno Mod 19
b = anno \ 100
c = anno Mod 100
d = b \ 4
e = b Mod 4
f = (b + 8) \ 25
g = (b - f + 1) \ 3
h = (19 * a + b - d - g + 15) Mod 30
i = c \ 4
k = c Mod 4
l = (32 + 2 * e + 2 * i - h - k) Mod 7
m = (a + 11 * h + 22 * l) \ 451
n = h + l - 7 * m + 114
Dim As Short mes = n \ 31
Dim As Short dia = n Mod 31 + 1
Return Dateserial(anno, mes, dia)
End Function
Sub Mostar(anno As Short)
Dim As Double e = Pascua(anno)
Print Using (" #### "); anno;
For i As Short = 1 To Ubound(fechas)
Print Format(e + fechas(i).d, "dd/mmm"); Spc(3);
Next i
Print
End Sub
Print " Year Easter Ascension Pentecost Trinity C/Christi"
Print " CE Sunday Thursday Sunday Sunday Thursday "
Print " ---- ------ --------- ---------- ------- ---------"
For anno = 400 To 2100 Step 100
Mostar(anno)
Next anno
Print
For anno = 2010 To 2020
Mostar(anno)
Next anno
Sleep
- Output:
Year Easter Ascension Pentecost Trinity C/Christi CE Sunday Thursday Sunday Sunday Thursday ---- ------ --------- ---------- ------- --------- 400 02/abr. 11/may. 21/may. 28/may. 01/jun. 500 04/abr. 13/may. 23/may. 30/may. 03/jun. 600 13/abr. 22/may. 01/jun. 08/jun. 12/jun. 700 15/abr. 24/may. 03/jun. 10/jun. 14/jun. 800 23/abr. 01/jun. 11/jun. 18/jun. 22/jun. 900 28/mar. 06/may. 16/may. 23/may. 27/may. 1000 30/mar. 08/may. 18/may. 25/may. 29/may. 1100 08/abr. 17/may. 27/may. 03/jun. 07/jun. 1200 09/abr. 18/may. 28/may. 04/jun. 08/jun. 1300 18/abr. 27/may. 06/jun. 13/jun. 17/jun. 1400 20/abr. 29/may. 08/jun. 15/jun. 19/jun. 1500 01/abr. 10/may. 20/may. 27/may. 31/may. 1600 02/abr. 11/may. 21/may. 28/may. 01/jun. 1700 11/abr. 20/may. 30/may. 06/jun. 10/jun. 1800 13/abr. 22/may. 01/jun. 08/jun. 12/jun. 1900 15/abr. 24/may. 03/jun. 10/jun. 14/jun. 2000 23/abr. 01/jun. 11/jun. 18/jun. 22/jun. 2100 28/mar. 06/may. 16/may. 23/may. 27/may. 2010 04/abr. 13/may. 23/may. 30/may. 03/jun. 2011 24/abr. 02/jun. 12/jun. 19/jun. 23/jun. 2012 08/abr. 17/may. 27/may. 03/jun. 07/jun. 2013 31/mar. 09/may. 19/may. 26/may. 30/may. 2014 20/abr. 29/may. 08/jun. 15/jun. 19/jun. 2015 05/abr. 14/may. 24/may. 31/may. 04/jun. 2016 27/mar. 05/may. 15/may. 22/may. 26/may. 2017 16/abr. 25/may. 04/jun. 11/jun. 15/jun. 2018 01/abr. 10/may. 20/may. 27/may. 31/may. 2019 21/abr. 30/may. 09/jun. 16/jun. 20/jun. 2020 12/abr. 21/may. 31/may. 07/jun. 11/jun.
Fōrmulæ
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.
Programs in Fōrmulæ are created/edited online in its website.
In this page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.
Solution
This is a implementation of the "Meeus/Jones/Butcher" algorithm:
Test cases
FutureBasic
This code outputs a complete Mac application showing the Julian Easter dates from 532 to 1582 and Gregorian Easter dates thereafter, without regard to historical niceties. The Gregorian rule has no set limits, but we went up to the year 10,000,000 (note that Gregorian Easter dates repeat every 5,700,000 years, so Easter 5702023 is on the same date as Easter 2023). Calculating other moveable feasts is trivial.
begin enum 1
_window : _scroll : _showOff
_clmYear : _clmEaster : _lblYear : _lblEaster
_inField : _outField
end enum
void local fn buildInterface
window _window, @"Easter dates", ( 0, 0, 200, 200 ), 3
scrollview _scroll, ( 20, 80, 170, 91 )
textview _showOff, , _scroll
textlabel _clmYear, @"Year", ( 21, 168, 60, 22 )
textlabel _clmEaster, @"Easter", ( 92, 168, 140, 22 )
textlabel _lblYear, @"Year:", ( 40, 40, 100, 22 )
textlabel _lblEaster, @"Easter:", ( 31, 10, 100, 22 )
textlabel _outField, @"14 April", ( 87, 10, 100, 22 )
textfield _inField, , @"14250", ( 85, 42, 70, 22 )
ControlSetFormat ( _inField, @"0123456789", YES, 7, 0 )
TextSetFont( _showOff, fn FontMonospacedDigitSystemFontOfSize( 12 , 0 ) )
menu 1, , , @"File" : menu 1, 0, , @"Close", @"w"
MenuItemSetAction(1, 0, @"performClose:")
editmenu 2
WindowMakeFirstResponder( _window, _inField )
end fn
clear local fn easter( year as NSInteger) as CFStringRef
NSInteger goldenNumber, leapDays, century, epact
NSInteger moonAdjust, leapAdjust,fullMoon, easter
CFStringRef s = @""
goldenNumber = year mod 19 + 1 ' moon phase on 1 Jan
if year < 1583
// Algorithm by Dionysius Exiguus, 525
leapDays = 5 * year / 4 ' one leap year every four years
epact = ( 11 * goldenNumber - 4 ) mod 30 ' moon phase on 22 March
else
// Algorithm by Christoph Clavius, 1582 (see D. Knuth: CACM 1962;5:209)
century = int( year / 100 ) + 1
leapAdjust = int( ( 3 * century / 4 ) - 12 ) ' correct leap years
leapDays = int( 5 * year / 4 ) - leapAdjust - 10 ' new calculation of leap days
moonAdjust = int( ( 8 * century + 5 ) / 25 ) - 5 ' correct moon cycle
epact = ( 11 * goldenNumber + moonAdjust - leapAdjust + 20 ) mod 30 ' new calculation of moon phase
if epact < 0 then epact += 30
if ( epact = 24 or ( epact = 25 and goldenNumber > 11 ) ) then epact ++ ' final tweaks
end if
fullMoon = 44 - epact ' find first full moon in March
if fullMoon < 21 then fullMoon += 30 ' not before 21 March
easter = fullMoon + 7 - ( ( leapDays + fullMoon ) mod 7 ) ' find Sunday after first full moon in March
if easter < 32
s = fn StringWithFormat( @"%u March", easter )
else
s = fn StringWithFormat( @"%u April", easter - 31 )
end if
end fn = s
void local fn showOff
NSInteger year
CFMutableStringRef s = @"", t
for year = 532 to 2100 ' 532 is first year of Dionysius' tables
t = fn StringWithFormat( @"%u%@%@\n", year, @" ", fn easter( year) )
s = fn StringByAppendingString( s, t )
next
s = left( s, len( s ) - 1 ) ' cosmetic: remove last line feed
TextSetString( _showOff, s )
end fn
void local fn doEvents( evt as Long, tag as Long )
NSInteger t
select evt
case _textFieldDidChange
ControlSetStringValue ( _outField, @"" )
t = fn ControlIntegerValue( _inField )
if t > 531 then ControlSetStringValue ( _outField, fn easter( t ) )
case _windowShouldClose : end
end select
end fn
fn buildInterface
fn showOff
on dialog fn doEvents
handleevents
- Output:
Go
This solution takes the ALGOL 68 as a reference solution, using its math for calculating the holidays, and reproducing its output.
package main
import (
"fmt"
"time"
)
type holiday struct {
time.Time
}
func easter(y int) holiday {
c := y / 100
n := mod(y, 19)
i := mod(c-c/4-(c-(c-17)/25)/3+19*n+15, 30)
i -= (i / 28) * (1 - (i/28)*(29/(i+1))*((21-n)/11))
l := i - mod(y+y/4+i+2-c+c/4, 7)
m := 3 + (l+40)/44
d := l + 28 - 31*(m/4)
return holiday{time.Date(y, time.Month(m), d, 0, 0, 0, 0, time.UTC)}
}
func mod(a, n int) int {
r := a % n
if r < 0 {
return r + n
}
return r
}
func (h holiday) addDays(d int) holiday {
return holiday{h.Add(time.Duration(d) * 24 * time.Hour)}
}
type easterRelated struct {
easter, ascension, pentecost, trinity, corpusChristi holiday
}
func newEasterRelated(y int) (er easterRelated) {
er.easter = easter(y)
er.ascension = er.easter.addDays(39)
er.pentecost = er.ascension.addDays(10)
er.trinity = er.pentecost.addDays(7)
er.corpusChristi = er.trinity.addDays(4)
return
}
func (er easterRelated) print() {
const wdmdm = ": Mon _2 Jan"
fmt.Printf("%4d %s, %s, %s, %s, %s\n",
er.easter.Year(),
er.easter.Format("Easter"+wdmdm),
er.ascension.Format("Ascension"+wdmdm),
er.pentecost.Format("Pentecost"+wdmdm),
er.trinity.Format("Trinity"+wdmdm),
er.corpusChristi.Format("Corpus"+wdmdm))
}
func main() {
fmt.Println("Christian holidays, related to Easter, " +
"for each centennial from 400 to 2100 CE:")
for y := 400; y <= 2100; y += 100 {
newEasterRelated(y).print()
}
fmt.Println("\nChristian holidays, related to Easter, " +
"for years from 2010 to 2020 CE:")
for y := 2010; y <= 2020; y++ {
newEasterRelated(y).print()
}
}
Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 CE: 400 Easter: Sun 2 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 Jun 500 Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun 600 Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 1 Jun, Trinity: Sun 8 Jun, Corpus: Thu 12 Jun 700 Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 3 Jun, Trinity: Sun 10 Jun, Corpus: Thu 14 Jun 800 Easter: Sun 23 Apr, Ascension: Thu 1 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus: Thu 22 Jun 900 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 CE: 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
Icon and Unicon
This is a modified translation of the C# code with specialized (limited) date calculation procedures added.
Aside from the already noted issues and inconsistencies with extending these calculations back centuries, the calculation of the correct and proper date of Easter has historically been responsible for massive conflict in Western history including excommunications, near wars, and contributing to the splitting of the Catholic Church. For more see Calculating Easter @ Mang's Bat Page.
Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 CE: 400 Easter: Sun 2 Apr Ascension: Thu 11 May Pentecost: Sun 21 May Trinity: Sun 28 May Corpus: Thu 1 Jun 500 Easter: Sun 4 Apr Ascension: Thu 13 May Pentecost: Sun 23 May Trinity: Sun 30 May Corpus: Thu 3 Jun 600 Easter: Sun 13 Apr Ascension: Thu 22 May Pentecost: Sun 1 Jun Trinity: Sun 8 Jun Corpus: Thu 12 Jun 700 Easter: Sun 15 Apr Ascension: Thu 24 May Pentecost: Sun 3 Jun Trinity: Sun 10 Jun Corpus: Thu 14 Jun 800 Easter: Sun 23 Apr Ascension: Thu 1 Jun Pentecost: Sun 11 Jun Trinity: Sun 18 Jun Corpus: Thu 22 Jun 900 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 CE: 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
J
Issues and Ambiguities
Caution: This task is currently self-contradictory, thus consistent results are impossible. See the talk page for some further discussion of this issue.
That said, the only calendar where the specified date range can be meaningful is the Julian calendar, which is currently used by Eastern Christianity for determining when to celebrate easter.
However, Corpus Christi is a Western Catholic holiday. Then again, Corpus Christi was not celebrated anywhere prior to the 13th century and in some countries it is celebrated on a Thursday and in other countries it is celebrated on a Sunday. So I have chosen to ignore this holiday for now.
In Eastern Christianity, Trinity Sunday is the same day as Pentecost.
Julian Easters
This code is based on the above rationale, and http://www.merlyn.demon.co.uk/estr-bcp.htm and the wikipedia pages referenced in the task description:
jed=:3 :0
pfm=. 21 + 30 | _4 + 19 * 1 + 19|y
sn=. 6 - 7 | 4 + <.@*&1.25 y
dys=. 1 40 50 50 +/~sn (] + 7 | 4 + -) pfm
y,"0 1(+/\0 0 0 31 30 31 30) (I.,"0]-<:@I.{[) dys
)
Required example:
jed (400 + 100* i.17),(2010 + i.11),2100
output:
400 4 1 400 5 10 400 5 20 400 5 20 500 4 2 500 5 11 500 5 21 500 5 21 600 4 10 600 5 19 600 5 29 600 5 29 700 4 11 700 5 20 700 5 30 700 5 30 800 4 19 800 5 28 800 6 7 800 6 7 900 4 20 900 5 29 900 6 8 900 6 8 1000 3 31 1000 5 9 1000 5 19 1000 5 19 1100 4 1 1100 5 10 1100 5 20 1100 5 20 1200 4 9 1200 5 18 1200 5 28 1200 5 28 1300 4 10 1300 5 19 1300 5 29 1300 5 29 1400 4 18 1400 5 27 1400 6 6 1400 6 6 1500 4 19 1500 5 28 1500 6 7 1500 6 7 1600 3 23 1600 5 1 1600 5 11 1600 5 11 1700 3 31 1700 5 9 1700 5 19 1700 5 19 1800 4 8 1800 5 17 1800 5 27 1800 5 27 1900 4 9 1900 5 18 1900 5 28 1900 5 28 2000 4 17 2000 5 26 2000 6 5 2000 6 5 2010 3 22 2010 4 30 2010 5 10 2010 5 10 2011 4 11 2011 5 20 2011 5 30 2011 5 30 2012 4 2 2012 5 11 2012 5 21 2012 5 21 2013 4 22 2013 5 31 2013 6 10 2013 6 10 2014 4 7 2014 5 16 2014 5 26 2014 5 26 2015 3 30 2015 5 8 2015 5 18 2015 5 18 2016 4 18 2016 5 27 2016 6 6 2016 6 6 2017 4 3 2017 5 12 2017 5 22 2017 5 22 2018 3 26 2018 5 4 2018 5 14 2018 5 14 2019 4 15 2019 5 24 2019 6 3 2019 6 3 2020 4 6 2020 5 15 2020 5 25 2020 5 25 2100 4 18 2100 5 27 2100 6 6 2100 6 6
Gregorian Easters
Other entries on this page are showing gregorian easter results despite the nonsensical character of those results (for example, no country celebrated easter using the Gregorian calendar before 1583).
Nevertheless, here is an implementation which reproduces those numbers, based on the same resource I used for the Julian easters:
ged=:3 :0
ce =. <. y%100
GN =. 1 + 19 | y
CY =. 30 | 23 + (<.4 %~ 3 * ce+1) - <. 25 %~ 13 + ce*8
YR =. 400 | y
SN =. 6 - 7 | 6 + YR + (<. YR%4) - <. YR%100
dm =. 21 + 30 | 3 + CY + 19*GN
DM =. dm - 49 < dm+11 < GN
dys=. 0 39 49 56 60 +/~ DM + 1 + 7 | 60+SN-DM
y,"0 1(+/\0 0 0 31 30 31 30) (I.,"0]-<:@I.{[) dys
)
And here is the required example (and note that I am including the same Corpus Christi feast date here that others are using, because that makes sense with recent Gregorian dates even though it is a nonsense value for earlier dates):
ged (400 + 100* i.17),(2010 + i.11),2100
output (in each block of dates, they are, in order Easter, Ascension Thursday, Pentecost, Trinity Sunday, and Corpus Christi feast):
400 4 2 400 5 11 400 5 21 400 5 28 400 6 1 500 4 4 500 5 13 500 5 23 500 5 30 500 6 3 600 4 13 600 5 22 600 6 1 600 6 8 600 6 12 700 4 15 700 5 24 700 6 3 700 6 10 700 6 14 800 4 23 800 6 1 800 6 11 800 6 18 800 6 22 900 3 28 900 5 6 900 5 16 900 5 23 900 5 27 1000 3 30 1000 5 8 1000 5 18 1000 5 25 1000 5 29 1100 4 8 1100 5 17 1100 5 27 1100 6 3 1100 6 7 1200 4 9 1200 5 18 1200 5 28 1200 6 4 1200 6 8 1300 4 18 1300 5 27 1300 6 6 1300 6 13 1300 6 17 1400 4 20 1400 5 29 1400 6 8 1400 6 15 1400 6 19 1500 4 1 1500 5 10 1500 5 20 1500 5 27 1500 5 31 1600 4 2 1600 5 11 1600 5 21 1600 5 28 1600 6 1 1700 4 11 1700 5 20 1700 5 30 1700 6 6 1700 6 10 1800 4 13 1800 5 22 1800 6 1 1800 6 8 1800 6 12 1900 4 15 1900 5 24 1900 6 3 1900 6 10 1900 6 14 2000 4 23 2000 6 1 2000 6 11 2000 6 18 2000 6 22 2010 4 4 2010 5 13 2010 5 23 2010 5 30 2010 6 3 2011 4 24 2011 6 2 2011 6 12 2011 6 19 2011 6 23 2012 4 8 2012 5 17 2012 5 27 2012 6 3 2012 6 7 2013 3 31 2013 5 9 2013 5 19 2013 5 26 2013 5 30 2014 4 20 2014 5 29 2014 6 8 2014 6 15 2014 6 19 2015 4 5 2015 5 14 2015 5 24 2015 5 31 2015 6 4 2016 3 27 2016 5 5 2016 5 15 2016 5 22 2016 5 26 2017 4 16 2017 5 25 2017 6 4 2017 6 11 2017 6 15 2018 4 1 2018 5 10 2018 5 20 2018 5 27 2018 5 31 2019 4 21 2019 5 30 2019 6 9 2019 6 16 2019 6 20 2020 4 12 2020 5 21 2020 5 31 2020 6 7 2020 6 11 2100 3 28 2100 5 6 2100 5 16 2100 5 23 2100 5 27
Java
Translation of C Sharp via D
import java.text.DateFormatSymbols;
import java.util.*;
public class EasterRelatedHolidays {
final static Map<String, Integer> holidayOffsets;
static {
holidayOffsets = new LinkedHashMap<>();
holidayOffsets.put("Easter", 0);
holidayOffsets.put("Ascension", 39);
holidayOffsets.put("Pentecost", 10);
holidayOffsets.put("Trinity", 7);
holidayOffsets.put("Corpus", 4);
}
public static void main(String[] args) {
System.out.println("Christian holidays, related to Easter,"
+ " for each centennial from 400 to 2100 CE:");
for (int y = 400; y <= 2100; y += 100)
printEasterRelatedHolidays(y);
System.out.println("\nChristian holidays, related to Easter,"
+ " for years from 2010 to 2020 CE:");
for (int y = 2010; y < 2021; y++)
printEasterRelatedHolidays(y);
}
static void printEasterRelatedHolidays(int year) {
final int a = year % 19;
final int b = year / 100;
final int c = year % 100;
final int d = b / 4;
final int e = b % 4;
final int f = (b + 8) / 25;
final int g = (b - f + 1) / 3;
final int h = (19 * a + b - d - g + 15) % 30;
final int i = c / 4;
final int k = c % 4;
final int l = (32 + 2 * e + 2 * i - h - k) % 7;
final int m = (a + 11 * h + 22 * l) / 451;
final int n = h + l - 7 * m + 114;
final int month = n / 31 - 1;
final int day = (n % 31) + 1;
Calendar date = new GregorianCalendar(year, month, day);
String[] months = new DateFormatSymbols(Locale.US).getShortMonths();
System.out.printf("%4d ", year);
for (String hd : holidayOffsets.keySet()) {
date.add(Calendar.DATE, holidayOffsets.get(hd));
System.out.printf("%s: %2d %s ", hd,
date.get(Calendar.DAY_OF_MONTH),
months[date.get(Calendar.MONTH)]);
}
System.out.println();
}
}
Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 CE: 400 Easter: 2 Apr Ascension: 11 May Pentecost: 21 May Trinity: 28 May Corpus: 1 Jun 500 Easter: 4 Apr Ascension: 13 May Pentecost: 23 May Trinity: 30 May Corpus: 3 Jun 600 Easter: 13 Apr Ascension: 22 May Pentecost: 1 Jun Trinity: 8 Jun Corpus: 12 Jun 700 Easter: 15 Apr Ascension: 24 May Pentecost: 3 Jun Trinity: 10 Jun Corpus: 14 Jun 800 Easter: 23 Apr Ascension: 1 Jun Pentecost: 11 Jun Trinity: 18 Jun Corpus: 22 Jun 900 Easter: 28 Mar Ascension: 6 May Pentecost: 16 May Trinity: 23 May Corpus: 27 May 1000 Easter: 30 Mar Ascension: 8 May Pentecost: 18 May Trinity: 25 May Corpus: 29 May 1100 Easter: 8 Apr Ascension: 17 May Pentecost: 27 May Trinity: 3 Jun Corpus: 7 Jun 1200 Easter: 9 Apr Ascension: 18 May Pentecost: 28 May Trinity: 4 Jun Corpus: 8 Jun 1300 Easter: 18 Apr Ascension: 27 May Pentecost: 6 Jun Trinity: 13 Jun Corpus: 17 Jun 1400 Easter: 20 Apr Ascension: 29 May Pentecost: 8 Jun Trinity: 15 Jun Corpus: 19 Jun 1500 Easter: 1 Apr Ascension: 10 May Pentecost: 20 May Trinity: 27 May Corpus: 31 May 1600 Easter: 2 Apr Ascension: 11 May Pentecost: 21 May Trinity: 28 May Corpus: 1 Jun 1700 Easter: 11 Apr Ascension: 20 May Pentecost: 30 May Trinity: 6 Jun Corpus: 10 Jun 1800 Easter: 13 Apr Ascension: 22 May Pentecost: 1 Jun Trinity: 8 Jun Corpus: 12 Jun 1900 Easter: 15 Apr Ascension: 24 May Pentecost: 3 Jun Trinity: 10 Jun Corpus: 14 Jun 2000 Easter: 23 Apr Ascension: 1 Jun Pentecost: 11 Jun Trinity: 18 Jun Corpus: 22 Jun 2100 Easter: 28 Mar Ascension: 6 May Pentecost: 16 May Trinity: 23 May Corpus: 27 May Christian holidays, related to Easter, for years from 2010 to 2020 CE: 2010 Easter: 4 Apr Ascension: 13 May Pentecost: 23 May Trinity: 30 May Corpus: 3 Jun 2011 Easter: 24 Apr Ascension: 2 Jun Pentecost: 12 Jun Trinity: 19 Jun Corpus: 23 Jun 2012 Easter: 8 Apr Ascension: 17 May Pentecost: 27 May Trinity: 3 Jun Corpus: 7 Jun 2013 Easter: 31 Mar Ascension: 9 May Pentecost: 19 May Trinity: 26 May Corpus: 30 May 2014 Easter: 20 Apr Ascension: 29 May Pentecost: 8 Jun Trinity: 15 Jun Corpus: 19 Jun 2015 Easter: 5 Apr Ascension: 14 May Pentecost: 24 May Trinity: 31 May Corpus: 4 Jun 2016 Easter: 27 Mar Ascension: 5 May Pentecost: 15 May Trinity: 22 May Corpus: 26 May 2017 Easter: 16 Apr Ascension: 25 May Pentecost: 4 Jun Trinity: 11 Jun Corpus: 15 Jun 2018 Easter: 1 Apr Ascension: 10 May Pentecost: 20 May Trinity: 27 May Corpus: 31 May 2019 Easter: 21 Apr Ascension: 30 May Pentecost: 9 Jun Trinity: 16 Jun Corpus: 20 Jun 2020 Easter: 12 Apr Ascension: 21 May Pentecost: 31 May Trinity: 7 Jun Corpus: 11 Jun
JavaScript
(English version courtesy of google translate below)
const Пасха = год => {
let дата = (год % 19 * 19 + 15) % 30;
дата += (год % 4 * 2 + год % 7 * 4 + 6 * дата + 6) % 7;
if (год >= 1918) дата += (год / 100 | 0) - (год / 400 | 0) - 2;
return new Date(год, 2, 22 + дата);
};
for (let год = 400; год <= 2100; год += год < 2000 ? 100 : год >= 2020 ? 80 : год < 2010 ? 10 : 1) {
const дата_Пасхи = Пасха(год);
document.write(
год + ": " +
[ ["Easter", 1], ["Ascension", 40], ["Trinity (Pentecost)", 50], ["All Saints' Sunday", 57] ].map(праздник => {
let дата = new Date(дата_Пасхи);
дата.setDate(дата.getDate() + праздник[1] - 1);
return праздник[0] + ": " + new Intl.DateTimeFormat("ru", { month: "numeric", day: "numeric" }).format(дата);
}).join("; ") + ".<br />"
);
}
Output:
400: Easter: 01.04; Ascension: 10.05; Trinity (Pentecost): 20.05; All Saints' Sunday: 27.05. 500: Easter: 02.04; Ascension: 11.05; Trinity (Pentecost): 21.05; All Saints' Sunday: 28.05. 600: Easter: 10.04; Ascension: 19.05; Trinity (Pentecost): 29.05; All Saints' Sunday: 05.06. 700: Easter: 11.04; Ascension: 20.05; Trinity (Pentecost): 30.05; All Saints' Sunday: 06.06. 800: Easter: 19.04; Ascension: 28.05; Trinity (Pentecost): 07.06; All Saints' Sunday: 14.06. 900: Easter: 20.04; Ascension: 29.05; Trinity (Pentecost): 08.06; All Saints' Sunday: 15.06. 1000: Easter: 31.03; Ascension: 09.05; Trinity (Pentecost): 19.05; All Saints' Sunday: 26.05. 1100: Easter: 01.04; Ascension: 10.05; Trinity (Pentecost): 20.05; All Saints' Sunday: 27.05. 1200: Easter: 09.04; Ascension: 18.05; Trinity (Pentecost): 28.05; All Saints' Sunday: 04.06. 1300: Easter: 10.04; Ascension: 19.05; Trinity (Pentecost): 29.05; All Saints' Sunday: 05.06. 1400: Easter: 18.04; Ascension: 27.05; Trinity (Pentecost): 06.06; All Saints' Sunday: 13.06. 1500: Easter: 19.04; Ascension: 28.05; Trinity (Pentecost): 07.06; All Saints' Sunday: 14.06. 1600: Easter: 23.03; Ascension: 01.05; Trinity (Pentecost): 11.05; All Saints' Sunday: 18.05. 1700: Easter: 31.03; Ascension: 09.05; Trinity (Pentecost): 19.05; All Saints' Sunday: 26.05. 1800: Easter: 08.04; Ascension: 17.05; Trinity (Pentecost): 27.05; All Saints' Sunday: 03.06. 1900: Easter: 09.04; Ascension: 18.05; Trinity (Pentecost): 28.05; All Saints' Sunday: 04.06. 2000: Easter: 30.04; Ascension: 08.06; Trinity (Pentecost): 18.06; All Saints' Sunday: 25.06. 2010: Easter: 04.04; Ascension: 13.05; Trinity (Pentecost): 23.05; All Saints' Sunday: 30.05. 2011: Easter: 24.04; Ascension: 02.06; Trinity (Pentecost): 12.06; All Saints' Sunday: 19.06. 2012: Easter: 15.04; Ascension: 24.05; Trinity (Pentecost): 03.06; All Saints' Sunday: 10.06. 2013: Easter: 05.05; Ascension: 13.06; Trinity (Pentecost): 23.06; All Saints' Sunday: 30.06. 2014: Easter: 20.04; Ascension: 29.05; Trinity (Pentecost): 08.06; All Saints' Sunday: 15.06. 2015: Easter: 12.04; Ascension: 21.05; Trinity (Pentecost): 31.05; All Saints' Sunday: 07.06. 2016: Easter: 01.05; Ascension: 09.06; Trinity (Pentecost): 19.06; All Saints' Sunday: 26.06. 2017: Easter: 16.04; Ascension: 25.05; Trinity (Pentecost): 04.06; All Saints' Sunday: 11.06. 2018: Easter: 08.04; Ascension: 17.05; Trinity (Pentecost): 27.05; All Saints' Sunday: 03.06. 2019: Easter: 28.04; Ascension: 06.06; Trinity (Pentecost): 16.06; All Saints' Sunday: 23.06. 2020: Easter: 19.04; Ascension: 28.05; Trinity (Pentecost): 07.06; All Saints' Sunday: 14.06. 2100: Easter: 02.05; Ascension: 10.06; Trinity (Pentecost): 20.06; All Saints' Sunday: 27.06.
English version
(same output)
const Easter = year => {
let date = (year % 19 * 19 + 15) % 30;
date += (year % 4 * 2 + year % 7 * 4 + 6 * date + 6) % 7;
if (year >= 1918) date += (year / 100 | 0) - (year / 400 | 0) - 2;
return new Date(year, 2, 22 + date);
};
for (let year = 400; year <= 2100; year += year < 2000 ? 100 : year >= 2020 ? 80 : year < 2010 ? 10 : 1) {
const Easter_Date = Easter(year);
document.write(
year + ": " +
[ ["Easter", 1], ["Ascension", 40], ["Trinity (Pentecost)", 50], ["All Saints' Sunday", 57] ].map(holiday => {
let date = new Date(Easter_Date);
date.setDate(date.getDate() + holiday[1] - 1);
return holiday[0] + ": " + new Intl.DateTimeFormat("ru", { month: "numeric", day: "numeric" }).format(date);
}).join("; ") + ".<br />"
);
}
Universal algorithm
function getEasterDate(year = new Date().getFullYear(), church = 1, calendar = year < 1918 ? 1 : 2) {
/* year: a number of the year (from 325 CE);
church: an algorithm of the computus,
for Orthodox = 1; for Catholic = 2;
calendar: a calendar of the output date,
Julian = 1; Gregorian = 2. */
if (church == 1) {
let d = (year % 19 * 19 + 15) % 30;
d += (year % 4 * 2 + year % 7 * 4 + 6 * d + 6) % 7;
if (calendar == 1)
return d > 9 ? [d - 9, 4] : [22 + d, 3];
else if (calendar == 2) {
const c = (year / 100 | 0) - (year / 400 | 0) - 2;
return d > 39 - c ? [d - 39 + c, 5] : [d - 9 + c, 4];
}
}
else if (church == 2) {
const
a = year % 19, b = year / 100 | 0, c = year % 100,
d = (19 * a + b - (b / 4 | 0) - ((b - ((b + 8) / 25 | 0) + 1) / 3 | 0) + 15) % 30,
e = (32 + 2 * (b % 4) + 2 * (c / 4 | 0) - d - c % 4) % 7,
f = d + e - 7 * ((a + 11 * d + 22 * e) / 451 | 0) + 114;
if (calendar == 1) {
const
g = f % 31 + 1,
h = (year / 100 | 0) - (year / 400 | 0) - 2;
return g <= h ? [31 + g - h, 3] : [g - h, f / 31 | 0];
}
else if (calendar == 2)
return [f % 31 + 1, f / 31 | 0];
}
}
const
OrthodoxHolidays = [["Easter", 1], ["Ascension", 40], ["Trinity (Pentecost)", 50], ["All Saints' Sunday", 57]],
CatholicHolidays = [["Easter", 1], ["Ascension", 40], ["Pentecost", 50], ["Trinity Sunday", 57], ["Corpus Christi", 61]];
const firstYearOfNewStyle = 1918;
function getHolidaysDates(year = new Date().getFullYear(), church = 1) {
const
Easter = getEasterDate(year, church, year < firstYearOfNewStyle ? 1 : 2),
holidays = church == 1 ? OrthodoxHolidays : CatholicHolidays;
return year + ": " +
holidays.map(h => {
const d = new Date(year, Easter[1] - 1, Easter[0]);
d.setDate(d.getDate() + h[1] - 1);
return h[0] + ": " + new Intl.DateTimeFormat("ru", { month: "numeric", day: "numeric" }).format(d);
}).join("; ") + ".";
}
for (let year = 400; year <= 2100; year += year < 2000 ? 100 : year >= 2021 ? 80 : year < 2010 ? 10 : 1)
document.write(getHolidaysDates(year, 1) + " <br />");
jq
Works with gojq, the Go implementation of jq
Also works with fq, a Go implementation of a large subset of jq
Adapted from Wren
This entry uses jq's `mktime` and `gmtime` functions. Unfortunately, the implementation of `mktime` in the C implementation of jq does not currently (jq 1.6) support years before 1900.
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
# add the number of days to [year, month, day]
def addDays($days):
. as [$y,$m,$d]
| [$y,$m,$d + $days,0,0,0,0,0] | mktime | gmtime ;
# Output: [year, month_indexed_by_0, day]
def calculateEaster:
. as $year
| {}
| .a = $year % 19
| .b = (($year / 100)|floor)
| .c = $year % 100
| .d = ((.b / 4)|floor)
| .e = .b % 4
| .f = (((.b + 8) / 25)|floor)
| .g = (((.b - .f + 1) / 3)|floor)
| .h = (19 * .a + .b - .d - .g + 15) % 30
| .i = ((.c / 4)|floor)
| .k = .c % 4
| .l = (32 + 2 * .e + 2 * .i - .h - .k) % 7
| .m = (((.a + 11 * .h + 22 * .l) / 451)|floor)
| .n = .h + .l - 7 * .m + 114
| .month = ((.n / 31)|floor) # months indexed from 1
| .day = (.n % 31) + 1
| [$year, .month - 1, .day] ;
def holidayOffsets: [
["Easter", 0],
["Ascension", 39],
["Pentecost", 49],
["Trinity", 56],
["C/Christi", 60]
];
# Input: year
def outputHolidays:
calculateEaster as $date
| holidayOffsets[] as [$h, $o]
| $date | addDays($o) | strftime("%d %b") ;
def tables:
def row: "\(lpad(4)) \([outputHolidays] | join(" "))";
"Year Easter Ascension Pentecost Trinity C/Christi",
" CE Sunday Thursday Sunday Sunday Thursday ",
"---- ------ --------- --------- ------- ---------",
( range(400; 2101; 100) | row),
"",
( range(2010; 2021) | row) ;
tables
Invocation: gojq -nr -f holidays-related-to-easter.jq
- Output:
Except for whitespace, the output is identical to that shown in the Wren entry.
Julia
# v0.6
using Dates
function easter(year::Int)::Date
a = rem(year, 19)
b, c = divrem(year, 100)
d = rem(19a + b - div(b, 4) - div(b - div(b + 8, 25) + 1, 3) + 15, 30)
e = rem(32 + 2 * rem(b, 4) + 2 * div(c, 4) - d - rem(c, 4), 7)
f = d + e - 7 * div(a + 11d + 22e, 451) + 114
month, day = divrem(f, 31)
day += 1
return Date(year, month, day)
end
function holiday_values(year::Int)::Dict{String,Date}
offsets = Dict{String,Day}("Easter" => Day(0), "Ascension" => Day(39),
"Pentecost" => Day(49), "Trinity" => Day(56), "Corpus" => Day(60))
easterdate = easter(year)
rst = Dict{String,Date}(holiday => easterdate + days for (holiday, days) in offsets)
return rst
end
function holiday2str(year::Int)::String
function holiday2str(holiday::String, date::Date)::String
dayname, daynumb, month = dayabbr(date), day(date), monthabbr(date)
return @sprintf "%s: %s %2i %s" holiday dayname daynumb month
end
cal = holiday_values(year)
rst = join(collect(holiday2str(hday, cal[hday]) for hday in
("Easter", "Ascension", "Pentecost", "Trinity", "Corpus")), ", ")
return "$year -> " * rst
end
println("\nChristian holidays, related to Easter, for each centennial from 400 to 2100 CE:")
for yr in 400:100:2200
println(holiday2str(yr))
end
println("\nChristian holidays, related to Easter, for years from 2010 to 2020 CE:")
for yr in 2010:2020
println(holiday2str(yr))
end
- Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 CE: 400 -> Easter: Sun 2 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 Jun 500 -> Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun 600 -> Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 1 Jun, Trinity: Sun 8 Jun, Corpus: Thu 12 Jun 700 -> Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 3 Jun, Trinity: Sun 10 Jun, Corpus: Thu 14 Jun 800 -> Easter: Sun 23 Apr, Ascension: Thu 1 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus: Thu 22 Jun 900 -> 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 2200 -> Easter: Sun 6 Apr, Ascension: Thu 15 May, Pentecost: Sun 25 May, Trinity: Sun 1 Jun, Corpus: Thu 5 Jun Christian holidays, related to Easter, for years from 2010 to 2020 CE: 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
Kotlin
// version 1.1.2
import java.util.Calendar
import java.util.GregorianCalendar
val holidayOffsets = listOf(
"Easter" to 0,
"Ascension" to 39,
"Pentecost" to 49,
"Trinity" to 56,
"C/Christi" to 60
)
fun String.padCenter(n: Int): String {
val len = this.length
if (n <= len) return this
return this.padStart((n + len) / 2).padEnd(n)
}
fun calculateEaster(year: Int): GregorianCalendar {
val a = year % 19
val b = year / 100
val c = year % 100
val d = b / 4
val e = b % 4
val f = (b + 8) / 25
val g = (b - f + 1) / 3
val h = (19 * a + b - d - g + 15) % 30
val i = c / 4
val k = c % 4
val l = (32 + 2 * e + 2 * i - h - k) % 7
val m = (a + 11 * h + 22 * l) / 451
val n = h + l - 7 * m + 114
val month = n / 31 - 1 // months indexed from 0
val day = (n % 31) + 1
return GregorianCalendar(year, month, day)
}
fun outputHolidays(year: Int) {
val date = calculateEaster(year)
print("%4d ".format(year))
var po = 0
for ((h, o) in holidayOffsets) {
date.add(Calendar.DATE, o - po)
po = o
print("${"%1\$td %1\$tb".format(date).padCenter(h.length)} ")
}
println()
}
fun main(args: Array<String>) {
println("Year Easter Ascension Pentecost Trinity C/Christi")
println(" CE Sunday Thursday Sunday Sunday Thursday ")
println("---- ------ --------- --------- ------- ---------")
for (year in 400..2100 step 100) outputHolidays(year)
println()
for (year in 2010..2020) outputHolidays(year)
}
- Output:
Year Easter Ascension Pentecost Trinity C/Christi CE Sunday Thursday Sunday Sunday Thursday ---- ------ --------- --------- ------- --------- 400 02 Apr 11 May 21 May 28 May 01 Jun 500 04 Apr 13 May 23 May 30 May 03 Jun 600 13 Apr 22 May 01 Jun 08 Jun 12 Jun 700 15 Apr 24 May 03 Jun 10 Jun 14 Jun 800 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 900 28 Mar 06 May 16 May 23 May 27 May 1000 30 Mar 08 May 18 May 25 May 29 May 1100 08 Apr 17 May 27 May 03 Jun 07 Jun 1200 09 Apr 18 May 28 May 04 Jun 08 Jun 1300 18 Apr 27 May 06 Jun 13 Jun 17 Jun 1400 20 Apr 29 May 08 Jun 15 Jun 19 Jun 1500 01 Apr 10 May 20 May 27 May 31 May 1600 02 Apr 11 May 21 May 28 May 01 Jun 1700 11 Apr 20 May 30 May 06 Jun 10 Jun 1800 13 Apr 22 May 01 Jun 08 Jun 12 Jun 1900 15 Apr 24 May 03 Jun 10 Jun 14 Jun 2000 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 2100 28 Mar 06 May 16 May 23 May 27 May 2010 04 Apr 13 May 23 May 30 May 03 Jun 2011 24 Apr 02 Jun 12 Jun 19 Jun 23 Jun 2012 08 Apr 17 May 27 May 03 Jun 07 Jun 2013 31 Mar 09 May 19 May 26 May 30 May 2014 20 Apr 29 May 08 Jun 15 Jun 19 Jun 2015 05 Apr 14 May 24 May 31 May 04 Jun 2016 27 Mar 05 May 15 May 22 May 26 May 2017 16 Apr 25 May 04 Jun 11 Jun 15 Jun 2018 01 Apr 10 May 20 May 27 May 31 May 2019 21 Apr 30 May 09 Jun 16 Jun 20 Jun 2020 12 Apr 21 May 31 May 07 Jun 11 Jun
Lua
The function 'easter' is a Lua translation of a C function by Claus Tøndering. This script relies heavily on the 'time' library, available from scilua.org. Dates before 1582 are not supported.
local Time = require("time")
function div (x, y) return math.floor(x / y) end
function easter (year)
local G = year % 19
local C = div(year, 100)
local H = (C - div(C, 4) - div((8 * C + 13), 25) + 19 * G + 15) % 30
local I = H - div(H, 28) * (1 - div(29, H + 1)) * (div(21 - G, 11))
local J = (year + div(year, 4) + I + 2 - C + div(C, 4)) % 7
local L = I - J
local month = 3 + div(L + 40, 44)
return month, L + 28 - 31 * div(month, 4)
end
function holidays (year)
local dates = {}
dates.easter = Time.date(year, easter(year))
dates.ascension = dates.easter + Time.days(39)
dates.pentecost = dates.easter + Time.days(49)
dates.trinity = dates.easter + Time.days(56)
dates.corpus = dates.easter + Time.days(60)
return dates
end
function puts (...)
for k, v in pairs{...} do io.write(tostring(v):sub(6, 10), "\t") end
end
function show (year, d)
io.write(year, "\t")
puts(d.easter, d.ascension, d.pentecost, d.trinity, d.corpus)
print()
end
print("Year\tEaster\tAscen.\tPent.\tTrinity\tCorpus")
for year = 1600, 2100, 100 do show(year, holidays(year)) end
for year = 2010, 2020 do show(year, holidays(year)) end
Output:
Year Easter Ascen. Pent. Trinity Corpus 1600 04-02 05-11 05-21 05-28 06-01 1700 04-11 05-20 05-30 06-06 06-10 1800 04-13 05-22 06-01 06-08 06-12 1900 04-15 05-24 06-03 06-10 06-14 2000 04-23 06-01 06-11 06-18 06-22 2100 03-28 05-06 05-16 05-23 05-27 2010 04-04 05-13 05-23 05-30 06-03 2011 04-24 06-02 06-12 06-19 06-23 2012 04-08 05-17 05-27 06-03 06-07 2013 03-31 05-09 05-19 05-26 05-30 2014 04-20 05-29 06-08 06-15 06-19 2015 04-05 05-14 05-24 05-31 06-04 2016 03-27 05-05 05-15 05-22 05-26 2017 04-16 05-25 06-04 06-11 06-15 2018 04-01 05-10 05-20 05-27 05-31 2019 04-21 05-30 06-09 06-16 06-20 2020 04-12 05-21 05-31 06-07 06-11
Mathematica /Wolfram Language
Needs["Calendar`"];DateFormat[x_]:=DateString[x,{"DayNameShort"," ","DayShort"," ","MonthName"}]
Map[StringJoin[ToString[#]," Easter: ",DateFormat[EasterSunday[#]],
", Ascension: ",DateFormat[DaysPlus[EasterSunday[#],39]],
", Pentecost: ",DateFormat[DaysPlus[EasterSunday[#],49]],
", Trinity: ",DateFormat[DaysPlus[EasterSunday[#],56]],
", Corpus: ",DateFormat[DaysPlus[EasterSunday[#],60]]]&
,Range[400,2100,100]~Join~Range[2010,2020]]
Output
{400 Easter: Sun 2 April, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 June,
500 Easter: Sun 4 April, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 June,
600 Easter: Sun 13 April, Ascension: Thu 22 May, Pentecost: Sun 1 June, Trinity: Sun 8 June, Corpus: Thu 12 June,
700 Easter: Sun 15 April, Ascension: Thu 24 May, Pentecost: Sun 3 June, Trinity: Sun 10 June, Corpus: Thu 14 June,
800 Easter: Sun 23 April, Ascension: Thu 1 June, Pentecost: Sun 11 June, Trinity: Sun 18 June, Corpus: Thu 22 June,
900 Easter: Sun 28 March, Ascension: Thu 6 May, Pentecost: Sun 16 May, Trinity: Sun 23 May, Corpus: Thu 27 May,
1000 Easter: Sun 30 March, Ascension: Thu 8 May, Pentecost: Sun 18 May, Trinity: Sun 25 May, Corpus: Thu 29 May,
1100 Easter: Sun 8 April, Ascension: Thu 17 May, Pentecost: Sun 27 May, Trinity: Sun 3 June, Corpus: Thu 7 June,
1200 Easter: Sun 9 April, Ascension: Thu 18 May, Pentecost: Sun 28 May, Trinity: Sun 4 June, Corpus: Thu 8 June,
1300 Easter: Sun 18 April, Ascension: Thu 27 May, Pentecost: Sun 6 June, Trinity: Sun 13 June, Corpus: Thu 17 June,
1400 Easter: Sun 20 April, Ascension: Thu 29 May, Pentecost: Sun 8 June, Trinity: Sun 15 June, Corpus: Thu 19 June,
1500 Easter: Sun 1 April, Ascension: Thu 10 May, Pentecost: Sun 20 May, Trinity: Sun 27 May, Corpus: Thu 31 May,
1600 Easter: Sun 2 April, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 June,
1700 Easter: Sun 11 April, Ascension: Thu 20 May, Pentecost: Sun 30 May, Trinity: Sun 6 June, Corpus: Thu 10 June,
1800 Easter: Sun 13 April, Ascension: Thu 22 May, Pentecost: Sun 1 June, Trinity: Sun 8 June, Corpus: Thu 12 June,
1900 Easter: Sun 15 April, Ascension: Thu 24 May, Pentecost: Sun 3 June, Trinity: Sun 10 June, Corpus: Thu 14 June,
2000 Easter: Sun 23 April, Ascension: Thu 1 June, Pentecost: Sun 11 June, Trinity: Sun 18 June, Corpus: Thu 22 June,
2100 Easter: Sun 28 March, Ascension: Thu 6 May, Pentecost: Sun 16 May, Trinity: Sun 23 May, Corpus: Thu 27 May,
2010 Easter: Sun 4 April, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 June,
2011 Easter: Sun 24 April, Ascension: Thu 2 June, Pentecost: Sun 12 June, Trinity: Sun 19 June, Corpus: Thu 23 June,
2012 Easter: Sun 8 April, Ascension: Thu 17 May, Pentecost: Sun 27 May, Trinity: Sun 3 June, Corpus: Thu 7 June,
2013 Easter: Sun 31 March, Ascension: Thu 9 May, Pentecost: Sun 19 May, Trinity: Sun 26 May, Corpus: Thu 30 May,
2014 Easter: Sun 20 April, Ascension: Thu 29 May, Pentecost: Sun 8 June, Trinity: Sun 15 June, Corpus: Thu 19 June,
2015 Easter: Sun 5 April, Ascension: Thu 14 May, Pentecost: Sun 24 May, Trinity: Sun 31 May, Corpus: Thu 4 June,
2016 Easter: Sun 27 March, Ascension: Thu 5 May, Pentecost: Sun 15 May, Trinity: Sun 22 May, Corpus: Thu 26 May,
2017 Easter: Sun 16 April, Ascension: Thu 25 May, Pentecost: Sun 4 June, Trinity: Sun 11 June, Corpus: Thu 15 June,
2018 Easter: Sun 1 April, Ascension: Thu 10 May, Pentecost: Sun 20 May, Trinity: Sun 27 May, Corpus: Thu 31 May,
2019 Easter: Sun 21 April, Ascension: Thu 30 May, Pentecost: Sun 9 June, Trinity: Sun 16 June, Corpus: Thu 20 June,
2020 Easter: Sun 12 April, Ascension: Thu 21 May, Pentecost: Sun 31 May, Trinity: Sun 7 June, Corpus: Thu 11 June}
Maxima
/* Easter sunday. Result is a list [month, day]
See:
Jean Meeus, "Astronomical Formulae for Calculators",
4th edition, Willmann-Bell, 1988, p.31 */
easter_sunday(year):=block([a,b,c,d,e,f,g,h,i,k,l,m,n,p],
a:remainder(year,19),[b,c]:divide(year,100),[d,e]:divide(b,4),
f:quotient(b+8,25),g:quotient(b-f+1,3),h:remainder(19*a+b-d-g+15,30),
[i,k]:divide(c,4),l:remainder(32+2*e+2*i-h-k,7),m:quotient(a+11*h+22*l,451),
[n,p]:divide(h+l-7*m+114,31),[n,p+1])$
МК-61/52
П2 1 9 ПП 90 П3 ИП2 4 ПП 90
П4 ИП2 7 ПП 90 П5 1 9 ИП3 *
1 5 + 3 0 ПП 90 П6 2 ИП4
* 4 ИП5 * + 6 ИП6 * + 6
+ 7 ПП 90 ИП6 + П1 3 П4 ИП2
1 - 2 10^x / [x] ^ ^ 4 /
[x] - 2 0 + ИП1 + П3 3 1
- /-/ x<0 78 |x| П3 KИП4 ИП3 3 0
- /-/ x<0 87 |x| П3 KИП4 ИП3 ИП4 С/П
П0 <-> П1 <-> / [x] ИП0 * ИП1 -
/-/ В/О
Enter the number of the year, the result of: the day in the register Y, a month in the register X.
For the subsequent calculation of Ascension and Pentecost (Trinity Day):
П0 <-> П1 <-> - 1 3 + П1 3
1 - /-/ x<0 21 |x| П1 ИП0 1 +
П0 ИП0 1 + П0 ИП1 ИП0 С/П ИП1 1
0 + П1 3 1 - /-/ x<0 45 |x|
П1 ИП0 1 + П0 ИП1 ИП0 С/П
Example: Easter in 2014 is 20.04; Ascension is 29.05; Pentecost is 08.06.
To calculate the dates of holidays of western heretics (catholics, protestants, other sectarians), it is necessary to replace the coefficients 15 on the address 20 and 6 on the address 39 by: 22 and 2 for the 16th and 17th centuries; 23 and 3 for 18th; 23 and 4 for 19th; 24 and 5 for 20th and 21th; 25 and 6 for 22th century, etc.
Nim
import strformat, strutils, times
const HolidayOffsets = {"Easter": 0, "Ascension": 39, "Pentecost": 49,
"Trinity": 56, "C/Christi": 60}
proc easterDate(year: int): DateTime =
let a = year mod 19
let b = year div 100
let c = year mod 100
let d = b div 4
let e = b mod 4
let f = (b + 8) div 25
let g = (b - f + 1) div 3
let h = (19 * a + b - d - g + 15) mod 30
let i = c div 4
let k = c mod 4
let l = (32 + 2 * e + 2 * i - h - k) mod 7
let m = (a + 11 * h + 22 * l) div 451
let n = h + l - 7 * m + 114
let month = n div 31
let day = n mod 31 + 1
result = initDateTime(day, Month(month), year, 0, 0, 0)
proc outputHolidays(year: int) =
let edate = easterDate(year)
stdout.write &"{year:4d} "
for (holiday, offset) in HolidayOffsets:
let date = edate + initDuration(days = offset)
let s = date.format("dd MMM").center(holiday.len)
stdout.write &"{s} "
echo ""
echo "Year Easter Ascension Pentecost Trinity C/Christi"
echo " CE Sunday Thursday Sunday Sunday Thursday "
echo "---- ------ --------- ---------- ------- ---------"
for year in countup(400, 2100, 100): outputHolidays(year)
echo ""
for year in 2010..2020: outputHolidays(year)
- Output:
Year Easter Ascension Pentecost Trinity C/Christi CE Sunday Thursday Sunday Sunday Thursday ---- ------ --------- ---------- ------- --------- 400 02 Apr 11 May 21 May 28 May 01 Jun 500 04 Apr 13 May 23 May 30 May 03 Jun 600 13 Apr 22 May 01 Jun 08 Jun 12 Jun 700 15 Apr 24 May 03 Jun 10 Jun 14 Jun 800 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 900 28 Mar 06 May 16 May 23 May 27 May 1000 30 Mar 08 May 18 May 25 May 29 May 1100 08 Apr 17 May 27 May 03 Jun 07 Jun 1200 09 Apr 18 May 28 May 04 Jun 08 Jun 1300 18 Apr 27 May 06 Jun 13 Jun 17 Jun 1400 20 Apr 29 May 08 Jun 15 Jun 19 Jun 1500 01 Apr 10 May 20 May 27 May 31 May 1600 02 Apr 11 May 21 May 28 May 01 Jun 1700 11 Apr 20 May 30 May 06 Jun 10 Jun 1800 13 Apr 22 May 01 Jun 08 Jun 12 Jun 1900 15 Apr 24 May 03 Jun 10 Jun 14 Jun 2000 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 2100 28 Mar 06 May 16 May 23 May 27 May 2010 04 Apr 13 May 23 May 30 May 03 Jun 2011 24 Apr 02 Jun 12 Jun 19 Jun 23 Jun 2012 08 Apr 17 May 27 May 03 Jun 07 Jun 2013 31 Mar 09 May 19 May 26 May 30 May 2014 20 Apr 29 May 08 Jun 15 Jun 19 Jun 2015 05 Apr 14 May 24 May 31 May 04 Jun 2016 27 Mar 05 May 15 May 22 May 26 May 2017 16 Apr 25 May 04 Jun 11 Jun 15 Jun 2018 01 Apr 10 May 20 May 27 May 31 May 2019 21 Apr 30 May 09 Jun 16 Jun 20 Jun 2020 12 Apr 21 May 31 May 07 Jun 11 Jun
PARI/GP
Code handles Gregorian / Julian holidays and dates correctly. Calendar reform was 1582-10-04.
/*
* Normalized Julian Day Number from date (base 1899-12-30 00:00:00)
* D = Vec [year, month, day]
* return day number
*/
njd(D) =
{
my (m, y);
if (D[2] > 2, y = D[1]; m = D[2] + 1, y = D[1] - 1; m = D[2] + 13);
(1461 * y) \ 4 + (306001 * m) \ 10000 + D[3] - 694024
/* Calendar reform ? */
+ if (100 * (100 * D[1] + D[2]) + D[3] > 15821004, 2 - y \ 100 + y \ 400)
}
/*
* Date from Normalized Julian Day Number (base 1899-12-30 00:00:00)
* n = Normalized Julian Day Number
* return Vec [year, month, day]
*/
njdate(n) =
{
my (a = n + 2415019, b, c, d, m, D, M, Y);
/* Calendar reform ? */
if (a >= 2299161, b = (4 * a - 7468865) \ 146097; a += 1 + b - b \ 4);
a += 1524;
b = (20 * a - 2442) \ 7305;
c = (1461 * b) \ 4;
d = ((a - c) * 10000) \ 306001;
m = d - 1 - 12 * (d > 13);
[b - 4715 - (m > 2), m, a - c - (306001 * d) \ 10000]
}
/*
* Date of Easter
* Y = year
* return Vec [year, month, day]
*/
easter(y) =
{
my (a, b, d, m);
if (y > 1582, /* calendar reform ? */
/* Gregorian Easter */
a = y % 19;
b = y % 100;
d = y \ 100;
m = (19 * a + d - d \ 4 - (d - (d + 8) \ 25 + 1) \ 3 + 15) % 30;
d = (32 + (d % 4) * 2 + (b \ 4) * 2 - m - b % 4) % 7;
m += d - (a + 11 * m + 22 * d) \ 451 * 7 + 114;
,
/* Julian Easter */
d = ((y % 19) * 19 + 15) % 30;
m = d + ((y % 4) * 2 + (y % 7) * 4 - d + 34) % 7 + 114;
);
[y, m \ 31, m % 31 + 1]
}
holiday(y) =
{
my (e = njd(easter(y)), n);
n = njdate(e ); printf("%4d: Easter: %02d-%02d, ", y, n[2], n[3]);
n = njdate(e+39); printf("Ascension: %02d-%02d, ", n[2], n[3]);
n = njdate(e+49); printf("Pentecost: %02d-%02d, ", n[2], n[3]);
n = njdate(e+56); printf("Trinity: %02d-%02d, ", n[2], n[3]);
n = njdate(e+60); printf("Corpus: %02d-%02d\n", n[2], n[3]);
}
print("Christian holidays, related to Easter, for years from 400 to 2100 CE:");
forstep (y = 400, 2100, 100, holiday(y));
print("\nChristian holidays, related to Easter, for years from 2010 to 2020 CE:");
for (y = 2010, 2020, holiday(y));
Output:
Christian holidays, related to Easter, for years from 400 to 2100 CE: 400: Easter: 04-01, Ascension: 05-10, Pentecost: 05-20, Trinity: 05-27, Corpus: 05-31 500: Easter: 04-02, Ascension: 05-11, Pentecost: 05-21, Trinity: 05-28, Corpus: 06-01 600: Easter: 04-10, Ascension: 05-19, Pentecost: 05-29, Trinity: 06-05, Corpus: 06-09 700: Easter: 04-11, Ascension: 05-20, Pentecost: 05-30, Trinity: 06-06, Corpus: 06-10 800: Easter: 04-19, Ascension: 05-28, Pentecost: 06-07, Trinity: 06-14, Corpus: 06-18 900: Easter: 04-20, Ascension: 05-29, Pentecost: 06-08, Trinity: 06-15, Corpus: 06-19 1000: Easter: 03-31, Ascension: 05-09, Pentecost: 05-19, Trinity: 05-26, Corpus: 05-30 1100: Easter: 04-01, Ascension: 05-10, Pentecost: 05-20, Trinity: 05-27, Corpus: 05-31 1200: Easter: 04-09, Ascension: 05-18, Pentecost: 05-28, Trinity: 06-04, Corpus: 06-08 1300: Easter: 04-10, Ascension: 05-19, Pentecost: 05-29, Trinity: 06-05, Corpus: 06-09 1400: Easter: 04-18, Ascension: 05-27, Pentecost: 06-06, Trinity: 06-13, Corpus: 06-17 1500: Easter: 04-19, Ascension: 05-28, Pentecost: 06-07, Trinity: 06-14, Corpus: 06-18 1600: Easter: 04-02, Ascension: 05-11, Pentecost: 05-21, Trinity: 05-28, Corpus: 06-01 1700: Easter: 04-11, Ascension: 05-20, Pentecost: 05-30, Trinity: 06-06, Corpus: 06-10 1800: Easter: 04-13, Ascension: 05-22, Pentecost: 06-01, Trinity: 06-08, Corpus: 06-12 1900: Easter: 04-15, Ascension: 05-24, Pentecost: 06-03, Trinity: 06-10, Corpus: 06-14 2000: Easter: 04-23, Ascension: 06-01, Pentecost: 06-11, Trinity: 06-18, Corpus: 06-22 2100: Easter: 03-28, Ascension: 05-06, Pentecost: 05-16, Trinity: 05-23, Corpus: 05-27 Christian holidays, related to Easter, for years from 2010 to 2020 CE: 2010: Easter: 04-04, Ascension: 05-13, Pentecost: 05-23, Trinity: 05-30, Corpus: 06-03 2011: Easter: 04-24, Ascension: 06-02, Pentecost: 06-12, Trinity: 06-19, Corpus: 06-23 2012: Easter: 04-08, Ascension: 05-17, Pentecost: 05-27, Trinity: 06-03, Corpus: 06-07 2013: Easter: 03-31, Ascension: 05-09, Pentecost: 05-19, Trinity: 05-26, Corpus: 05-30 2014: Easter: 04-20, Ascension: 05-29, Pentecost: 06-08, Trinity: 06-15, Corpus: 06-19 2015: Easter: 04-05, Ascension: 05-14, Pentecost: 05-24, Trinity: 05-31, Corpus: 06-04 2016: Easter: 03-27, Ascension: 05-05, Pentecost: 05-15, Trinity: 05-22, Corpus: 05-26 2017: Easter: 04-16, Ascension: 05-25, Pentecost: 06-04, Trinity: 06-11, Corpus: 06-15 2018: Easter: 04-01, Ascension: 05-10, Pentecost: 05-20, Trinity: 05-27, Corpus: 05-31 2019: Easter: 04-21, Ascension: 05-30, Pentecost: 06-09, Trinity: 06-16, Corpus: 06-20 2020: Easter: 04-12, Ascension: 05-21, Pentecost: 05-31, Trinity: 06-07, Corpus: 06-11
Perl
#!/usr/bin/perl
use strict; use warnings;
use Date::Calc qw(:all);
my @abbr = qw( Not Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
my %c_hols = (
Easter=> 0,
Ascension=> 39,
Pentecost=> 49,
Trinity=> 56,
Corpus=> 60
);
sub easter {
my $year=shift;
my $ay=$year % 19;
my $by=int($year / 100);
my $cy=$year % 100;
my $dy=int($by/4);
my $ey=$by % 4;
my $fy=int(($by+8)/25);
my $gy=int(($by-$fy+1)/3);
my $hy=($ay*19+$by-$dy-$gy+15) % 30;
my $iy=int($cy/4);
my $ky=$cy % 4;
my $ly=(32+2*$ey+2*$iy-$hy-$ky) % 7;
my $m_y=int(($ay+11*$hy+22*$ly)/451);
my $month=int(($hy+$ly-7*$m_y+114)/31);
my $day=(($hy+$ly-7*$m_y+114) % 31)+1;
return ($month, $day, $year);
}
sub cholidays {
my $year=shift;
my ($emon, $eday)=easter($year);
my @fields;
printf("%4s: ", $year);
foreach my $hol (sort { $c_hols{$a}<=>$c_hols{$b} } keys %c_hols) {
my ($ye,$mo,$da)=Add_Delta_Days($year,$emon,$eday,$c_hols{$hol});
my $month=$abbr[$mo];
push @fields, sprintf("%s: %02s %s",$hol,$da,$month);
}
print join (", ",@fields);
print "\n";
}
print "Christian holidays, related to Easter, for each centennial from ",
"400 to 2100 CE:\n";
for (my $year=400; $year<=2100; $year+=100) {
cholidays($year);
}
print "Christian holidays, related to Easter, ",
"for years from 2010 to 2020 CE:\n";
cholidays($_) for(2010..2020);
Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 CE: 400: Easter: 02 Apr, Ascension: 11 May, Pentecost: 21 May, Trinity: 28 May, Corpus: 01 Jun 500: Easter: 04 Apr, Ascension: 13 May, Pentecost: 23 May, Trinity: 30 May, Corpus: 03 Jun 600: Easter: 13 Apr, Ascension: 22 May, Pentecost: 01 Jun, Trinity: 08 Jun, Corpus: 12 Jun 700: Easter: 15 Apr, Ascension: 24 May, Pentecost: 03 Jun, Trinity: 10 Jun, Corpus: 14 Jun 800: Easter: 23 Apr, Ascension: 01 Jun, Pentecost: 11 Jun, Trinity: 18 Jun, Corpus: 22 Jun 900: Easter: 28 Mar, Ascension: 06 May, Pentecost: 16 May, Trinity: 23 May, Corpus: 27 May 1000: Easter: 30 Mar, Ascension: 08 May, Pentecost: 18 May, Trinity: 25 May, Corpus: 29 May 1100: Easter: 08 Apr, Ascension: 17 May, Pentecost: 27 May, Trinity: 03 Jun, Corpus: 07 Jun 1200: Easter: 09 Apr, Ascension: 18 May, Pentecost: 28 May, Trinity: 04 Jun, Corpus: 08 Jun 1300: Easter: 18 Apr, Ascension: 27 May, Pentecost: 06 Jun, Trinity: 13 Jun, Corpus: 17 Jun 1400: Easter: 20 Apr, Ascension: 29 May, Pentecost: 08 Jun, Trinity: 15 Jun, Corpus: 19 Jun 1500: Easter: 01 Apr, Ascension: 10 May, Pentecost: 20 May, Trinity: 27 May, Corpus: 31 May 1600: Easter: 02 Apr, Ascension: 11 May, Pentecost: 21 May, Trinity: 28 May, Corpus: 01 Jun 1700: Easter: 11 Apr, Ascension: 20 May, Pentecost: 30 May, Trinity: 06 Jun, Corpus: 10 Jun 1800: Easter: 13 Apr, Ascension: 22 May, Pentecost: 01 Jun, Trinity: 08 Jun, Corpus: 12 Jun 1900: Easter: 15 Apr, Ascension: 24 May, Pentecost: 03 Jun, Trinity: 10 Jun, Corpus: 14 Jun 2000: Easter: 23 Apr, Ascension: 01 Jun, Pentecost: 11 Jun, Trinity: 18 Jun, Corpus: 22 Jun 2100: Easter: 28 Mar, Ascension: 06 May, Pentecost: 16 May, Trinity: 23 May, Corpus: 27 May Christian holidays, related to Easter, for years from 2010 to 2020 CE: 2010: Easter: 04 Apr, Ascension: 13 May, Pentecost: 23 May, Trinity: 30 May, Corpus: 03 Jun 2011: Easter: 24 Apr, Ascension: 02 Jun, Pentecost: 12 Jun, Trinity: 19 Jun, Corpus: 23 Jun 2012: Easter: 08 Apr, Ascension: 17 May, Pentecost: 27 May, Trinity: 03 Jun, Corpus: 07 Jun 2013: Easter: 31 Mar, Ascension: 09 May, Pentecost: 19 May, Trinity: 26 May, Corpus: 30 May 2014: Easter: 20 Apr, Ascension: 29 May, Pentecost: 08 Jun, Trinity: 15 Jun, Corpus: 19 Jun 2015: Easter: 05 Apr, Ascension: 14 May, Pentecost: 24 May, Trinity: 31 May, Corpus: 04 Jun 2016: Easter: 27 Mar, Ascension: 05 May, Pentecost: 15 May, Trinity: 22 May, Corpus: 26 May 2017: Easter: 16 Apr, Ascension: 25 May, Pentecost: 04 Jun, Trinity: 11 Jun, Corpus: 15 Jun 2018: Easter: 01 Apr, Ascension: 10 May, Pentecost: 20 May, Trinity: 27 May, Corpus: 31 May 2019: Easter: 21 Apr, Ascension: 30 May, Pentecost: 09 Jun, Trinity: 16 Jun, Corpus: 20 Jun 2020: Easter: 12 Apr, Ascension: 21 May, Pentecost: 31 May, Trinity: 07 Jun, Corpus: 11 Jun
Phix
The Phix timedate routines make no attempt to support pre-1752 dates, but the algorithm seems to work.
(Note: that pre-1752 part got itself broken on 0.8.1, but is back working on the as-yet-unreleased 0.8.2)
-- demo\rosetta\Easter.exw function easter(integer year) -- from https://en.wikipedia.org/wiki/Computus#Anonymous_Gregorian_algorithm integer a = mod(year,19), b = floor(year/100), c = mod(year,100), d = floor(b/4), e = mod(b,4), f = floor((b+8)/25), g = floor((b-f+1)/3), h = mod(19*a+b-d-g+15,30), i = floor(c/4), k = mod(c,4), l = mod(32+2*e+2*i-h-k,7), m = floor((a+11*h+22*l)/451), n = h+l-7*m+114, month = floor(n/31), day = mod(n,31)+1 return {year,month,day,0,0,0,0,0,0} end function constant dates = {{"Easter ",0}, {"Ascension",39}, {"Pentecost",49}, {"Trinity ",56}, {"Corpus ",60}} constant fmt = join(repeat(" %12s",length(dates))), fmt0 = " "&fmt&"\n", fmtN = "%4d"&fmt&"\n" include builtins\timedate.e set_timedate_formats({"Ddd ddth Mmm"}) procedure show(integer year) if year=0 then printf(1,fmt0, columnize(dates,1)[1]) else timedate e = easter(year) sequence args = {year} for i=1 to length(dates) do string d = format_timedate(adjust_timedate(e,timedelta(days:=dates[i][2]))) args = append(args,d) end for printf(1,fmtN, args) end if end procedure show(0) for year=400 to 2100 by 100 do show(year) end for show(0) for year=2010 to 2020 do show(year) end for
- Output:
Easter Ascension Pentecost Trinity Corpus 400 Sun 02nd Apr Thu 11th May Sun 21st May Sun 28th May Thu 01st Jun 500 Sun 04th Apr Thu 13th May Sun 23rd May Sun 30th May Thu 03rd Jun 600 Sun 13th Apr Thu 22nd May Sun 01st Jun Sun 08th Jun Thu 12th Jun 700 Sun 15th Apr Thu 24th May Sun 03rd Jun Sun 10th Jun Thu 14th Jun 800 Sun 23rd Apr Thu 01st Jun Sun 11th Jun Sun 18th Jun Thu 22nd Jun 900 Sun 28th Mar Thu 06th May Sun 16th May Sun 23rd May Thu 27th May 1000 Sun 30th Mar Thu 08th May Sun 18th May Sun 25th May Thu 29th May 1100 Sun 08th Apr Thu 17th May Sun 27th May Sun 03rd Jun Thu 07th Jun 1200 Sun 09th Apr Thu 18th May Sun 28th May Sun 04th Jun Thu 08th Jun 1300 Sun 18th Apr Thu 27th May Sun 06th Jun Sun 13th Jun Thu 17th Jun 1400 Sun 20th Apr Thu 29th May Sun 08th Jun Sun 15th Jun Thu 19th Jun 1500 Sun 01st Apr Thu 10th May Sun 20th May Sun 27th May Thu 31st May 1600 Sun 02nd Apr Thu 11th May Sun 21st May Sun 28th May Thu 01st Jun 1700 Sun 11th Apr Thu 20th May Sun 30th May Sun 06th Jun Thu 10th Jun 1800 Sun 13th Apr Thu 22nd May Sun 01st Jun Sun 08th Jun Thu 12th Jun 1900 Sun 15th Apr Thu 24th May Sun 03rd Jun Sun 10th Jun Thu 14th Jun 2000 Sun 23rd Apr Thu 01st Jun Sun 11th Jun Sun 18th Jun Thu 22nd Jun 2100 Sun 28th Mar Thu 06th May Sun 16th May Sun 23rd May Thu 27th May Easter Ascension Pentecost Trinity Corpus 2010 Sun 04th Apr Thu 13th May Sun 23rd May Sun 30th May Thu 03rd Jun 2011 Sun 24th Apr Thu 02nd Jun Sun 12th Jun Sun 19th Jun Thu 23rd Jun 2012 Sun 08th Apr Thu 17th May Sun 27th May Sun 03rd Jun Thu 07th Jun 2013 Sun 31st Mar Thu 09th May Sun 19th May Sun 26th May Thu 30th May 2014 Sun 20th Apr Thu 29th May Sun 08th Jun Sun 15th Jun Thu 19th Jun 2015 Sun 05th Apr Thu 14th May Sun 24th May Sun 31st May Thu 04th Jun 2016 Sun 27th Mar Thu 05th May Sun 15th May Sun 22nd May Thu 26th May 2017 Sun 16th Apr Thu 25th May Sun 04th Jun Sun 11th Jun Thu 15th Jun 2018 Sun 01st Apr Thu 10th May Sun 20th May Sun 27th May Thu 31st May 2019 Sun 21st Apr Thu 30th May Sun 09th Jun Sun 16th Jun Thu 20th Jun 2020 Sun 12th Apr Thu 21st May Sun 31st May Sun 07th Jun Thu 11th Jun
PicoLisp
(load "@lib/cal.l") # For 'easter' function
(de dayMon (Dat)
(let D (date Dat)
(list (day Dat *Day) " " (align 2 (caddr D)) " " (get *Mon (cadr D))) ) )
(for Y (append (range 400 2100 100) (range 2010 2020))
(let E (easter Y)
(prinl
(align 4 Y)
" Easter: " (dayMon E)
", Ascension: " (dayMon (+ E 39))
", Pentecost: " (dayMon (+ E 49))
", Trinity: " (dayMon (+ E 56))
", Corpus: " (dayMon (+ E 60)) ) ) )
Output:
400 Easter: Sun 2 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 Jun 500 Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun 600 Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 1 Jun, Trinity: Sun 8 Jun, Corpus: Thu 12 Jun 700 Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 3 Jun, Trinity: Sun 10 Jun, Corpus: Thu 14 Jun 800 Easter: Sun 23 Apr, Ascension: Thu 1 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus: Thu 22 Jun 900 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 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
PL/I
(subscriptrange, size, fofl):
Easter: procedure options (main);
declare months(12) character (9) varying static initial (
'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December');
declare (year, month, day) fixed binary;
do year = 2000 to 2020;
call Easter_Sunday (year, month, day);
put skip edit ('In ', year, ' Easter occurs on ', day, ' of ', months(month))
(a, f(4), a, f(2), a, a);
end;
/* Given the year, this procedure computes the month and day when Easter Sunday falls. */
Easter_Sunday: procedure (year,month,day);
/*
See:
Jean Meeus, "Astronomical Formulae for Calculators",
4th edition, Willmann-Bell, 1988, p.31
*/
declare (year nonassignable, month, day) fixed binary;
declare (a, b, c, d, e, f, g, h, i, j, k, l, m, n) fixed binary;
a = mod(year, 19);
b = year/100;
c = mod(year, 100);
d = b/4;
e = mod(b,4);
f = (b+8)/25;
g = (b-f+1)/3;
h = mod(19*a+b-d-g+15, 30);
i = c/4;
k = mod(c,4);
l = mod(32+2*e+2*i-h-k, 7);
m = (a+11*h+22*l)/451;
n = h+l-7*m+114;
month = n/31;
day = mod(n, 31)+1;
end Easter_Sunday;
end Easter;
Results:
In 2000 Easter occurs on 23 of April In 2001 Easter occurs on 15 of April In 2002 Easter occurs on 31 of March In 2003 Easter occurs on 20 of April In 2004 Easter occurs on 11 of April In 2005 Easter occurs on 27 of March In 2006 Easter occurs on 16 of April In 2007 Easter occurs on 8 of April In 2008 Easter occurs on 23 of March In 2009 Easter occurs on 12 of April In 2010 Easter occurs on 4 of April In 2011 Easter occurs on 24 of April In 2012 Easter occurs on 8 of April In 2013 Easter occurs on 31 of March In 2014 Easter occurs on 20 of April In 2015 Easter occurs on 5 of April In 2016 Easter occurs on 27 of March In 2017 Easter occurs on 16 of April In 2018 Easter occurs on 1 of April In 2019 Easter occurs on 21 of April In 2020 Easter occurs on 12 of April
PowerShell
function Get-Easter
{
[CmdletBinding()]
[OutputType([PSCustomObject])]
Param
(
[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[int]
$Year
)
Begin
{
$holidayOffset = [ordered]@{
Easter = 0
Ascension = 39
Pentecost = 49
Trinity = 56
Corpus = 60
}
function Get-DateOfEaster ([int]$Year)
{
[int]$a = $Year % 19
[int]$b = [Math]::Truncate($Year / 100)
[int]$c = $Year % 100
[int]$d = [Math]::Truncate($b / 4)
[int]$e = $b % 4
[int]$f = [Math]::Truncate(($b + 8) / 25)
[int]$g = [Math]::Truncate(($b - $f + 1) / 3)
[int]$h = ((19 * $a) + $b - $d - $g + 15) % 30
[int]$i = [Math]::Truncate($c / 4)
[int]$j = $c % 4
[int]$k = (32 + 2 * ($e + $i) - $h - $j) % 7
[int]$l = [Math]::Truncate(($a + (11 * $h) + (22 * $k)) / 451)
[int]$m = [Math]::Truncate(($h + $k - (7 * $l) + 114) / 31)
[int]$d = (($h + $k - (7 * $l) + 114) % 31) + 1
Get-Date -Year $Year -Month $m -Day $d
}
function Get-Holiday ([int]$Year)
{
$easter = Get-DateOfEaster -Year $Year
$holidays = foreach ($key in $holidayOffset.Keys)
{
$easter.AddDays($holidayOffset.$key)
}
[PSCustomObject]@{
Year = $Year
Easter = $holidays[0].ToString("ddd dd MMM")
Ascension = $holidays[1].ToString("ddd dd MMM")
Pentecost = $holidays[2].ToString("ddd dd MMM")
Trinity = $holidays[3].ToString("ddd dd MMM")
Corpus = $holidays[4].ToString("ddd dd MMM")
}
}
}
Process
{
foreach ($y in $Year)
{
Get-Holiday -Year $y
}
}
}
$years = for ($i = 400; $i -le 2100; $i+=100) {$i}
$years0400to2100 = $years | Get-Easter
$years2010to2020 = 2010..2020 | Get-Easter
Write-Host "Christian holidays, related to Easter, for each centennial from 400 to 2100 AD:"
$years0400to2100 | Format-Table
Write-Host "Christian holidays, related to Easter, for years from 2010 to 2020 AD:"
$years2010to2020 | Format-Table
- Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 AD: Year Easter Ascension Pentecost Trinity Corpus ---- ------ --------- --------- ------- ------ 400 Sun 02 Apr Thu 11 May Sun 21 May Sun 28 May Thu 01 Jun 500 Sun 04 Apr Thu 13 May Sun 23 May Sun 30 May Thu 03 Jun 600 Sun 13 Apr Thu 22 May Sun 01 Jun Sun 08 Jun Thu 12 Jun 700 Sun 15 Apr Thu 24 May Sun 03 Jun Sun 10 Jun Thu 14 Jun 800 Sun 23 Apr Thu 01 Jun Sun 11 Jun Sun 18 Jun Thu 22 Jun 900 Sun 28 Mar Thu 06 May Sun 16 May Sun 23 May Thu 27 May 1000 Sun 30 Mar Thu 08 May Sun 18 May Sun 25 May Thu 29 May 1100 Sun 08 Apr Thu 17 May Sun 27 May Sun 03 Jun Thu 07 Jun 1200 Sun 09 Apr Thu 18 May Sun 28 May Sun 04 Jun Thu 08 Jun 1300 Sun 18 Apr Thu 27 May Sun 06 Jun Sun 13 Jun Thu 17 Jun 1400 Sun 20 Apr Thu 29 May Sun 08 Jun Sun 15 Jun Thu 19 Jun 1500 Sun 01 Apr Thu 10 May Sun 20 May Sun 27 May Thu 31 May 1600 Sun 02 Apr Thu 11 May Sun 21 May Sun 28 May Thu 01 Jun 1700 Sun 11 Apr Thu 20 May Sun 30 May Sun 06 Jun Thu 10 Jun 1800 Sun 13 Apr Thu 22 May Sun 01 Jun Sun 08 Jun Thu 12 Jun 1900 Sun 15 Apr Thu 24 May Sun 03 Jun Sun 10 Jun Thu 14 Jun 2000 Sun 23 Apr Thu 01 Jun Sun 11 Jun Sun 18 Jun Thu 22 Jun 2100 Sun 28 Mar Thu 06 May Sun 16 May Sun 23 May Thu 27 May Christian holidays, related to Easter, for years from 2010 to 2020 AD: Year Easter Ascension Pentecost Trinity Corpus ---- ------ --------- --------- ------- ------ 2010 Sun 04 Apr Thu 13 May Sun 23 May Sun 30 May Thu 03 Jun 2011 Sun 24 Apr Thu 02 Jun Sun 12 Jun Sun 19 Jun Thu 23 Jun 2012 Sun 08 Apr Thu 17 May Sun 27 May Sun 03 Jun Thu 07 Jun 2013 Sun 31 Mar Thu 09 May Sun 19 May Sun 26 May Thu 30 May 2014 Sun 20 Apr Thu 29 May Sun 08 Jun Sun 15 Jun Thu 19 Jun 2015 Sun 05 Apr Thu 14 May Sun 24 May Sun 31 May Thu 04 Jun 2016 Sun 27 Mar Thu 05 May Sun 15 May Sun 22 May Thu 26 May 2017 Sun 16 Apr Thu 25 May Sun 04 Jun Sun 11 Jun Thu 15 Jun 2018 Sun 01 Apr Thu 10 May Sun 20 May Sun 27 May Thu 31 May 2019 Sun 21 Apr Thu 30 May Sun 09 Jun Sun 16 Jun Thu 20 Jun 2020 Sun 12 Apr Thu 21 May Sun 31 May Sun 07 Jun Thu 11 Jun
PureBasic
DataSection
C_DAYS:
Data.i 0,39,49,56,60
END_C_DAYS:
DAYS_MT:
Data.i 0,31,28,31,30,31,30,31,31,30,31,30,31
END_DAYS_MT:
EndDataSection
Dim m.s{3}(12) : PokeS(@m(),"___JanFebMarAprMayJunJulAugSepOctNovDec")
Dim dom.i(12) : CopyMemory(?DAYS_MT,@dom(),?END_DAYS_MT-?DAYS_MT)
Structure tDate : yyyy.i : mm.i : dd.i : EndStructure
Define.tDate DateTime, BufDateTime
Procedure.b IsLeap(y.i)
ProcedureReturn Bool( y % 4 = 0 ) & Bool( y % 100 <> 0 ) | Bool( y % 400 = 0 )
EndProcedure
Procedure.i DayOfMt(mm.i,yyyy.i)
Shared dom()
If mm=2 And IsLeap(yyyy) : ProcedureReturn 29 : Else : ProcedureReturn dom(mm) : EndIf
EndProcedure
Procedure delta(*pDate.tDate,AddDays.i)
*pDate\dd+AddDays
dom.i=DayOfMt(*pDate\mm,*pDate\yyyy)
While *pDate\dd-dom>0
*pDate\mm+1
If *pDate\mm>12 : *pDate\mm=1 : *pDate\yyyy+1 : EndIf
*pDate\dd-dom
dom=DayOfMt(*pDate\mm,*pDate\yyyy)
Wend
EndProcedure
Procedure dt(y.i)
a.i=y%19
b.i=y/100
c.i=y%100
d.i=b/4
e.i=b%4
f.i=(b+8)/25
g.i=(b-f+1)/3
h.i=(19*a+b-d-g+15)%30
i.i=c/4
k.i=c%4
l.i=(32+2*e+2*i-h-k)%7
m.i=(a+11*h+22*l)/451
num.i=h+l-7*m+114
mt.i=num/31
dy.i=(num%31)+1
Shared DateTime
DateTime\yyyy=y
DateTime\mm=mt
DateTime\dd=dy
EndProcedure
Macro PutTab(i)
dt(i) : BufDateTime=DateTime : r$=RSet(Str(DateTime\yyyy),4)
*p_C_Days=?C_DAYS
While *p_C_Days<?END_C_DAYS
delta(@DateTime,PeekI(*p_C_Days))
r$+Space(5)+RSet(Str(DateTime\dd),2,"0")+" "+m(DateTime\mm)
DateTime=BufDateTime
*p_C_Days+SizeOf(Integer)
Wend
EndMacro
OpenConsole()
PrintN("Year"+Space(5)+"Easter Ascension Pentecost Trinity C/Christi")
PrintN(" CE "+Space(5)+"Sunday Thursday Sunday Sunday Thursday")
PrintN("----"+Space(5)+"------ --------- ---------- ------- ---------")
For i=400 To 2100 Step 100 : PutTab(i) : PrintN(r$) : Next
PrintN("")
For i=2010 To 2020 : PutTab(i) : PrintN(r$) : Next
Input()
- Output:
Year Easter Ascension Pentecost Trinity C/Christi CE Sunday Thursday Sunday Sunday Thursday ---- ------ --------- ---------- ------- --------- 400 02 Apr 11 May 21 May 28 May 01 Jun 500 04 Apr 13 May 23 May 30 May 03 Jun 600 13 Apr 22 May 01 Jun 08 Jun 12 Jun 700 15 Apr 24 May 03 Jun 10 Jun 14 Jun 800 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 900 28 Mar 06 May 16 May 23 May 27 May 1000 30 Mar 08 May 18 May 25 May 29 May 1100 08 Apr 17 May 27 May 03 Jun 07 Jun 1200 09 Apr 18 May 28 May 04 Jun 08 Jun 1300 18 Apr 27 May 06 Jun 13 Jun 17 Jun 1400 20 Apr 29 May 08 Jun 15 Jun 19 Jun 1500 01 Apr 10 May 20 May 27 May 31 May 1600 02 Apr 11 May 21 May 28 May 01 Jun 1700 11 Apr 20 May 30 May 06 Jun 10 Jun 1800 13 Apr 22 May 01 Jun 08 Jun 12 Jun 1900 15 Apr 24 May 03 Jun 10 Jun 14 Jun 2000 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 2100 28 Mar 06 May 16 May 23 May 27 May 2010 04 Apr 13 May 23 May 30 May 03 Jun 2011 24 Apr 02 Jun 12 Jun 19 Jun 23 Jun 2012 08 Apr 17 May 27 May 03 Jun 07 Jun 2013 31 Mar 09 May 19 May 26 May 30 May 2014 20 Apr 29 May 08 Jun 15 Jun 19 Jun 2015 05 Apr 14 May 24 May 31 May 04 Jun 2016 27 Mar 05 May 15 May 22 May 26 May 2017 16 Apr 25 May 04 Jun 11 Jun 15 Jun 2018 01 Apr 10 May 20 May 27 May 31 May 2019 21 Apr 30 May 09 Jun 16 Jun 20 Jun 2020 12 Apr 21 May 31 May 07 Jun 11 Jun
Python
Unfortunately, at present Python doesn't support date formatting for any dates before 1900. So while it is trivial to get the date for easter, it takes a bit more work to format the date.
from dateutil.easter import *
import datetime, calendar
class Holiday(object):
def __init__(self, date, offset=0):
self.holiday = date + datetime.timedelta(days=offset)
def __str__(self):
dayofweek = calendar.day_name[self.holiday.weekday()][0:3]
month = calendar.month_name[self.holiday.month][0:3]
return '{0} {1:2d} {2}'.format(dayofweek, self.holiday.day, month)
def get_holiday_values(year):
holidays = {'year': year}
easterDate = easter(year)
holidays['easter'] = Holiday(easterDate)
holidays['ascension'] = Holiday(easterDate, 39)
holidays['pentecost'] = Holiday(easterDate, 49)
holidays['trinity'] = Holiday(easterDate, 56)
holidays['corpus'] = Holiday(easterDate, 60)
return holidays
def print_holidays(holidays):
print '{year:4d} Easter: {easter}, Ascension: {ascension}, Pentecost: {pentecost}, Trinity: {trinity}, Corpus: {corpus}'.format(**holidays)
if __name__ == "__main__":
print "Christian holidays, related to Easter, for each centennial from 400 to 2100 CE:"
for year in range(400, 2200, 100):
print_holidays(get_holiday_values(year))
print ''
print "Christian holidays, related to Easter, for years from 2010 to 2020 CE:"
for year in range(2010, 2021):
print_holidays(get_holiday_values(year))
Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 CE: 400 Easter: Sun 2 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 Jun 500 Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun 600 Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 1 Jun, Trinity: Sun 8 Jun, Corpus: Thu 12 Jun 700 Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 3 Jun, Trinity: Sun 10 Jun, Corpus: Thu 14 Jun 800 Easter: Sun 23 Apr, Ascension: Thu 1 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus: Thu 22 Jun 900 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 CE: 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
Quackery
Julian calendar for dates prior to 1583CE, Gregorian calendar thereafter.
[ dup 19 mod 19 *
15 + 30 mod
swap dup 4 mod 2 *
swap 7 mod 4 * +
over - 34 + 7 mod +
114 + 31 /mod 1+ ] is julian ( y --> m d )
[ dup 19 mod 19 *
over 100 / +
over 400 / -
swap 100 / 8 * 13 +
25 / - 15 + 30 mod ] is hge ( y --> n )
[ dup 100 / 4 mod 2 * 32 +
over 100 mod 4 / 2 * +
over hge -
swap 4 mod - 7 mod ] is lge ( y --> n )
[ dup 19 mod
over hge 11 * +
swap lge 19 * + 443 / ] is mge ( y --> n )
[ dup hge
over lge +
swap mge 7 * -
90 + 25 / ] is nge ( y --> n )
[ dup hge
over lge +
over mge 7 * +
swap nge 33 * +
19 + 32 mod ] is pge ( y --> n )
[ dup nge swap pge ] is gregorian ( y --> m d )
[ dup 1583 < iff
julian
else gregorian ] is easter ( y --> m d )
[ dip 1+ 9 +
dup 31 > if
[ dip 1+ 31 - ] ] is ascension ( m d --> )
[ dip 1+ 19 +
dup 31 > if
[ dip 1+ 31 - ] ] is pentecost ( m d --> )
[ dip 1+ 26 +
dup 31 > if
[ dip 1+ 31 - ] ] is trinity ( m d --> )
[ dip 1+ 30 +
dup 31 > if
[ dip 1+ 31 - ] ] is corpus ( m d --> )
[ swap 3 -
[ table
$ "Mar" $ "Apr"
$ "May" $ "Jun" ]
do echo$ sp
dup 10 < if [ say "0" ]
echo ] is echodate ( m d --> )
[ dup 1000 < if sp
dup echo say " "
easter 2dup echodate
say " "
2dup ascension echodate
say " "
2dup pentecost echodate
say " "
2dup trinity echodate
say " "
corpus echodate cr ] is echodates ( y --> )
say "Year Easter Ascension Trinity Corpus"
cr
say "(CE) Sunday Thursday Pentecost Sunday Christi"
cr cr
18 times
[ i^ 100 * 400 + echodates ]
cr
11 times
[ i^ 2010 + echodates ]
- Output:
Output concurs with the bc Western holidays entry.
Year Easter Ascension Trinity Corpus (CE) Sunday Thursday Pentecost Sunday Christi 400 Apr 01 May 10 May 20 May 27 May 31 500 Apr 02 May 11 May 21 May 28 Jun 01 600 Apr 10 May 19 May 29 Jun 05 Jun 09 700 Apr 11 May 20 May 30 Jun 06 Jun 10 800 Apr 19 May 28 Jun 07 Jun 14 Jun 18 900 Apr 20 May 29 Jun 08 Jun 15 Jun 19 1000 Mar 31 May 09 May 19 May 26 May 30 1100 Apr 01 May 10 May 20 May 27 May 31 1200 Apr 09 May 18 May 28 Jun 04 Jun 08 1300 Apr 10 May 19 May 29 Jun 05 Jun 09 1400 Apr 18 May 27 Jun 06 Jun 13 Jun 17 1500 Apr 19 May 28 Jun 07 Jun 14 Jun 18 1600 Apr 02 May 11 May 21 May 28 Jun 01 1700 Apr 11 May 20 May 30 Jun 06 Jun 10 1800 Apr 13 May 22 Jun 01 Jun 08 Jun 12 1900 Apr 15 May 24 Jun 03 Jun 10 Jun 14 2000 Apr 23 Jun 01 Jun 11 Jun 18 Jun 22 2100 Mar 28 May 06 May 16 May 23 May 27 2010 Apr 04 May 13 May 23 May 30 Jun 03 2011 Apr 24 Jun 02 Jun 12 Jun 19 Jun 23 2012 Apr 08 May 17 May 27 Jun 03 Jun 07 2013 Mar 31 May 09 May 19 May 26 May 30 2014 Apr 20 May 29 Jun 08 Jun 15 Jun 19 2015 Apr 05 May 14 May 24 May 31 Jun 04 2016 Mar 27 May 05 May 15 May 22 May 26 2017 Apr 16 May 25 Jun 04 Jun 11 Jun 15 2018 Apr 01 May 10 May 20 May 27 May 31 2019 Apr 21 May 30 Jun 09 Jun 16 Jun 20 2020 Apr 12 May 21 May 31 Jun 07 Jun 11
R
library(tidyverse)
library(lubridate)
# Make a pretty date function:
pretty_date = stamp_date("Thu, Jun 1, 2000")
# Gregorian calendar:
tibble(year = c(seq(400, 2100, 100), 2010:2020)) %>%
arrange(year) %>%
mutate(a = year %% 19,
b = year %% 4,
c = year %% 7,
k = year %/% 100,
p = (13 + 8 * k) %/% 25,
q = k %/% 4,
M = (15 - p + k - q) %% 30,
N = (4 + k - q) %% 7,
d = (19 * a + M) %% 30,
e = (2 * b + 4 * c + 6 * d + N) %% 7,
easter_mar = 22 + d + e,
easter_apr = d + e - 9,
easter_day = if_else(easter_mar <= 31, easter_mar, easter_apr),
easter_day = case_when(
d == 29 & e == 6 ~ 19,
d == 28 & e == 6 & (11 * M + 11) %% 30 < 19 ~ 18,
TRUE ~ easter_day),
easter_day = sprintf("%02d", easter_day),
easter_year = sprintf("%04d", year),
easter_mon = if_else(easter_mar <= 31, "03", "04")) %>%
unite("easter", easter_year, easter_mon, easter_day, sep = "-") %>%
mutate(Easter = parse_date(easter, format = "%Y-%m-%e")) %>%
select(Easter) %>%
mutate(Ascension = Easter + 39,
Pentecost = Ascension + 10,
Trinity = Pentecost + 7,
`Corpus Christi` = Trinity + 4,
across(.fns = pretty_date))
- Output:
# A tibble: 29 x 5 Easter Ascension Pentecost Trinity `Corpus Christi` <chr> <chr> <chr> <chr> <chr> 1 Sun, Apr 02, 0400 Thu, May 11, 0400 Sun, May 21, 0400 Sun, May 28, 0400 Thu, Jun 01, 0400 2 Sun, Apr 04, 0500 Thu, May 13, 0500 Sun, May 23, 0500 Sun, May 30, 0500 Thu, Jun 03, 0500 3 Sun, Apr 13, 0600 Thu, May 22, 0600 Sun, Jun 01, 0600 Sun, Jun 08, 0600 Thu, Jun 12, 0600 4 Sun, Apr 15, 0700 Thu, May 24, 0700 Sun, Jun 03, 0700 Sun, Jun 10, 0700 Thu, Jun 14, 0700 5 Sun, Apr 23, 0800 Thu, Jun 01, 0800 Sun, Jun 11, 0800 Sun, Jun 18, 0800 Thu, Jun 22, 0800 6 Sun, Mar 28, 0900 Thu, May 06, 0900 Sun, May 16, 0900 Sun, May 23, 0900 Thu, May 27, 0900 7 Sun, Mar 30, 1000 Thu, May 08, 1000 Sun, May 18, 1000 Sun, May 25, 1000 Thu, May 29, 1000 8 Sun, Apr 08, 1100 Thu, May 17, 1100 Sun, May 27, 1100 Sun, Jun 03, 1100 Thu, Jun 07, 1100 9 Sun, Apr 09, 1200 Thu, May 18, 1200 Sun, May 28, 1200 Sun, Jun 04, 1200 Thu, Jun 08, 1200 10 Sun, Apr 18, 1300 Thu, May 27, 1300 Sun, Jun 06, 1300 Sun, Jun 13, 1300 Thu, Jun 17, 1300 11 Sun, Apr 20, 1400 Thu, May 29, 1400 Sun, Jun 08, 1400 Sun, Jun 15, 1400 Thu, Jun 19, 1400 12 Sun, Apr 01, 1500 Thu, May 10, 1500 Sun, May 20, 1500 Sun, May 27, 1500 Thu, May 31, 1500 13 Sun, Apr 02, 1600 Thu, May 11, 1600 Sun, May 21, 1600 Sun, May 28, 1600 Thu, Jun 01, 1600 14 Sun, Apr 11, 1700 Thu, May 20, 1700 Sun, May 30, 1700 Sun, Jun 06, 1700 Thu, Jun 10, 1700 15 Sun, Apr 13, 1800 Thu, May 22, 1800 Sun, Jun 01, 1800 Sun, Jun 08, 1800 Thu, Jun 12, 1800 16 Sun, Apr 15, 1900 Thu, May 24, 1900 Sun, Jun 03, 1900 Sun, Jun 10, 1900 Thu, Jun 14, 1900 17 Sun, Apr 23, 2000 Thu, Jun 01, 2000 Sun, Jun 11, 2000 Sun, Jun 18, 2000 Thu, Jun 22, 2000 18 Sun, Apr 04, 2010 Thu, May 13, 2010 Sun, May 23, 2010 Sun, May 30, 2010 Thu, Jun 03, 2010 19 Sun, Apr 24, 2011 Thu, Jun 02, 2011 Sun, Jun 12, 2011 Sun, Jun 19, 2011 Thu, Jun 23, 2011 20 Sun, Apr 08, 2012 Thu, May 17, 2012 Sun, May 27, 2012 Sun, Jun 03, 2012 Thu, Jun 07, 2012 21 Sun, Mar 31, 2013 Thu, May 09, 2013 Sun, May 19, 2013 Sun, May 26, 2013 Thu, May 30, 2013 22 Sun, Apr 20, 2014 Thu, May 29, 2014 Sun, Jun 08, 2014 Sun, Jun 15, 2014 Thu, Jun 19, 2014 23 Sun, Apr 05, 2015 Thu, May 14, 2015 Sun, May 24, 2015 Sun, May 31, 2015 Thu, Jun 04, 2015 24 Sun, Mar 27, 2016 Thu, May 05, 2016 Sun, May 15, 2016 Sun, May 22, 2016 Thu, May 26, 2016 25 Sun, Apr 16, 2017 Thu, May 25, 2017 Sun, Jun 04, 2017 Sun, Jun 11, 2017 Thu, Jun 15, 2017 26 Sun, Apr 01, 2018 Thu, May 10, 2018 Sun, May 20, 2018 Sun, May 27, 2018 Thu, May 31, 2018 27 Sun, Apr 21, 2019 Thu, May 30, 2019 Sun, Jun 09, 2019 Sun, Jun 16, 2019 Thu, Jun 20, 2019 28 Sun, Apr 12, 2020 Thu, May 21, 2020 Sun, May 31, 2020 Sun, Jun 07, 2020 Thu, Jun 11, 2020 29 Sun, Mar 28, 2100 Thu, May 06, 2100 Sun, May 16, 2100 Sun, May 23, 2100 Thu, May 27, 2100
Racket
The Scheme version works unchanged for Racket.
Raku
(formerly Perl 6)
my @abbr = < Nil Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec >;
my @holidays =
Easter => 0,
Ascension => 39,
Pentecost => 49,
Trinity => 56,
Corpus => 60;
sub easter($year) {
my \ay = $year % 19;
my \by = $year div 100;
my \cy = $year % 100;
my \dy = by div 4;
my \ey = by % 4;
my \fy = (by + 8) div 25;
my \gy = (by - fy + 1) div 3;
my \hy = (ay * 19 + by - dy - gy + 15) % 30;
my \iy = cy div 4;
my \ky = cy % 4;
my \ly = (32 + 2 * ey + 2 * iy - hy - ky) % 7;
my \md = hy + ly - 7 * ((ay + 11 * hy + 22 * ly) div 451) + 114;
my \month = md div 31;
my \day = md % 31 + 1;
return month, day;
}
sub cholidays($year) {
my ($emon, $eday) = easter($year);
printf "%4s: ", $year;
say join ', ', gather for @holidays -> $holiday {
my $d = Date.new($year,$emon,$eday) + $holiday.value;
take "{$holiday.key}: $d.day-of-month.fmt('%02s') @abbr[$d.month]";
}
}
for flat (400,500 ... 2000), (2010 ... 2020), 2100 -> $year {
cholidays($year);
}
- Output:
400: Easter: 02 Apr, Ascension: 11 May, Pentecost: 21 May, Trinity: 28 May, Corpus: 01 Jun 500: Easter: 04 Apr, Ascension: 13 May, Pentecost: 23 May, Trinity: 30 May, Corpus: 03 Jun 600: Easter: 13 Apr, Ascension: 22 May, Pentecost: 01 Jun, Trinity: 08 Jun, Corpus: 12 Jun 700: Easter: 15 Apr, Ascension: 24 May, Pentecost: 03 Jun, Trinity: 10 Jun, Corpus: 14 Jun 800: Easter: 23 Apr, Ascension: 01 Jun, Pentecost: 11 Jun, Trinity: 18 Jun, Corpus: 22 Jun 900: Easter: 28 Mar, Ascension: 06 May, Pentecost: 16 May, Trinity: 23 May, Corpus: 27 May 1000: Easter: 30 Mar, Ascension: 08 May, Pentecost: 18 May, Trinity: 25 May, Corpus: 29 May 1100: Easter: 08 Apr, Ascension: 17 May, Pentecost: 27 May, Trinity: 03 Jun, Corpus: 07 Jun 1200: Easter: 09 Apr, Ascension: 18 May, Pentecost: 28 May, Trinity: 04 Jun, Corpus: 08 Jun 1300: Easter: 18 Apr, Ascension: 27 May, Pentecost: 06 Jun, Trinity: 13 Jun, Corpus: 17 Jun 1400: Easter: 20 Apr, Ascension: 29 May, Pentecost: 08 Jun, Trinity: 15 Jun, Corpus: 19 Jun 1500: Easter: 01 Apr, Ascension: 10 May, Pentecost: 20 May, Trinity: 27 May, Corpus: 31 May 1600: Easter: 02 Apr, Ascension: 11 May, Pentecost: 21 May, Trinity: 28 May, Corpus: 01 Jun 1700: Easter: 11 Apr, Ascension: 20 May, Pentecost: 30 May, Trinity: 06 Jun, Corpus: 10 Jun 1800: Easter: 13 Apr, Ascension: 22 May, Pentecost: 01 Jun, Trinity: 08 Jun, Corpus: 12 Jun 1900: Easter: 15 Apr, Ascension: 24 May, Pentecost: 03 Jun, Trinity: 10 Jun, Corpus: 14 Jun 2000: Easter: 23 Apr, Ascension: 01 Jun, Pentecost: 11 Jun, Trinity: 18 Jun, Corpus: 22 Jun 2010: Easter: 04 Apr, Ascension: 13 May, Pentecost: 23 May, Trinity: 30 May, Corpus: 03 Jun 2011: Easter: 24 Apr, Ascension: 02 Jun, Pentecost: 12 Jun, Trinity: 19 Jun, Corpus: 23 Jun 2012: Easter: 08 Apr, Ascension: 17 May, Pentecost: 27 May, Trinity: 03 Jun, Corpus: 07 Jun 2013: Easter: 31 Mar, Ascension: 09 May, Pentecost: 19 May, Trinity: 26 May, Corpus: 30 May 2014: Easter: 20 Apr, Ascension: 29 May, Pentecost: 08 Jun, Trinity: 15 Jun, Corpus: 19 Jun 2015: Easter: 05 Apr, Ascension: 14 May, Pentecost: 24 May, Trinity: 31 May, Corpus: 04 Jun 2016: Easter: 27 Mar, Ascension: 05 May, Pentecost: 15 May, Trinity: 22 May, Corpus: 26 May 2017: Easter: 16 Apr, Ascension: 25 May, Pentecost: 04 Jun, Trinity: 11 Jun, Corpus: 15 Jun 2018: Easter: 01 Apr, Ascension: 10 May, Pentecost: 20 May, Trinity: 27 May, Corpus: 31 May 2019: Easter: 21 Apr, Ascension: 30 May, Pentecost: 09 Jun, Trinity: 16 Jun, Corpus: 20 Jun 2020: Easter: 12 Apr, Ascension: 21 May, Pentecost: 31 May, Trinity: 07 Jun, Corpus: 11 Jun 2100: Easter: 28 Mar, Ascension: 06 May, Pentecost: 16 May, Trinity: 23 May, Corpus: 27 May
REXX
/* REXX **********************************************************************************
* Test frame for computing Christian (Roman Catholic) holidays, related to Easter
* 16.04.2013 Walter Pachl
* 08.03.2021 -"- extended range of years and indicate Roman Catholic use
*****************************************************************************************/
oid='ee.txt'; 'erase' oid
month.3='Mar'; days.3=31
month.4='Apr'; days.4=30
month.5='May'; days.5=31
month.6='Jun'; days.6=30
Call o 'Christian holidays, related to Easter, for each centennial',
'from 400 to 2200 CE:'
Do y=400 To 2200 By 100
Call line y
End
Call o ' '
Call o 'Christian holidays, related to Easter, for years',
'from 2010 to 2030 CE:'
Do y=2010 To 2030
Call line y
End
Exit
line: Parse Arg y
Parse Value easter(y) With y m d
Parse Value add(d,m,39) With ad am
Parse Value add(ad,am,10) With pd pm
Parse Value add(pd,pm,7) With td tm
Parse Value add(td,tm,4) With cd cm
ol=right(y,4) 'Easter:' right(d,2) month.m
ol=ol' Ascension:' right(ad,2) month.am ' Pentecost:' right(pd,2) month.pm
ol=ol' Trinity:' right(td,2) month.tm' Corpus:' right(cd,2) month.cm
Call o ol
Return
o: Return lineout(oid,arg(1))
add: Procedure Expose days.
Parse Arg d,m,dd
res=d+dd
Do While res>days.m
res=res-days.m
m=m+1
End
Return res m
easter: Procedure
/***********************************************************
* translated from FORTRAN (mod -> //; / -> %)
* Input year
* Output year month day of Easter Sunday
* 16.04.2013 Walter Pachl
c See:
c Jean Meeus, "Astronomical Formulae for Calculators",
c 4th edition, Willmann-Bell, 1988, p.31
*********************************************************/
Parse Arg year
a=year//19
b=year%100
c=year//100
d=b%4
e=b//4
f=(b+8)%25
g=(b-f+1)%3
h=(19*a+b-d-g+15)//30
i=c%4
k=c//4
l=(32+2*e+2*i-h-k)//7
m=(a+11*h+22*l)%451
n=h+l-7*m+114
month=n%31
day=n//31+1
Return year month day
Output:
Christian holidays, related to Easter, for each centennial from 400 to 2200 CE: 400 Easter: 2 Apr Ascension: 11 May Pentecost: 21 May Trinity: 28 May Corpus: 1 Jun 500 Easter: 4 Apr Ascension: 13 May Pentecost: 23 May Trinity: 30 May Corpus: 3 Jun 600 Easter: 13 Apr Ascension: 22 May Pentecost: 1 Jun Trinity: 8 Jun Corpus: 12 Jun 700 Easter: 15 Apr Ascension: 24 May Pentecost: 3 Jun Trinity: 10 Jun Corpus: 14 Jun 800 Easter: 23 Apr Ascension: 1 Jun Pentecost: 11 Jun Trinity: 18 Jun Corpus: 22 Jun 900 Easter: 28 Mar Ascension: 6 May Pentecost: 16 May Trinity: 23 May Corpus: 27 May 1000 Easter: 30 Mar Ascension: 8 May Pentecost: 18 May Trinity: 25 May Corpus: 29 May 1100 Easter: 8 Apr Ascension: 17 May Pentecost: 27 May Trinity: 3 Jun Corpus: 7 Jun 1200 Easter: 9 Apr Ascension: 18 May Pentecost: 28 May Trinity: 4 Jun Corpus: 8 Jun 1300 Easter: 18 Apr Ascension: 27 May Pentecost: 6 Jun Trinity: 13 Jun Corpus: 17 Jun 1400 Easter: 20 Apr Ascension: 29 May Pentecost: 8 Jun Trinity: 15 Jun Corpus: 19 Jun 1500 Easter: 1 Apr Ascension: 10 May Pentecost: 20 May Trinity: 27 May Corpus: 31 May 1600 Easter: 2 Apr Ascension: 11 May Pentecost: 21 May Trinity: 28 May Corpus: 1 Jun 1700 Easter: 11 Apr Ascension: 20 May Pentecost: 30 May Trinity: 6 Jun Corpus: 10 Jun 1800 Easter: 13 Apr Ascension: 22 May Pentecost: 1 Jun Trinity: 8 Jun Corpus: 12 Jun 1900 Easter: 15 Apr Ascension: 24 May Pentecost: 3 Jun Trinity: 10 Jun Corpus: 14 Jun 2000 Easter: 23 Apr Ascension: 1 Jun Pentecost: 11 Jun Trinity: 18 Jun Corpus: 22 Jun 2100 Easter: 28 Mar Ascension: 6 May Pentecost: 16 May Trinity: 23 May Corpus: 27 May 2200 Easter: 6 Apr Ascension: 15 May Pentecost: 25 May Trinity: 1 Jun Corpus: 5 Jun Christian holidays, related to Easter, for years from 2010 to 2030 CE: 2010 Easter: 4 Apr Ascension: 13 May Pentecost: 23 May Trinity: 30 May Corpus: 3 Jun 2011 Easter: 24 Apr Ascension: 2 Jun Pentecost: 12 Jun Trinity: 19 Jun Corpus: 23 Jun 2012 Easter: 8 Apr Ascension: 17 May Pentecost: 27 May Trinity: 3 Jun Corpus: 7 Jun 2013 Easter: 31 Mar Ascension: 9 May Pentecost: 19 May Trinity: 26 May Corpus: 30 May 2014 Easter: 20 Apr Ascension: 29 May Pentecost: 8 Jun Trinity: 15 Jun Corpus: 19 Jun 2015 Easter: 5 Apr Ascension: 14 May Pentecost: 24 May Trinity: 31 May Corpus: 4 Jun 2016 Easter: 27 Mar Ascension: 5 May Pentecost: 15 May Trinity: 22 May Corpus: 26 May 2017 Easter: 16 Apr Ascension: 25 May Pentecost: 4 Jun Trinity: 11 Jun Corpus: 15 Jun 2018 Easter: 1 Apr Ascension: 10 May Pentecost: 20 May Trinity: 27 May Corpus: 31 May 2019 Easter: 21 Apr Ascension: 30 May Pentecost: 9 Jun Trinity: 16 Jun Corpus: 20 Jun 2020 Easter: 12 Apr Ascension: 21 May Pentecost: 31 May Trinity: 7 Jun Corpus: 11 Jun 2021 Easter: 4 Apr Ascension: 13 May Pentecost: 23 May Trinity: 30 May Corpus: 3 Jun 2022 Easter: 17 Apr Ascension: 26 May Pentecost: 5 Jun Trinity: 12 Jun Corpus: 16 Jun 2023 Easter: 9 Apr Ascension: 18 May Pentecost: 28 May Trinity: 4 Jun Corpus: 8 Jun 2024 Easter: 31 Mar Ascension: 9 May Pentecost: 19 May Trinity: 26 May Corpus: 30 May 2025 Easter: 20 Apr Ascension: 29 May Pentecost: 8 Jun Trinity: 15 Jun Corpus: 19 Jun 2026 Easter: 5 Apr Ascension: 14 May Pentecost: 24 May Trinity: 31 May Corpus: 4 Jun 2027 Easter: 28 Mar Ascension: 6 May Pentecost: 16 May Trinity: 23 May Corpus: 27 May 2028 Easter: 16 Apr Ascension: 25 May Pentecost: 4 Jun Trinity: 11 Jun Corpus: 15 Jun 2029 Easter: 1 Apr Ascension: 10 May Pentecost: 20 May Trinity: 27 May Corpus: 31 May 2030 Easter: 21 Apr Ascension: 30 May Pentecost: 9 Jun Trinity: 16 Jun Corpus: 20 Jun
Ruby
require 'date'
def easter_date(year)
# Anonymous Gregorian algorithm
# http://en.wikipedia.org/wiki/Computus#Algorithms
a = year % 19
b, c = year.divmod(100)
d, e = b.divmod(4)
f = (b + 8) / 25
g = (b - f + 1) / 3
h = (19*a + b - d - g + 15) % 30
i, k = c.divmod(4)
l = (32 + 2*e + 2*i - h - k) % 7
m = (a + 11*h + 22*l) / 451
numerator = h + l - 7*m + 114
month = numerator / 31
day = (numerator % 31) + 1
Date.new(year, month, day)
end
OFFSETS = [
[:easter, 0],
[:ascension, 39],
[:pentecost, 49],
[:trinity, 56],
[:corpus, 60],
]
def emit_dates(year)
e = easter_date year
dates = OFFSETS.collect {|item, offset| (e + offset).strftime(" %e %b")}
puts "%4s: %s" % [year, dates.join(', ')]
end
puts "year:" + OFFSETS.collect{|item, offset| "%9s" % item}.join(', ')
400.step(2100, 100).each {|year| emit_dates year}
puts
(2010 .. 2020).each {|year| emit_dates year}
outputs
year: easter, ascension, pentecost, trinity, corpus 400: 2 Apr, 11 May, 21 May, 28 May, 1 Jun 500: 4 Apr, 13 May, 23 May, 30 May, 3 Jun 600: 13 Apr, 22 May, 1 Jun, 8 Jun, 12 Jun 700: 15 Apr, 24 May, 3 Jun, 10 Jun, 14 Jun 800: 23 Apr, 1 Jun, 11 Jun, 18 Jun, 22 Jun 900: 28 Mar, 6 May, 16 May, 23 May, 27 May 1000: 30 Mar, 8 May, 18 May, 25 May, 29 May 1100: 8 Apr, 17 May, 27 May, 3 Jun, 7 Jun 1200: 9 Apr, 18 May, 28 May, 4 Jun, 8 Jun 1300: 18 Apr, 27 May, 6 Jun, 13 Jun, 17 Jun 1400: 20 Apr, 29 May, 8 Jun, 15 Jun, 19 Jun 1500: 1 Apr, 10 May, 20 May, 27 May, 31 May 1600: 2 Apr, 11 May, 21 May, 28 May, 1 Jun 1700: 11 Apr, 20 May, 30 May, 6 Jun, 10 Jun 1800: 13 Apr, 22 May, 1 Jun, 8 Jun, 12 Jun 1900: 15 Apr, 24 May, 3 Jun, 10 Jun, 14 Jun 2000: 23 Apr, 1 Jun, 11 Jun, 18 Jun, 22 Jun 2100: 28 Mar, 6 May, 16 May, 23 May, 27 May 2010: 4 Apr, 13 May, 23 May, 30 May, 3 Jun 2011: 24 Apr, 2 Jun, 12 Jun, 19 Jun, 23 Jun 2012: 8 Apr, 17 May, 27 May, 3 Jun, 7 Jun 2013: 31 Mar, 9 May, 19 May, 26 May, 30 May 2014: 20 Apr, 29 May, 8 Jun, 15 Jun, 19 Jun 2015: 5 Apr, 14 May, 24 May, 31 May, 4 Jun 2016: 27 Mar, 5 May, 15 May, 22 May, 26 May 2017: 16 Apr, 25 May, 4 Jun, 11 Jun, 15 Jun 2018: 1 Apr, 10 May, 20 May, 27 May, 31 May 2019: 21 Apr, 30 May, 9 Jun, 16 Jun, 20 Jun 2020: 12 Apr, 21 May, 31 May, 7 Jun, 11 Jun
Rust
use std::ops::Add;
use chrono::{prelude::*, Duration};
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_sign_loss)]
#[allow(clippy::cast_possible_wrap)]
fn get_easter_day(year: u32) -> chrono::NaiveDate {
let k = (f64::from(year) / 100.).floor();
let d = (19 * (year % 19)
+ ((15 - ((13. + 8. * k) / 25.).floor() as u32 + k as u32 - (k / 4.).floor() as u32) % 30))
% 30;
let e =
(2 * (year % 4) + 4 * (year % 7) + 6 * d + ((4 + k as u32 - (k / 4.).floor() as u32) % 7))
% 7;
let (month, day) = match d {
29 if e == 6 => (4, 19),
28 if e == 6 => (4, 18),
_ if d + e < 10 => (3, 22 + d + e),
_ => (4, d + e - 9),
};
NaiveDate::from_ymd(year as i32, month, day)
}
fn main() {
let holidays = vec![
("Easter", Duration::days(0)),
("Ascension", Duration::days(39)),
("Pentecost", Duration::days(49)),
("Trinity", Duration::days(56)),
("Corpus Christi", Duration::days(60)),
];
for year in (400..=2100).step_by(100).chain(2010..=2020) {
print!("{}: ", year);
for (name, offset) in &holidays {
print!(
"{}: {}, ",
name,
get_easter_day(year).add(*offset).format("%a %d %h")
);
}
println!();
}
}
- Output:
400: Easter: Sun 02 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus Christi: Thu 01 Jun, 500: Easter: Sun 04 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus Christi: Thu 03 Jun, 600: Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 01 Jun, Trinity: Sun 08 Jun, Corpus Christi: Thu 12 Jun, 700: Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 03 Jun, Trinity: Sun 10 Jun, Corpus Christi: Thu 14 Jun, 800: Easter: Sun 23 Apr, Ascension: Thu 01 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus Christi: Thu 22 Jun, 900: Easter: Sun 28 Mar, Ascension: Thu 06 May, Pentecost: Sun 16 May, Trinity: Sun 23 May, Corpus Christi: Thu 27 May, 1000: Easter: Sun 30 Mar, Ascension: Thu 08 May, Pentecost: Sun 18 May, Trinity: Sun 25 May, Corpus Christi: Thu 29 May, 1100: Easter: Sun 08 Apr, Ascension: Thu 17 May, Pentecost: Sun 27 May, Trinity: Sun 03 Jun, Corpus Christi: Thu 07 Jun, 1200: Easter: Sun 09 Apr, Ascension: Thu 18 May, Pentecost: Sun 28 May, Trinity: Sun 04 Jun, Corpus Christi: Thu 08 Jun, 1300: Easter: Sun 18 Apr, Ascension: Thu 27 May, Pentecost: Sun 06 Jun, Trinity: Sun 13 Jun, Corpus Christi: Thu 17 Jun, 1400: Easter: Sun 20 Apr, Ascension: Thu 29 May, Pentecost: Sun 08 Jun, Trinity: Sun 15 Jun, Corpus Christi: Thu 19 Jun, 1500: Easter: Sun 01 Apr, Ascension: Thu 10 May, Pentecost: Sun 20 May, Trinity: Sun 27 May, Corpus Christi: Thu 31 May, 1600: Easter: Sun 02 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus Christi: Thu 01 Jun, 1700: Easter: Sun 11 Apr, Ascension: Thu 20 May, Pentecost: Sun 30 May, Trinity: Sun 06 Jun, Corpus Christi: Thu 10 Jun, 1800: Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 01 Jun, Trinity: Sun 08 Jun, Corpus Christi: Thu 12 Jun, 1900: Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 03 Jun, Trinity: Sun 10 Jun, Corpus Christi: Thu 14 Jun, 2000: Easter: Sun 23 Apr, Ascension: Thu 01 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus Christi: Thu 22 Jun, 2100: Easter: Sun 28 Mar, Ascension: Thu 06 May, Pentecost: Sun 16 May, Trinity: Sun 23 May, Corpus Christi: Thu 27 May, 2010: Easter: Sun 04 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus Christi: Thu 03 Jun, 2011: Easter: Sun 24 Apr, Ascension: Thu 02 Jun, Pentecost: Sun 12 Jun, Trinity: Sun 19 Jun, Corpus Christi: Thu 23 Jun, 2012: Easter: Sun 08 Apr, Ascension: Thu 17 May, Pentecost: Sun 27 May, Trinity: Sun 03 Jun, Corpus Christi: Thu 07 Jun, 2013: Easter: Sun 31 Mar, Ascension: Thu 09 May, Pentecost: Sun 19 May, Trinity: Sun 26 May, Corpus Christi: Thu 30 May, 2014: Easter: Sun 20 Apr, Ascension: Thu 29 May, Pentecost: Sun 08 Jun, Trinity: Sun 15 Jun, Corpus Christi: Thu 19 Jun, 2015: Easter: Sun 05 Apr, Ascension: Thu 14 May, Pentecost: Sun 24 May, Trinity: Sun 31 May, Corpus Christi: Thu 04 Jun, 2016: Easter: Sun 27 Mar, Ascension: Thu 05 May, Pentecost: Sun 15 May, Trinity: Sun 22 May, Corpus Christi: Thu 26 May, 2017: Easter: Sun 16 Apr, Ascension: Thu 25 May, Pentecost: Sun 04 Jun, Trinity: Sun 11 Jun, Corpus Christi: Thu 15 Jun, 2018: Easter: Sun 01 Apr, Ascension: Thu 10 May, Pentecost: Sun 20 May, Trinity: Sun 27 May, Corpus Christi: Thu 31 May, 2019: Easter: Sun 21 Apr, Ascension: Thu 30 May, Pentecost: Sun 09 Jun, Trinity: Sun 16 Jun, Corpus Christi: Thu 20 Jun, 2020: Easter: Sun 12 Apr, Ascension: Thu 21 May, Pentecost: Sun 31 May, Trinity: Sun 07 Jun, Corpus Christi: Thu 11 Jun,
Scala
import java.util._
import scala.swing._
def easter(year: Int) = {
// Start at March 21.
val cal = new GregorianCalendar(year, 2, 21);
/*
* Calculate e = day of Easter, following the 1886 paper,
* Kalender-Formeln (Calendar Formulae) by Chr. Zeller.
* http://www.merlyn.demon.co.uk/zel-1886.htm
*
* With Scala, p % 7 gives the wrong result when p < 0. To give the
* correct result, this code uses "+ 6 * j" where one might have used
* "- j". This works because because 6 == -1 (mod 7).
*/
var b = 0
var d = 0
if (cal.getTime().before(cal.getGregorianChange())) {
// Julian calendar
b = (19 * (year % 19) + 15) % 30
d = (b + year + year / 4) % 7
} else {
// Gregorian calendar
val j = year / 100
val a = year % 19
b = (19 * a + 15 + j - (8 * j + 13) / 25 - j / 4) % 30
d = (b + year + year / 4 + 6 * j + j / 4 + 2) % 7
if (d == 0 && (b == 29 || (b == 28 && a > 10))) d = 7
}
val e = b + 7 - d // This counts days after 21 March.
val df = new java.text.SimpleDateFormat("EEE dd MMM");
def advance(days: Int) = {
cal.add(Calendar.DAY_OF_MONTH, days)
df.format(cal.getTime())
}
val ary = new Array[Any](6)
ary(0) = year
ary(1) = advance(e) // Easter
ary(2) = advance(39) // Ascension Thursday
ary(3) = advance(10) // Pentecost
ary(4) = advance(7) // Trinity Sunday
ary(5) = advance(4) // Corpus Christi
ary
}
val columns = Array("AD", "Easter", "Ascension Thursday", "Pentecost",
"Trinity Sunday", "Corpus Christi")
val rows = (400.to(2000, 100) ++ 2010.to(2020) ++ Array(2100))
.map(easter(_)).toArray
new MainFrame {
title = "Holidays related to Easter"
contents = new ScrollPane {
contents = new Table(rows, columns)
}
size = new java.awt.Dimension(600, 400)
visible = true
}
Scheme
; Easter sunday. Result is a list '(month day)
;
; See:
; Jean Meeus, "Astronomical Formulae for Calculators",
; 4th edition, Willmann-Bell, 1988, p.31
(define (easter year)
(let* ((a (remainder year 19))
(b (quotient year 100))
(c (remainder year 100))
(d (quotient b 4))
(e (remainder b 4))
(f (quotient (+ b 8) 25))
(g (quotient (+ 1 (- b f)) 3))
(h (remainder (+ (* 19 a) (- b d g) 15) 30))
(i (quotient c 4))
(k (remainder c 4))
(l (remainder (+ e e i i (- 32 h k)) 7))
(m (quotient (+ a (* 11 h) (* 22 l)) 451))
(n (+ h l (- 114 (* 7 m)))))
(list (quotient n 31) (+ 1 (remainder n 31)))))
Seed7
$ include "seed7_05.s7i";
include "time.s7i";
include "duration.s7i";
const func time: easterDate (in integer: year) is func
result
var time: result is time.value;
local
var integer: H1 is 0;
var integer: H2 is 0;
var integer: M is 0;
var integer: N is 0;
var integer: a is 0;
var integer: b is 0;
var integer: c is 0;
var integer: d is 0;
var integer: e is 0;
var integer: f is 0;
begin
H1 := year mdiv 100;
H2 := year mdiv 400;
M := 15 + H1 - H2 - (8 * H1 + 13) mdiv 25;
N := 4 + H1 - H2;
# Gauss formula:
a := year mod 19;
b := year mod 4;
c := year mod 7;
d := (19 * a + M) mod 30;
e := (2 * b + 4 * c + 6 * d + N) mod 7;
f := 22 + d + e;
if f = 57 then
f := 50;
end if;
if d = 28 and e = 6 and a > 10 then
f := 49;
end if;
result.year := year;
if f <= 31 then
result.month := 3;
else
result.month := 4;
f -:= 31;
end if;
result.day := f;
end func;
const array string: weekday is [] ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");
const array string: month is [] ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
const array string: holiday is [] ("Easter", "Ascension", "Pentecost", "Trinity", "Corpus");
const array integer: delta is [] (0, 39, 49, 56, 60);
const func string: usDate (in time: aTime) is
return weekday[dayOfWeek(aTime)] <& aTime.day lpad 3 <& " " <& month[aTime.month];
const func string: holiday (in integer: index, in time: easter) is
return holiday[index] <& ": " <& usDate(easter + delta[index] . DAYS);
const proc: writeHolidays (in integer: year) is func
local
var time: easter is time.value;
begin
easter := easterDate(year);
writeln(year lpad 4 <& " " <&
holiday(1, easter) <& ", " <&
holiday(2, easter) <& ", " <&
holiday(3, easter) <& ", " <&
holiday(4, easter) <& ", " <&
holiday(5, easter));
end func;
const proc: main is func
local
var integer: year is 0;
begin
writeln("Christian holidays, related to Easter, for each centennial from 400 to 2100 CE:");
for year range 400 to 2100 step 100 do
writeHolidays(year);
end for;
writeln;
writeln("Christian holidays, related to Easter, for years from 2010 to 2020 CE:");
for year range 2010 to 2020 do
writeHolidays(year);
end for;
end func;
Original source of the function easterDate, which uses the Gauss formula: [1]
Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 CE: 400 Easter: Sun 2 Apr, Ascension: Thu 11 May, Pentecost: Sun 21 May, Trinity: Sun 28 May, Corpus: Thu 1 Jun 500 Easter: Sun 4 Apr, Ascension: Thu 13 May, Pentecost: Sun 23 May, Trinity: Sun 30 May, Corpus: Thu 3 Jun 600 Easter: Sun 13 Apr, Ascension: Thu 22 May, Pentecost: Sun 1 Jun, Trinity: Sun 8 Jun, Corpus: Thu 12 Jun 700 Easter: Sun 15 Apr, Ascension: Thu 24 May, Pentecost: Sun 3 Jun, Trinity: Sun 10 Jun, Corpus: Thu 14 Jun 800 Easter: Sun 23 Apr, Ascension: Thu 1 Jun, Pentecost: Sun 11 Jun, Trinity: Sun 18 Jun, Corpus: Thu 22 Jun 900 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 CE: 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
Sidef
require('Date::Calc')
var abbr = < Nil Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec >
var holidays = [
[Easter => 0],
[Ascension => 39],
[Pentecost => 49],
[Trinity => 56],
[Corpus => 60],
]
func easter(year) {
var ay = (year % 19)
var by = (year // 100)
var cy = (year % 100)
var dy = (by // 4)
var ey = (by % 4)
var fy = ((by + 8) // 25)
var gy = ((by - fy + 1) // 3)
var hy = ((19*ay + by - dy - gy + 15) % 30)
var iy = (cy // 4)
var ky = (cy % 4)
var ly = ((32 + 2*ey + 2*iy - hy - ky) % 7)
var md = (hy + ly - 7*((ay + 11*hy + 22*ly) // 451) + 114)
var month = (md // 31)
var day = (md % 31 + 1)
return(month, day)
}
func cholidays(year) {
var (emon, eday) = easter(year)
printf("%4s: ", year)
say gather {
holidays.each { |holiday|
var (_, mo, da) = %S<Date::Calc>.Add_Delta_Days(year, emon, eday, holiday[1])
take("#{holiday[0]}: #{'%02d' % da} #{abbr[mo]}")
}
}.join(', ')
}
for year in (400..2100 `by` 100, 2010..2020) {
cholidays(year)
}
Tcl
package require Tcl 8.5; # Advanced date handling engine
# Easter computation code from http://www.assa.org.au/edm.html
proc EasterDate year {
set FirstDig [expr {$year / 100}]
set Remain19 [expr {$year % 19}]
# calculate Paschal Full Moon date
set temp [expr {($FirstDig - 15)/2 + 202 - 11*$Remain19}]
if {$FirstDig in {21 24 25 27 28 29 30 31 32 34 35 38}} {
incr temp -1
} elseif {$FirstDig in {33 36 37 39 40}} {
incr temp -2
}
set temp [expr {$temp % 30}]
set tA [expr {$temp + 21}]
if {$temp == 29} {incr tA -1}
if {$temp == 28 && $Remain19 > 10} {incr tA -1}
# find the next Sunday
set tB [expr {($tA - 19) % 7}]
set tC [expr {(40 - $FirstDig) % 4}]
if {$tC == 3} {incr tC}
if {$tC > 1} {incr tC}
set temp [expr {$year % 100}]
set tD [expr {($temp + $temp/4) % 7}]
set tE [expr {((20 - $tB - $tC - $tD) % 7) + 1}]
set d [expr {$tA + $tE}]
# return the date
if {$d > 31} {
return [format "%02d April %04d" [expr {$d - 31}] $year]
} else {
return [format "%02d March %04d" $d $year]
}
}
# Use the Easter calculator to work out the data for the feasts
proc DateInfo year {
set fields [format %4d: $year]\t
set easter [clock scan [EasterDate $year] -format "%d %B %Y"]
foreach {name delta} {
Easter 0
Ascension 39
Pentecost 49
Trinity 56
Corpus 60
} {
set when [clock add $easter $delta days]
append fields [clock format $when -format "${name}: %d %b, "]
}
return [string trimright $fields " ,"]
}
# Print the required info
puts "Christian holidays, related to Easter, for each centennial from 400 to 2100 CE:"
for {set year 400} {$year <= 2100} {incr year 100} {
puts [DateInfo $year]
}
puts ""
puts "Christian holidays, related to Easter, for years from 2010 to 2020 CE:"
for {set year 2010} {$year <= 2020} {incr year} {
puts [DateInfo $year]
}
Output:
Christian holidays, related to Easter, for each centennial from 400 to 2100 CE: 400: Easter: 02 Apr, Ascension: 11 May, Pentecost: 21 May, Trinity: 28 May, Corpus: 01 Jun 500: Easter: 04 Apr, Ascension: 13 May, Pentecost: 23 May, Trinity: 30 May, Corpus: 03 Jun 600: Easter: 13 Apr, Ascension: 22 May, Pentecost: 01 Jun, Trinity: 08 Jun, Corpus: 12 Jun 700: Easter: 15 Apr, Ascension: 24 May, Pentecost: 03 Jun, Trinity: 10 Jun, Corpus: 14 Jun 800: Easter: 23 Apr, Ascension: 01 Jun, Pentecost: 11 Jun, Trinity: 18 Jun, Corpus: 22 Jun 900: Easter: 28 Mar, Ascension: 06 May, Pentecost: 16 May, Trinity: 23 May, Corpus: 27 May 1000: Easter: 30 Mar, Ascension: 08 May, Pentecost: 18 May, Trinity: 25 May, Corpus: 29 May 1100: Easter: 08 Apr, Ascension: 17 May, Pentecost: 27 May, Trinity: 03 Jun, Corpus: 07 Jun 1200: Easter: 09 Apr, Ascension: 18 May, Pentecost: 28 May, Trinity: 04 Jun, Corpus: 08 Jun 1300: Easter: 18 Apr, Ascension: 27 May, Pentecost: 06 Jun, Trinity: 13 Jun, Corpus: 17 Jun 1400: Easter: 20 Apr, Ascension: 29 May, Pentecost: 08 Jun, Trinity: 15 Jun, Corpus: 19 Jun 1500: Easter: 01 Apr, Ascension: 10 May, Pentecost: 20 May, Trinity: 27 May, Corpus: 31 May 1600: Easter: 02 Apr, Ascension: 11 May, Pentecost: 21 May, Trinity: 28 May, Corpus: 01 Jun 1700: Easter: 11 Apr, Ascension: 20 May, Pentecost: 30 May, Trinity: 06 Jun, Corpus: 10 Jun 1800: Easter: 13 Apr, Ascension: 22 May, Pentecost: 01 Jun, Trinity: 08 Jun, Corpus: 12 Jun 1900: Easter: 15 Apr, Ascension: 24 May, Pentecost: 03 Jun, Trinity: 10 Jun, Corpus: 14 Jun 2000: Easter: 23 Apr, Ascension: 01 Jun, Pentecost: 11 Jun, Trinity: 18 Jun, Corpus: 22 Jun 2100: Easter: 28 Mar, Ascension: 06 May, Pentecost: 16 May, Trinity: 23 May, Corpus: 27 May Christian holidays, related to Easter, for years from 2010 to 2020 CE: 2010: Easter: 04 Apr, Ascension: 13 May, Pentecost: 23 May, Trinity: 30 May, Corpus: 03 Jun 2011: Easter: 24 Apr, Ascension: 02 Jun, Pentecost: 12 Jun, Trinity: 19 Jun, Corpus: 23 Jun 2012: Easter: 08 Apr, Ascension: 17 May, Pentecost: 27 May, Trinity: 03 Jun, Corpus: 07 Jun 2013: Easter: 31 Mar, Ascension: 09 May, Pentecost: 19 May, Trinity: 26 May, Corpus: 30 May 2014: Easter: 20 Apr, Ascension: 29 May, Pentecost: 08 Jun, Trinity: 15 Jun, Corpus: 19 Jun 2015: Easter: 05 Apr, Ascension: 14 May, Pentecost: 24 May, Trinity: 31 May, Corpus: 04 Jun 2016: Easter: 27 Mar, Ascension: 05 May, Pentecost: 15 May, Trinity: 22 May, Corpus: 26 May 2017: Easter: 16 Apr, Ascension: 25 May, Pentecost: 04 Jun, Trinity: 11 Jun, Corpus: 15 Jun 2018: Easter: 01 Apr, Ascension: 10 May, Pentecost: 20 May, Trinity: 27 May, Corpus: 31 May 2019: Easter: 21 Apr, Ascension: 30 May, Pentecost: 09 Jun, Trinity: 16 Jun, Corpus: 20 Jun 2020: Easter: 12 Apr, Ascension: 21 May, Pentecost: 31 May, Trinity: 07 Jun, Corpus: 11 Jun
TUSCRIPT
For dates before October 15, 1582 the Julian Calendar is taken as basis.
$$ MODE TUSCRIPT
SET years=*
LOOP period1=400,2100,100
SET years=APPEND(years,period1)
ENDLOOP
LOOP period2=2010,2020
SET years=APPEND(years,period2)
ENDLOOP
SET years=DIGIT SORT (years)
LOOP year=years
SET dayofweek=DATE (EASTER,day,month,year,nreaster)
PRINT " Easter: ",year," ",month," ",day
LOOP nr="39'49'56'60",feast="Ascension'Pentecost' Trinity' Corpus"
SET number=nreaster+nr
SET dayofweek= DATE (DATE,day,month,year,number)
PRINT feast,": ",year," ",month," ",day
ENDLOOP
ENDLOOP
Output:
Easter: 400 4 1 Ascension: 400 5 10 Pentecost: 400 5 20 Trinity: 400 5 27 Corpus: 400 5 31 Easter: 500 4 2 Ascension: 500 5 11 Pentecost: 500 5 21 Trinity: 500 5 28 Corpus: 500 6 1 Easter: 600 4 10 Ascension: 600 5 19 Pentecost: 600 5 29 Trinity: 600 6 5 Corpus: 600 6 9 Easter: 700 4 11 Ascension: 700 5 20 Pentecost: 700 5 30 Trinity: 700 6 6 Corpus: 700 6 10 Easter: 800 4 19 Ascension: 800 5 28 Pentecost: 800 6 7 Trinity: 800 6 14 Corpus: 800 6 18 Easter: 900 4 20 Ascension: 900 5 29 Pentecost: 900 6 8 Trinity: 900 6 15 Corpus: 900 6 19 Easter: 1000 3 31 Ascension: 1000 5 9 Pentecost: 1000 5 19 Trinity: 1000 5 26 Corpus: 1000 5 30 Easter: 1100 4 1 Ascension: 1100 5 10 Pentecost: 1100 5 20 Trinity: 1100 5 27 Corpus: 1100 5 31 Easter: 1200 4 9 Ascension: 1200 5 18 Pentecost: 1200 5 28 Trinity: 1200 6 4 Corpus: 1200 6 8 Easter: 1300 4 10 Ascension: 1300 5 19 Pentecost: 1300 5 29 Trinity: 1300 6 5 Corpus: 1300 6 9 Easter: 1400 4 18 Ascension: 1400 5 27 Pentecost: 1400 6 6 Trinity: 1400 6 13 Corpus: 1400 6 17 Easter: 1500 4 19 Ascension: 1500 5 28 Pentecost: 1500 6 7 Trinity: 1500 6 14 Corpus: 1500 6 18 Easter: 1600 4 2 Ascension: 1600 5 11 Pentecost: 1600 5 21 Trinity: 1600 5 28 Corpus: 1600 6 1 Easter: 1700 4 11 Ascension: 1700 5 20 Pentecost: 1700 5 30 Trinity: 1700 6 6 Corpus: 1700 6 10 Easter: 1800 4 13 Ascension: 1800 5 22 Pentecost: 1800 6 1 Trinity: 1800 6 8 Corpus: 1800 6 12 Easter: 1900 4 15 Ascension: 1900 5 24 Pentecost: 1900 6 3 Trinity: 1900 6 10 Corpus: 1900 6 14 Easter: 2000 4 23 Ascension: 2000 6 1 Pentecost: 2000 6 11 Trinity: 2000 6 18 Corpus: 2000 6 22 Easter: 2010 4 4 Ascension: 2010 5 13 Pentecost: 2010 5 23 Trinity: 2010 5 30 Corpus: 2010 6 3 Easter: 2011 4 24 Ascension: 2011 6 2 Pentecost: 2011 6 12 Trinity: 2011 6 19 Corpus: 2011 6 23 Easter: 2012 4 8 Ascension: 2012 5 17 Pentecost: 2012 5 27 Trinity: 2012 6 3 Corpus: 2012 6 7 Easter: 2013 3 31 Ascension: 2013 5 9 Pentecost: 2013 5 19 Trinity: 2013 5 26 Corpus: 2013 5 30 Easter: 2014 4 20 Ascension: 2014 5 29 Pentecost: 2014 6 8 Trinity: 2014 6 15 Corpus: 2014 6 19 Easter: 2015 4 5 Ascension: 2015 5 14 Pentecost: 2015 5 24 Trinity: 2015 5 31 Corpus: 2015 6 4 Easter: 2016 3 27 Ascension: 2016 5 5 Pentecost: 2016 5 15 Trinity: 2016 5 22 Corpus: 2016 5 26 Easter: 2017 4 16 Ascension: 2017 5 25 Pentecost: 2017 6 4 Trinity: 2017 6 11 Corpus: 2017 6 15 Easter: 2018 4 1 Ascension: 2018 5 10 Pentecost: 2018 5 20 Trinity: 2018 5 27 Corpus: 2018 5 31 Easter: 2019 4 21 Ascension: 2019 5 30 Pentecost: 2019 6 9 Trinity: 2019 6 16 Corpus: 2019 6 20 Easter: 2020 4 12 Ascension: 2020 5 21 Pentecost: 2020 5 31 Trinity: 2020 6 7 Corpus: 2020 6 11 Easter: 2100 3 28 Ascension: 2100 5 6 Pentecost: 2100 5 16 Trinity: 2100 5 23 Corpus: 2100 5 27
VBA
Public dates As Variant
Private Function easter(year_ As Integer) As Date
'-- from https://en.wikipedia.org/wiki/Computus#Anonymous_Gregorian_algorithm
Dim a As Integer, b As Integer, c As Integer, d As Integer, e As Integer
Dim f As Integer, g As Integer, h As Integer, i As Integer, k As Integer
Dim l As Integer, m As Integer, n As Integer
a = year_ Mod 19
b = year_ \ 100
c = year_ Mod 100
d = b \ 4
e = b Mod 4
f = (b + 8) \ 25
g = (b - f + 1) \ 3
h = (19 * a + b - d - g + 15) Mod 30
i = c \ 4
k = c Mod 4
l = (32 + 2 * e + 2 * i - h - k) Mod 7
m = (a + 11 * h + 22 * l) \ 451
n = h + l - 7 * m + 114
month_ = n \ 31
day_ = n Mod 31 + 1
easter = DateSerial(year_, month_, day_)
End Function
Private Sub show(year_ As Integer)
If year_ = 0 Then
Debug.Print , "Easter", "Ascension", "Pentecost", "Trinity", "Corpus"
Else
Dim e As Date
e = easter(year_)
Debug.Print Format(year_, "@@@@"),
For i = 1 To UBound(dates)
Debug.Print Format(e + dates(i, 2), "ddd dd mmm"),
Next i
Debug.Print
End If
End Sub
Public Sub main()
Dim year_ As Integer
dates = [{"Easter ",0; "Ascension",39; "Pentecost",49; "Trinity ",56; "Corpus ",60}]
show 0
For year_ = 400 To 2000 Step 100
show year_
Next year_
Debug.Print
show 0
For year_ = 2010 To 2020
show year_
Next year_
End Sub
- Output:
Easter Ascension Pentecost Trinity Corpus 400 zo 02 apr do 11 mei zo 21 mei zo 28 mei do 01 jun 500 zo 04 apr do 13 mei zo 23 mei zo 30 mei do 03 jun 600 zo 13 apr do 22 mei zo 01 jun zo 08 jun do 12 jun 700 zo 15 apr do 24 mei zo 03 jun zo 10 jun do 14 jun 800 zo 23 apr do 01 jun zo 11 jun zo 18 jun do 22 jun 900 zo 28 mrt do 06 mei zo 16 mei zo 23 mei do 27 mei 1000 zo 30 mrt do 08 mei zo 18 mei zo 25 mei do 29 mei 1100 zo 08 apr do 17 mei zo 27 mei zo 03 jun do 07 jun 1200 zo 09 apr do 18 mei zo 28 mei zo 04 jun do 08 jun 1300 zo 18 apr do 27 mei zo 06 jun zo 13 jun do 17 jun 1400 zo 20 apr do 29 mei zo 08 jun zo 15 jun do 19 jun 1500 zo 01 apr do 10 mei zo 20 mei zo 27 mei do 31 mei 1600 zo 02 apr do 11 mei zo 21 mei zo 28 mei do 01 jun 1700 zo 11 apr do 20 mei zo 30 mei zo 06 jun do 10 jun 1800 zo 13 apr do 22 mei zo 01 jun zo 08 jun do 12 jun 1900 zo 15 apr do 24 mei zo 03 jun zo 10 jun do 14 jun 2000 zo 23 apr do 01 jun zo 11 jun zo 18 jun do 22 jun Easter Ascension Pentecost Trinity Corpus 2010 zo 04 apr do 13 mei zo 23 mei zo 30 mei do 03 jun 2011 zo 24 apr do 02 jun zo 12 jun zo 19 jun do 23 jun 2012 zo 08 apr do 17 mei zo 27 mei zo 03 jun do 07 jun 2013 zo 31 mrt do 09 mei zo 19 mei zo 26 mei do 30 mei 2014 zo 20 apr do 29 mei zo 08 jun zo 15 jun do 19 jun 2015 zo 05 apr do 14 mei zo 24 mei zo 31 mei do 04 jun 2016 zo 27 mrt do 05 mei zo 15 mei zo 22 mei do 26 mei 2017 zo 16 apr do 25 mei zo 04 jun zo 11 jun do 15 jun 2018 zo 01 apr do 10 mei zo 20 mei zo 27 mei do 31 mei 2019 zo 21 apr do 30 mei zo 09 jun zo 16 jun do 20 jun 2020 zo 12 apr do 21 mei zo 31 mei zo 07 jun do 11 jun
Wren
import "./date" for Date
import "./fmt" for Fmt
import "./iterate" for Stepped
var holidayOffsets = [
["Easter", 0],
["Ascension", 39],
["Pentecost", 49],
["Trinity", 56],
["C/Christi", 60]
]
var calculateEaster = Fn.new { |year|
var a = year % 19
var b = (year / 100).floor
var c = year % 100
var d = (b / 4).floor
var e = b % 4
var f = ((b + 8) / 25).floor
var g = ((b - f + 1) / 3).floor
var h = (19 * a + b - d - g + 15) % 30
var i = (c / 4).floor
var k = c % 4
var l = (32 + 2 * e + 2 * i - h - k) % 7
var m = ((a + 11 * h + 22 * l) / 451).floor
var n = h + l - 7 * m + 114
var month = (n / 31).floor // months indexed from 1
var day = (n % 31) + 1
return Date.new(year, month, day)
}
var outputHolidays = Fn.new { |year|
var date = calculateEaster.call(year)
Fmt.write("$4d ", year)
var po = 0
for (ho in holidayOffsets) {
var h = ho[0]
var o = ho[1]
date = date.addDays(o - po)
po = o
var ds = date.format("dd| |mmm|")
Fmt.write("$*m ", h.count, ds)
}
System.print()
}
System.print("Year Easter Ascension Pentecost Trinity C/Christi")
System.print(" CE Sunday Thursday Sunday Sunday Thursday ")
System.print("---- ------ --------- --------- ------- ---------")
for (year in Stepped.new(400..2100, 100)) outputHolidays.call(year)
System.print()
for (year in 2010..2020) outputHolidays.call(year)
- Output:
Year Easter Ascension Pentecost Trinity C/Christi CE Sunday Thursday Sunday Sunday Thursday ---- ------ --------- --------- ------- --------- 400 02 Apr 11 May 21 May 28 May 01 Jun 500 04 Apr 13 May 23 May 30 May 03 Jun 600 13 Apr 22 May 01 Jun 08 Jun 12 Jun 700 15 Apr 24 May 03 Jun 10 Jun 14 Jun 800 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 900 28 Mar 06 May 16 May 23 May 27 May 1000 30 Mar 08 May 18 May 25 May 29 May 1100 08 Apr 17 May 27 May 03 Jun 07 Jun 1200 09 Apr 18 May 28 May 04 Jun 08 Jun 1300 18 Apr 27 May 06 Jun 13 Jun 17 Jun 1400 20 Apr 29 May 08 Jun 15 Jun 19 Jun 1500 01 Apr 10 May 20 May 27 May 31 May 1600 02 Apr 11 May 21 May 28 May 01 Jun 1700 11 Apr 20 May 30 May 06 Jun 10 Jun 1800 13 Apr 22 May 01 Jun 08 Jun 12 Jun 1900 15 Apr 24 May 03 Jun 10 Jun 14 Jun 2000 23 Apr 01 Jun 11 Jun 18 Jun 22 Jun 2100 28 Mar 06 May 16 May 23 May 27 May 2010 04 Apr 13 May 23 May 30 May 03 Jun 2011 24 Apr 02 Jun 12 Jun 19 Jun 23 Jun 2012 08 Apr 17 May 27 May 03 Jun 07 Jun 2013 31 Mar 09 May 19 May 26 May 30 May 2014 20 Apr 29 May 08 Jun 15 Jun 19 Jun 2015 05 Apr 14 May 24 May 31 May 04 Jun 2016 27 Mar 05 May 15 May 22 May 26 May 2017 16 Apr 25 May 04 Jun 11 Jun 15 Jun 2018 01 Apr 10 May 20 May 27 May 31 May 2019 21 Apr 30 May 09 Jun 16 Jun 20 Jun 2020 12 Apr 21 May 31 May 07 Jun 11 Jun
- Programming Tasks
- Sciences
- 360 Assembly
- Ada
- ALGOL 68
- Arturo
- BASH
- BBC BASIC
- Bc
- Befunge
- C
- C sharp
- C++
- COBOL
- Common Lisp
- D
- Delphi
- System.SysUtils
- Elixir
- Erlang
- Factor
- Forth
- Fortran
- FreeBASIC
- Datetime
- String
- Fōrmulæ
- FutureBasic
- Go
- Icon
- Unicon
- J
- Java
- JavaScript
- Jq
- Julia
- Kotlin
- Lua
- Mathematica
- Wolfram Language
- Maxima
- МК-61/52
- Nim
- PARI/GP
- Perl
- Phix
- PicoLisp
- PL/I
- PowerShell
- PureBasic
- Python
- Python-dateutil
- Quackery
- R
- Racket
- Raku
- REXX
- Ruby
- Rust
- Scala
- Scheme
- Seed7
- Sidef
- Tcl
- TUSCRIPT
- GUISS/Omit
- Mathematics
- Date and time
- VBA
- Wren
- Wren-date
- Wren-fmt
- Wren-iterate