Re: Easter dates calculation?
Posted in 1994
Topics: General Discussion
In <1994Feb24.161110.352@spc.nl> piet@spc.nl (Piet Brekelmans) writes: >Does anyone know of a routine to calculate easter dates? Kind of. >I know it's got something to do with moon cycles and spring equinoxes, >but isn't there a possibility to calculate them (with some precision) >from one known easter date? Yup, the attached code uses a table to look up the dates of the full moon; the hard part was calculating the date of the following Sunday. - Mark ==================== CUT HERE =================================== #include <stdio.h> #define MARCH 3 #define APRIL 4 #define LEAP(year) ((year%4 == 0) && (year%100 != 0) || (year%400 == 0)) int juldays[13] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; /* I got this from the back of some desk calendar. */ struct paschal_plate { int pa_month; int pa_day } paschal_tab[] = { { APRIL, 14 }, { APRIL, 3 }, { MARCH, 23 }, { APRIL, 11 }, { MARCH, 31 }, { APRIL, 18 }, { APRIL, 8 }, { MARCH, 28 }, { APRIL, 16 }, { APRIL, 5 }, { MARCH, 25 }, { APRIL, 13 }, { APRIL, 2 }, { MARCH, 22 }, { APRIL, 10 }, { MARCH, 30 }, { APRIL, 17 }, { APRIL, 7 }, { MARCH, 27 }, }; /* local functions */ void julian2day(); void easter(); int paschal(); int weekday(); int julianday(); /* * just a demo main to show usage of the easter function */ main(argc, argv) int argc; char *argv[]; { int year, i; int month, day; if (argc < 2) { fprintf (stderr, "Usage: %s year [ ... ]\\n", argv[0]); exit(1); } for (i = 1; i < argc; i++) { year = atoi(argv[i]); if (year == 0) { fprintf(stderr, "I think something went wrong\\n"); exit(1); } easter (year, &month, &day); printf ("%02d/%02d/%04d\\n", month, day, year); } } /************************************************************/ void easter(year, month, mday) int year; int *month, *mday; { int wday, jday; /* * first get the date of the full moon that this is all based on */ paschal(year, month, mday); /* * Easter is the first Sunday after that full moon, so we need to * know what day of the week that full moon is this year. */ wday=weekday(year, *month, *mday); /* * now we need to add the number of days to the next Sunday, it * is easier to do this in julian days, so I convert this to julian * days, add the difference, and then convert it back again. */ jday=julianday(year, *month, *mday); if (wday == 7) jday+=7; else jday+=(7-wday); julian2day(year, jday, month, mday); } /************************************************************/ paschal (year, month, day) int year, *month, *day; { *month = paschal_tab[year % 19].pa_month; *day = paschal_tab[year % 19].pa_day; } /* ================================================================== * The code from here down was taken from the weekday program by * Marcel J.E. Mol (version 3.40). I removed some error checking * code of his because I new the limits of my Paschal table. * ================================================================== */ /* * weekday -- returns the day of the week number based on the given * year, month and day of the month value. */ int weekday(year, month, day) int year, month, day; { register int dow; dow = 6 + /* the magic number */ year + /* shift a day each year */ year/4 - year/100 + year/400 + /* shift a day each leap year */ juldays[month] + day; /* day of year */ if ((month < 3) && LEAP(year)) /* first two months of leap don't */ dow--; /* have the extra leap shift */ dow %= 7; return (dow == 0) ? 7 : dow; /* convert 0 to 7 */ } /* weekday */ /* * julian2day -- converts year and julian day value to the corresponding * month and day of the month values for that year. * these values are returned in the ouput variables month and day. */ void julian2day(year, jday, month, day) int year, jday; int *month, *day; { int leap; leap = LEAP(year) ? 1 : 0; if (jday > 365+leap || jday <= 0) { fprintf(stderr, "error in julian date %d.%d\\n", year, jday); exit(8); } if (jday <= 31) { *month = 1; *day = jday; return; } jday -= leap; if (jday <= 59) { *month = 2; *day = jday - 31 + leap; } else if (jday <= 90) { *month = 3; *day = jday - 59; } else if (jday <= 120) { *month = 4; *day = jday - 90; } else if (jday <= 151) { *month = 5; *day = jday - 120; } else if (jday <= 181) { *month = 6; *day = jday - 151; } else if (jday <= 212) { *month = 7; *day = jday - 181; } else if (jday <= 243) { *month = 8; *day = jday - 212; } else if (jday <= 273) { *month = 9; *day = jday - 243; } else if (jday <= 304) { *month = 10; *day = jday - 273; } else if (jday <= 334) { *month = 11; *day = jday - 304; } else { *month = 12; *day = jday - 334; } return; } /* julian2day */ /* * julianday -- converts a year, mont and day value the corresponding julian * day number of that year. * the julian day is passed as a return value. */ int julianday(year, month, day) int year, month, day; { register int doy; doy = juldays[month]; if ((month > 2) && LEAP(year)) doy++; doy += day; return doy; } /* julianday */ -- _____________________________________________________________________ Mark A. Delaney mdelaney@informix.com PHONE: (415) 926-6369 FAX: (415) 926-6571 Informix Software, 4100 Bohannon Drive, Menlo Park, CA 94025