Plan 9 from Bell Labs’s /usr/web/sources/contrib/steve/misc/easter.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#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);
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.