You are here: irt.org | Articles | JavaScript | Date and Time | Easter [ previous next ]
Published on: Saturday 6th December 1997 By: Martin Webb
Easter n. (also Easter Day or Easter Sunday) the festival (held on variable Sunday in March or April) commemorating Christ's resurrection.
This article will describe how to calculate the date of Easter Sunday, "held on a variable Sunday in March or April". This date will then be used to calculate other religious dates dependent on Easter Sunday.
The following algorithim is taken from Calendars and their History available at http://astro.nmsu.edu/~lhuber-leaphist.html:
The following algorithm for computing the date of Easter is based on the algorithm of Oudin (1940). It is valid for any Gregorian year, Y. All variables are integers and the remainders of all divisions are dropped. The final date is given by M, the month, and D, the day of the month.
C = Y/100,
N = Y - 19*(Y/19),
K = (C - 17)/25,
I = C - C/4 - (C - K)/3 + 19*N + 15,
I = I - 30*(I/30),
I = I - (I/28)*(1 - (I/28)*(29/(I + 1))*((21 - N)/11)),
J = Y + Y/4 + I + 2 - C + C/4,
J = J - 7*(J/7),
L = I - J,
M = 3 + (L + 40)/44,
D = L + 28 - 31*(M/4).
This can be converted into the following simple script, where Math.floor converts floating point numbers to integers:
function Easter(Y) { var C = Math.floor(Y/100); var N = Y - 19*Math.floor(Y/19); var K = Math.floor((C - 17)/25); var I = C - Math.floor(C/4) - Math.floor((C - K)/3) + 19*N + 15; I = I - 30*Math.floor((I/30)); I = I - Math.floor(I/28)*(1 - Math.floor(I/28)*Math.floor(29/(I + 1))*Math.floor((21 - N)/11)); var J = Y + Math.floor(Y/4) + I + 2 - C + Math.floor(C/4); J = J - 7*Math.floor(J/7); var L = I - J; var M = 3 + Math.floor((L + 40)/44); var D = L + 28 - 31*Math.floor(M/4); return padout(M) + '.' + padout(D); }
The padout() function adds a leading zero if the number passed is less than 10:
function padout(number) { return (number < 10) ? '0' + number : number; }
Therefore the Easter() function returns a number in the format MM.DD where MM is the number of the month, and DD is the day within the month MM.
For example:
document.write(Easter(1997));
When run produces:
i.e. the 30th April 1997.
To retrieve the month and day from this string, we can use the following simple functions getMM() and getDD():
function getMM(string) { return eval(string.substring(0,2)); } function getDD(string) { return eval(string.substring(3,2)); }
For example
var when = Easter(1997); document.write('Day = ' + getDD(when) + ' Month = ' + getMM(when));
When run produces:
Quite a few of the religious dates are dependent on the date of Easter:
Fixed Dates:
Variable:
So how do we subtract or add days to a date and get another date?
Simple we number each day of the year from 1 to 365 (or 366 in a leap year), i.e. we use the Julian Day format used by NASA. We can then easily subtract or add a number to produce another numbered day of the year.
All we need to be able to do is convert a date to and from this Julian Day format. To do this we can utilise the following two accumulate[] and accumulateLY[] arrays, which use the makeArray() function described in the previous article Blind Date:
var accumulate = new makeArray( 0, 31, 59, 90,120,151,181,212,243,273,304,334); var accumulateLY = new makeArray( 0, 31, 60, 91,121,152,182,213,244,274,305,335);
The accumulate[] array holds the accumulation of the number of days in each month. For example, the 13th of January converts to 0 + 13 = day 13, whereas the 24th of August converts to 212 + 24 = day 236.
For leap years we need to use the accumulateLY[] array. To detect a leap year we use LeapYear() function described in the previous article Blind Date.
The following addDays() function will add or subtract a number of days (addition) to a date and return the new date in the format YYYY.MM.DD:
function addDays(day,month,year,addition) { if (LeapYear(year)) var number = day + accumulateLY[month] + addition; else var number = day + accumulate[month] + addition; var days = daysinyear(year); while (number > days) { number -= days; days = daysinyear(++year); } while (number < 1) { days = daysinyear(--year); number += days; } month = 1; if (LeapYear(year)) { while (number > accumulateLY[month]) { month++; } day = number - accumulateLY[--month]; } else { while (number > accumulate[month]) { month++; } day = number - accumulate[--month]; } return year + '.' + padout(month) + '.' + padout(day); } function daysinyear(year) { if (LeapYear(year)) return 366; else return 365; }
For example:
document.write(addDays(1,1,1997,-1)+'<BR>'); document.write(addDays(1,1,1997,31)+'<BR>');
When run produces:
To retrieve the year, month and day from the string returned we use the getYYYY() and getMMDD() functions along with the previously described getMM() and getDD() functions:
function getYYYY(string) { return eval(string.substring(0,string.indexOf('.'))); } function getMMDD(string) { return string.substring(string.indexOf('.')+1,string.length); }
For example:
var when = addDays(1,1,1997,-1); var ddmm = getMMDD(when); document.write('Day = ' + getDD(ddmm) + ' Month = ' + getMM(ddmm) + ' Year = ' + getYYYY(when) + '<BR>'); var when = addDays(1,1,1997,31); var ddmm = getMMDD(when); document.write('Day = ' + getDD(ddmm) + ' Month = ' + getMM(ddmm) + ' Year = ' + getYYYY(when) + '<BR>');
When run produces the following:
We can pretty this date by using the FullDate() function described in the previous article Monday's child is full of grace:
var when = addDays(1,1,1997,358); var ddmm = getMMDD(when); document.write('Christmas Day - ' + FullDate(getDD(ddmm),getMM(ddmm),getYYYY(when))+'<BR>');
Which when run produces:
Christmas Day - Thursday 25th December 1997
Try the frame version which shows all the religious dates for the current year.
You can view the source code of the four components:
And now...The Weekly Update Script
Extending "Born of the 4th of July"
Monday's child is full of grace