diff options
author | dwmalone <dwmalone@FreeBSD.org> | 2001-01-02 11:35:57 +0000 |
---|---|---|
committer | dwmalone <dwmalone@FreeBSD.org> | 2001-01-02 11:35:57 +0000 |
commit | 53a3f567649231292f6d2d30eacf90124de02bee (patch) | |
tree | 4e92ee1920b3dbdc3109720223106a7b0181ed4d /usr.bin | |
parent | f41cea7e3911617cd40849a9e2785c99afd6c520 (diff) | |
download | FreeBSD-src-53a3f567649231292f6d2d30eacf90124de02bee.zip FreeBSD-src-53a3f567649231292f6d2d30eacf90124de02bee.tar.gz |
Use a slightly better documented way of calculating easter and
include a reference to the Calendar FAQ. Also make argument parsing
a little more robust.
PR: 23881
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/calendar/day.c | 36 | ||||
-rw-r--r-- | usr.bin/calendar/ostern.c | 63 |
2 files changed, 38 insertions, 61 deletions
diff --git a/usr.bin/calendar/day.c b/usr.bin/calendar/day.c index cdc3678..cf619b6 100644 --- a/usr.bin/calendar/day.c +++ b/usr.bin/calendar/day.c @@ -165,17 +165,13 @@ settime(now) time_t Mktime (dp) char *dp; { - char *date; time_t t; - int len; + int d, m, y; struct tm tm; - if ((date = strdup(dp)) == NULL) - errx(1, "strdup failed in Mktime"); (void)time(&t); tp = localtime(&t); - len = strlen(date); tm.tm_sec = 0; tm.tm_min = 0; tm.tm_hour = 0; @@ -184,31 +180,23 @@ time_t Mktime (dp) tm.tm_mon = tp->tm_mon; tm.tm_year = tp->tm_year; - - /* day */ - *(date+2) = '\0'; - tm.tm_mday = atoi(date); - - /* month */ - if (len >= 4) { - *(date+5) = '\0'; - tm.tm_mon = atoi(date+3) - 1; - } - - /* Year */ - if (len >= 7) { - tm.tm_year = atoi(date+6); - - /* tm_year up 1900 ... */ - if (tm.tm_year > 1900) - tm.tm_year -= 1900; + switch (sscanf(dp, "%d.%d.%d", &d, &m, &y)) { + case 3: + if (y > 1900) + y -= 1900; + tm.tm_year = y; + /* FALLTHROUGH */ + case 2: + tm.tm_mon = m - 1; + /* FALLTHROUGH */ + case 1: + tm.tm_mday = d; } #ifdef DEBUG fprintf(stderr, "Mktime: %d %d %d %s\n", (int)mktime(&tm), (int)t, len, asctime(&tm)); #endif - free(date); return(mktime(&tm)); } diff --git a/usr.bin/calendar/ostern.c b/usr.bin/calendar/ostern.c index 12bff9f..21c6c73 100644 --- a/usr.bin/calendar/ostern.c +++ b/usr.bin/calendar/ostern.c @@ -35,46 +35,35 @@ /* return year day for Easter */ +/* + * This code is based on the Calendar FAQ's code for how to calculate + * easter is. This is the Gregorian calendar version. They refer to + * the Algorithm of Oudin in the "Explanatory Supplement to the + * Astronomical Almanac". + */ + int easter (year) int year; /* 0 ... abcd, NOT since 1900 */ { - - int e_a, e_b, e_c, e_d, e_e,e_f, e_g, e_h, e_i, e_k, - e_l, e_m, e_n, e_p, e_q; - - /* silly, but it works */ - e_a = year % 19; - e_b = year / 100; - e_c = year % 100; - - e_d = e_b / 4; - e_e = e_b % 4; - e_f = (e_b + 8) / 25; - e_g = (e_b + 1 - e_f) / 3; - e_h = ((19 * e_a) + 15 + e_b - (e_d + e_g)) % 30; - e_i = e_c / 4; - e_k = e_c % 4; - e_l = (32 + 2 * e_e + 2 * e_i - (e_h + e_k)) % 7; - e_m = (e_a + 11 * e_h + 22 * e_l) / 451; - e_n = (e_h + e_l + 114 - (7 * e_m)) / 31; - e_p = (e_h + e_l + 114 - (7 * e_m)) % 31; - e_p = e_p + 1; - - e_q = 31 + 28; - - if (e_k == 0 && e_c != 0) - e_q += 1; - - if (e_n == 4) - e_q += 31; - - e_q += e_p; - -#if DEBUG - printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", e_a , e_b , e_c , e_d , e_e , e_f , e_g , e_h , e_i , e_k , e_l , e_m , e_n , e_p , e_q); -#endif - - return (e_q); + int G, /* Golden number - 1 */ + C, /* Century */ + H, /* 23 - epact % 30 */ + I, /* days from 21 March to Paschal full moon */ + J, /* weekday of full moon */ + L; /* days from 21 March to Sunday on of before full moon */ + + G = year % 19; + C = year / 100; + H = (C - C/4 - (8*C+13)/25 + 19*G + 15) % 30; + I = H - (H/28)*(1 - (H/28)*(29/(H + 1))*((21 - G)/11)); + J = (year + year/4 + I + 2 - C + C/4) % 7; + + L = I - J; + + if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) + return 31 + 29 + 21 + L + 7; + else + return 31 + 28 + 21 + L + 7; } /* return year day for Easter or easter depending days |