X-Git-Url: https://git.cameronkatri.com/bsdgames-darwin.git/blobdiff_plain/abde1dfc02f8a0a37d89f5474fccb031bb59eb91..f16c0e9729afa1f6f057ed82f618398fa8e84ad8:/pom/pom.c diff --git a/pom/pom.c b/pom/pom.c index 6c30a70b..3eabc7e9 100644 --- a/pom/pom.c +++ b/pom/pom.c @@ -1,4 +1,4 @@ -/* $NetBSD: pom.c,v 1.10 1998/07/25 10:36:54 hubertf Exp $ */ +/* $NetBSD: pom.c,v 1.13 2003/08/07 09:37:32 agc Exp $ */ /* * Copyright (c) 1989, 1993 @@ -14,11 +14,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -45,7 +41,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 1993\n\ #if 0 static char sccsid[] = "@(#)pom.c 8.1 (Berkeley) 5/31/93"; #else -__RCSID("$NetBSD: pom.c,v 1.10 1998/07/25 10:36:54 hubertf Exp $"); +__RCSID("$NetBSD: pom.c,v 1.13 2003/08/07 09:37:32 agc Exp $"); #endif #endif /* not lint */ @@ -57,58 +53,71 @@ __RCSID("$NetBSD: pom.c,v 1.10 1998/07/25 10:36:54 hubertf Exp $"); * * -- Keith E. Brandt VIII 1984 * + * Updated to the Third Edition of Duffett-Smith's book, Paul Janzen, IX 1998 + * */ -#include +#include #include -#include #include #include #include #include -#include +#include +#include + +#ifndef PI +#define PI 3.14159265358979323846 +#endif -#define PI 3.141592654 -#define EPOCH 85 /* really 1985 */ -#define EPSILONg 279.611371 /* solar ecliptic long at EPOCH */ -#define RHOg 282.680403 /* solar ecliptic long of perigee at EPOCH */ -#define ECCEN 0.01671542 /* solar orbit eccentricity */ -#define lzero 18.251907 /* lunar mean long at EPOCH */ -#define Pzero 192.917585 /* lunar mean long of perigee at EPOCH */ -#define Nzero 55.204723 /* lunar mean long of node at EPOCH */ +/* + * The EPOCH in the third edition of the book is 1990 Jan 0.0 TDT. + * In this program, we do not bother to correct for the differences + * between UTC (as shown by the UNIX clock) and TDT. (TDT = TAI + 32.184s; + * TAI-UTC = 32s in Jan 1999.) + */ +#define EPOCH_MINUS_1970 (20 * 365 + 5 - 1) /* 20 years, 5 leaps, back 1 day to Jan 0 */ +#define EPSILONg 279.403303 /* solar ecliptic long at EPOCH */ +#define RHOg 282.768422 /* solar ecliptic long of perigee at EPOCH */ +#define ECCEN 0.016713 /* solar orbit eccentricity */ +#define lzero 318.351648 /* lunar mean long at EPOCH */ +#define Pzero 36.340410 /* lunar mean long of perigee at EPOCH */ +#define Nzero 318.510107 /* lunar mean long of node at EPOCH */ void adj360 __P((double *)); double dtor __P((double)); int main __P((int, char *[])); double potm __P((double)); +time_t parsetime __P((char *)); +void badformat __P((void)) __attribute__((__noreturn__)); int main(argc, argv) int argc; char *argv[]; { - struct timeval tp; - struct timezone tzp; - struct tm *GMT; - time_t tmpt; + time_t tmpt, now; double days, today, tomorrow; - int cnt; + char buf[1024]; + if (time(&now) == (time_t)-1) + err(1, "time"); if (argc > 1) { - tp.tv_sec = atoi(argv[1]); - tp.tv_usec = 0; + tmpt = parsetime(argv[1]); + strftime(buf, sizeof(buf), "%a %Y %b %e %H:%M:%S (%Z)", + localtime(&tmpt)); + printf("%s: ", buf); } else { - if (gettimeofday(&tp,&tzp)) - err(1, "gettimeofday"); + tmpt = now; } - tmpt = tp.tv_sec; - GMT = gmtime(&tmpt); - days = (GMT->tm_yday + 1) + ((GMT->tm_hour + - (GMT->tm_min / 60.0) + (GMT->tm_sec / 3600.0)) / 24.0); - for (cnt = EPOCH; cnt < GMT->tm_year; ++cnt) - days += isleap(cnt + 1900) ? 366 : 365; + days = (tmpt - EPOCH_MINUS_1970 * 86400) / 86400.0; today = potm(days) + .5; - (void)printf("The Moon is "); + if (tmpt < now) + (void)printf("The Moon was "); + else if (tmpt == now) + (void)printf("The Moon is "); + else + (void)printf("The Moon will be "); if ((int)today == 100) (void)printf("Full\n"); else if (!(int)today) @@ -118,7 +127,11 @@ main(argc, argv) if ((int)today == 50) (void)printf("%s\n", tomorrow > today ? "at the First Quarter" : "at the Last Quarter"); + /* today is 0.5 too big, but it doesn't matter here + * since the phase is changing fast enough + */ else { + today -= 0.5; /* Now it might matter */ (void)printf("%s ", tomorrow > today ? "Waxing" : "Waning"); if (today > 50) @@ -143,30 +156,30 @@ potm(days) double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime; double A4, lprime, V, ldprime, D, Nm; - N = 360 * days / 365.2422; /* sec 42 #3 */ + N = 360 * days / 365.242191; /* sec 46 #3 */ adj360(&N); - Msol = N + EPSILONg - RHOg; /* sec 42 #4 */ + Msol = N + EPSILONg - RHOg; /* sec 46 #4 */ adj360(&Msol); - Ec = 360 / PI * ECCEN * sin(dtor(Msol)); /* sec 42 #5 */ - LambdaSol = N + Ec + EPSILONg; /* sec 42 #6 */ + Ec = 360 / PI * ECCEN * sin(dtor(Msol)); /* sec 46 #5 */ + LambdaSol = N + Ec + EPSILONg; /* sec 46 #6 */ adj360(&LambdaSol); - l = 13.1763966 * days + lzero; /* sec 61 #4 */ + l = 13.1763966 * days + lzero; /* sec 65 #4 */ adj360(&l); - Mm = l - (0.1114041 * days) - Pzero; /* sec 61 #5 */ + Mm = l - (0.1114041 * days) - Pzero; /* sec 65 #5 */ adj360(&Mm); - Nm = Nzero - (0.0529539 * days); /* sec 61 #6 */ + Nm = Nzero - (0.0529539 * days); /* sec 65 #6 */ adj360(&Nm); - Ev = 1.2739 * sin(dtor(2*(l - LambdaSol) - Mm)); /* sec 61 #7 */ - Ac = 0.1858 * sin(dtor(Msol)); /* sec 61 #8 */ + Ev = 1.2739 * sin(dtor(2*(l - LambdaSol) - Mm)); /* sec 65 #7 */ + Ac = 0.1858 * sin(dtor(Msol)); /* sec 65 #8 */ A3 = 0.37 * sin(dtor(Msol)); - Mmprime = Mm + Ev - Ac - A3; /* sec 61 #9 */ - Ec = 6.2886 * sin(dtor(Mmprime)); /* sec 61 #10 */ - A4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 61 #11 */ - lprime = l + Ev + Ec - Ac + A4; /* sec 61 #12 */ - V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 61 #13 */ - ldprime = lprime + V; /* sec 61 #14 */ - D = ldprime - LambdaSol; /* sec 63 #2 */ - return(50 * (1 - cos(dtor(D)))); /* sec 63 #3 */ + Mmprime = Mm + Ev - Ac - A3; /* sec 65 #9 */ + Ec = 6.2886 * sin(dtor(Mmprime)); /* sec 65 #10 */ + A4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 65 #11 */ + lprime = l + Ev + Ec - Ac + A4; /* sec 65 #12 */ + V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 65 #13 */ + ldprime = lprime + V; /* sec 65 #14 */ + D = ldprime - LambdaSol; /* sec 67 #2 */ + return(50.0 * (1 - cos(dtor(D)))); /* sec 67 #3 */ } /* @@ -196,3 +209,74 @@ adj360(deg) else break; } + +#define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2; +time_t +parsetime(p) + char *p; +{ + struct tm *lt; + int bigyear; + int yearset = 0; + time_t tval; + unsigned char *t; + + for (t = p; *t; ++t) { + if (isdigit(*t)) + continue; + badformat(); + } + + tval = time(NULL); + lt = localtime(&tval); + lt->tm_sec = 0; + lt->tm_min = 0; + + switch (strlen(p)) { + case 10: /* yyyy */ + bigyear = ATOI2(p); + lt->tm_year = bigyear * 100 - 1900; + yearset = 1; + /* FALLTHROUGH */ + case 8: /* yy */ + if (yearset) { + lt->tm_year += ATOI2(p); + } else { + lt->tm_year = ATOI2(p); + if (lt->tm_year < 69) /* hack for 2000 */ + lt->tm_year += 100; + } + /* FALLTHROUGH */ + case 6: /* mm */ + lt->tm_mon = ATOI2(p); + if ((lt->tm_mon > 12) || !lt->tm_mon) + badformat(); + --lt->tm_mon; /* time struct is 0 - 11 */ + /* FALLTHROUGH */ + case 4: /* dd */ + lt->tm_mday = ATOI2(p); + if ((lt->tm_mday > 31) || !lt->tm_mday) + badformat(); + /* FALLTHROUGH */ + case 2: /* HH */ + lt->tm_hour = ATOI2(p); + if (lt->tm_hour > 23) + badformat(); + break; + default: + badformat(); + } + /* The calling code needs a valid tm_ydays and this is the easiest + * way to get one */ + if ((tval = mktime(lt)) == -1) + errx(1, "specified date is outside allowed range"); + return (tval); +} + +void +badformat() +{ + warnx("illegal time format"); + (void)fprintf(stderr, "usage: pom [[[[[cc]yy]mm]dd]HH]\n"); + exit(1); +}