1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34: #include <sys/cdefs.h>
35: #ifndef lint
36: __COPYRIGHT("@(#) Copyright (c) 1989, 1993\n\
37: The Regents of the University of California. All rights reserved.\n");
38: #endif
39:
40: #ifndef lint
41: #if 0
42: static char sccsid[] = "@(#)pom.c 8.1 (Berkeley) 5/31/93";
43: #else
44: __RCSID("$NetBSD: pom.c,v 1.14 2004/01/27 20:30:30 jsm Exp $");
45: #endif
46: #endif
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60: #include <ctype.h>
61: #include <err.h>
62: #include <math.h>
63: #include <stdio.h>
64: #include <string.h>
65: #include <stdlib.h>
66: #include <time.h>
67: #include <unistd.h>
68:
69: #ifndef PI
70: #define PI 3.14159265358979323846
71: #endif
72:
73:
74:
75:
76:
77:
78:
79: #define EPOCH_MINUS_1970 (20 * 365 + 5 - 1)
80: #define EPSILONg 279.403303
81: #define RHOg 282.768422
82: #define ECCEN 0.016713
83: #define lzero 318.351648
84: #define Pzero 36.340410
85: #define Nzero 318.510107
86:
87: void adj360(double *);
88: double dtor(double);
89: int main(int, char *[]);
90: double potm(double);
91: time_t parsetime(char *);
92: void badformat(void) __attribute__((__noreturn__));
93:
94: int
95: main(argc, argv)
96: int argc;
97: char *argv[];
98: {
99: time_t tmpt, now;
100: double days, today, tomorrow;
101: char buf[1024];
102:
103:
104: setregid(getgid(), getgid());
105:
106: if (time(&now) == (time_t)-1)
107: err(1, "time");
108: if (argc > 1) {
109: tmpt = parsetime(argv[1]);
110: strftime(buf, sizeof(buf), "%a %Y %b %e %H:%M:%S (%Z)",
111: localtime(&tmpt));
112: printf("%s: ", buf);
113: } else {
114: tmpt = now;
115: }
116: days = (tmpt - EPOCH_MINUS_1970 * 86400) / 86400.0;
117: today = potm(days) + .5;
118: if (tmpt < now)
119: (void)printf("The Moon was ");
120: else if (tmpt == now)
121: (void)printf("The Moon is ");
122: else
123: (void)printf("The Moon will be ");
124: if ((int)today == 100)
125: (void)printf("Full\n");
126: else if (!(int)today)
127: (void)printf("New\n");
128: else {
129: tomorrow = potm(days + 1);
130: if ((int)today == 50)
131: (void)printf("%s\n", tomorrow > today ?
132: "at the First Quarter" : "at the Last Quarter");
133:
134:
135:
136: else {
137: today -= 0.5;
138: (void)printf("%s ", tomorrow > today ?
139: "Waxing" : "Waning");
140: if (today > 50)
141: (void)printf("Gibbous (%1.0f%% of Full)\n",
142: today);
143: else if (today < 50)
144: (void)printf("Crescent (%1.0f%% of Full)\n",
145: today);
146: }
147: }
148: exit(0);
149: }
150:
151:
152:
153:
154:
155: double
156: potm(days)
157: double days;
158: {
159: double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime;
160: double A4, lprime, V, ldprime, D, Nm;
161:
162: N = 360 * days / 365.242191;
163: adj360(&N);
164: Msol = N + EPSILONg - RHOg;
165: adj360(&Msol);
166: Ec = 360 / PI * ECCEN * sin(dtor(Msol));
167: LambdaSol = N + Ec + EPSILONg;
168: adj360(&LambdaSol);
169: l = 13.1763966 * days + lzero;
170: adj360(&l);
171: Mm = l - (0.1114041 * days) - Pzero;
172: adj360(&Mm);
173: Nm = Nzero - (0.0529539 * days);
174: adj360(&Nm);
175: Ev = 1.2739 * sin(dtor(2*(l - LambdaSol) - Mm));
176: Ac = 0.1858 * sin(dtor(Msol));
177: A3 = 0.37 * sin(dtor(Msol));
178: Mmprime = Mm + Ev - Ac - A3;
179: Ec = 6.2886 * sin(dtor(Mmprime));
180: A4 = 0.214 * sin(dtor(2 * Mmprime));
181: lprime = l + Ev + Ec - Ac + A4;
182: V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol)));
183: ldprime = lprime + V;
184: D = ldprime - LambdaSol;
185: return(50.0 * (1 - cos(dtor(D))));
186: }
187:
188:
189:
190:
191:
192: double
193: dtor(deg)
194: double deg;
195: {
196: return(deg * PI / 180);
197: }
198:
199:
200:
201:
202:
203: void
204: adj360(deg)
205: double *deg;
206: {
207: for (;;)
208: if (*deg < 0)
209: *deg += 360;
210: else if (*deg > 360)
211: *deg -= 360;
212: else
213: break;
214: }
215:
216: #define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2;
217: time_t
218: parsetime(p)
219: char *p;
220: {
221: struct tm *lt;
222: int bigyear;
223: int yearset = 0;
224: time_t tval;
225: unsigned char *t;
226:
227: for (t = (unsigned char *)p; *t; ++t) {
228: if (isdigit(*t))
229: continue;
230: badformat();
231: }
232:
233: tval = time(NULL);
234: lt = localtime(&tval);
235: lt->tm_sec = 0;
236: lt->tm_min = 0;
237:
238: switch (strlen(p)) {
239: case 10:
240: bigyear = ATOI2(p);
241: lt->tm_year = bigyear * 100 - 1900;
242: yearset = 1;
243:
244: case 8:
245: if (yearset) {
246: lt->tm_year += ATOI2(p);
247: } else {
248: lt->tm_year = ATOI2(p);
249: if (lt->tm_year < 69)
250: lt->tm_year += 100;
251: }
252:
253: case 6:
254: lt->tm_mon = ATOI2(p);
255: if ((lt->tm_mon > 12) || !lt->tm_mon)
256: badformat();
257: --lt->tm_mon;
258:
259: case 4:
260: lt->tm_mday = ATOI2(p);
261: if ((lt->tm_mday > 31) || !lt->tm_mday)
262: badformat();
263:
264: case 2:
265: lt->tm_hour = ATOI2(p);
266: if (lt->tm_hour > 23)
267: badformat();
268: break;
269: default:
270: badformat();
271: }
272:
273:
274: if ((tval = mktime(lt)) == -1)
275: errx(1, "specified date is outside allowed range");
276: return (tval);
277: }
278:
279: void
280: badformat()
281: {
282: warnx("illegal time format");
283: (void)fprintf(stderr, "usage: pom [[[[[cc]yy]mm]dd]HH]\n");
284: exit(1);
285: }