#include <u.h>
#include <libc.h>
/* lifted from Tom Duff's web page and 8c-ised */
/*
* Date of Easter, for years following 1582.
*
* The argument is a year, the return value is the date of Easter
* in March. Values larger than 31 are in April.
*
* Algorithm due to Aloysius Lilius and Christopher Clavius (16th century).
* Transcribed from D E Knuth, The Art of Computer Programming, Vol. 1,
* Second Edition, pages 155-156
*
* This code doesn't work for dates before 1582, when the Gregorian
* calendar was adopted. It is likely to become innacurate some time
* around 4140 A.D., when an additional February 29th will need to be
* removed from the calendar to maintain synchronization with the
* equinoxes. Nothing lasts forever.
*
* The Gregorian calendar was not universally adopted in 1582.
* Britain waited until 1752, and Russia until 1917. The Orthodox
* Church still uses the Julian calendar to compute the date
* of Easter and often celebrates on a different date.
*
* The movable feasts, synchronized with Easter are:
* Feast day Offset from Easter (days)
* ----- --- ------ ---- ------ ----
* Septuagesima Sunday -63
* Sexagesima Sunday -56
* Quinquagesima Sunday -49
* Shrove Tuesday -47
* Ash Wednesday (start of Lent) -46
* Quadragesima Sunday -42
* Palm Sunday (end of Lent) -7
* Good Friday -2
* Easter Sunday 0
* Rogation Sunday 35
* Ascension Day 40
* Whitsunday 49
* Trinity Sunday 56
*/
int
easter(int y)
{
int g; /* golden number in the 19 year metonic cycle */
int c; /* century of y (unless 100 divides y) */
int x; /* number of century years that are not leap years */
int z; /* correction to synchronize Easter with the moon's orbit */
int d; /* March (-d)%7 is a Sunday */
int e; /* the Epact, tells when a full moon occurs */
int n; /* date of the Paschal full moon */
g = y % 19 + 1;
c = y / 100 + 1;
x = 3 * c / 4 - 12;
z = (8 * c + 5) / 25 - 5;
d = 5 * y / 4 - x - 10;
e = (11 * g + 20 + z - x) % 30;
if(e < 0)
e += 30; /* first happens when y==9006 */
if(e == 25 && g > 11 || e == 24)
e++;
n = 44 - e;
if(n < 21)
n += 30;
return n + 7 - (d + n) % 7; /* the Sunday after the Paschal full moon */
}
void
printeaster(int y)
{
int d, m;
if(1582 <= y && y <= 4140) {
d = easter(y);
m = 3;
if(d > 31) {
m++;
d -= 31;
}
print("%s %2d %4d\n", m == 3 ? "Mar" : "Apr", d, y);
}
else
print("Don't know %4d\n", y);
}
void
main(int argc, char *argv[])
{
Tm *tm;
long t;
int i, d, m;
if(argc == 1){
/*
* To get the date of next Easter we first must decide
* whether it's passed already this year.
*/
time(&t);
tm = localtime(t);
tm->year += 1900;
d = easter(tm->year);
m = 2;
if(d > 31) {
m++;
d -= 31;
}
if(tm->mon > m || tm->mon == m && tm->mday >= d)
printeaster(tm->year + 1);
else
printeaster(tm->year);
}
else
for(i = 1; i != argc; i++)
printeaster(atoi(argv[i]));
exits(0);
}
|