sunpos.c revision 205821
1205821Sedwin/*-
2205821Sedwin * Copyright (c) 2009-2010 Edwin Groothuis. All rights reserved.
3205821Sedwin *
4205821Sedwin * Redistribution and use in source and binary forms, with or without
5205821Sedwin * modification, are permitted provided that the following conditions
6205821Sedwin * are met:
7205821Sedwin * 1. Redistributions of source code must retain the above copyright
8205821Sedwin *    notice, this list of conditions and the following disclaimer.
9205821Sedwin * 2. Redistributions in binary form must reproduce the above copyright
10205821Sedwin *    notice, this list of conditions and the following disclaimer in the
11205821Sedwin *    documentation and/or other materials provided with the distribution.
12205821Sedwin *
13205821Sedwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14205821Sedwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15205821Sedwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16205821Sedwin * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17205821Sedwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18205821Sedwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19205821Sedwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20205821Sedwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21205821Sedwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22205821Sedwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23205821Sedwin * SUCH DAMAGE.
24205821Sedwin *
25205821Sedwin */
26205821Sedwin
27205821Sedwin#include <sys/cdefs.h>
28205821Sedwin__FBSDID("$FreeBSD: head/usr.bin/calendar/sunpos.c 205821 2010-03-29 06:49:20Z edwin $");
29205821Sedwin
30205821Sedwin/*
31205821Sedwin * This code is created to match the formulas available at:
32205821Sedwin * Formula and examples obtained from "How to Calculate alt/az: SAAO" at
33205821Sedwin * http://www.saao.ac.za/public-info/sun-moon-stars/sun-index/how-to-calculate-altaz/
34205821Sedwin */
35205821Sedwin
36205821Sedwin#include <stdio.h>
37205821Sedwin#include <stdlib.h>
38205821Sedwin#include <limits.h>
39205821Sedwin#include <math.h>
40205821Sedwin#include <string.h>
41205821Sedwin#include <time.h>
42205821Sedwin#include "calendar.h"
43205821Sedwin
44205821Sedwin#define D2R(m)	((m) / 180 * M_PI)
45205821Sedwin#define R2D(m)	((m) * 180 / M_PI)
46205821Sedwin
47205821Sedwin#define	SIN(x)	(sin(D2R(x)))
48205821Sedwin#define	COS(x)	(cos(D2R(x)))
49205821Sedwin#define	TAN(x)	(tan(D2R(x)))
50205821Sedwin#define	ASIN(x)	(R2D(asin(x)))
51205821Sedwin#define	ATAN(x)	(R2D(atan(x)))
52205821Sedwin
53205821Sedwin#ifdef NOTDEF
54205821Sedwinstatic void
55205821Sedwincomp(char *s, double v, double c)
56205821Sedwin{
57205821Sedwin
58205821Sedwin	printf("%-*s %*g %*g %*g\n", 15, s, 15, v, 15, c, 15, v - c);
59205821Sedwin}
60205821Sedwin
61205821Sedwinint expY;
62205821Sedwindouble expZJ = 30.5;
63205821Sedwindouble expUTHM = 8.5;
64205821Sedwindouble expD = 34743.854;
65205821Sedwindouble expT = 0.9512349;
66205821Sedwindouble expL = 324.885;
67205821Sedwindouble expM = 42.029;
68205821Sedwindouble expepsilon = 23.4396;
69205821Sedwindouble explambda = 326.186;
70205821Sedwindouble expalpha = 328.428;
71205821Sedwindouble expDEC = -12.789;
72205821Sedwindouble expeastlongitude = 17.10;
73205821Sedwindouble explatitude = -22.57;
74205821Sedwindouble expHA = -37.673;
75205821Sedwindouble expALT = 49.822;
76205821Sedwindouble expAZ = 67.49;
77205821Sedwin#endif
78205821Sedwin
79205821Sedwinstatic double
80205821Sedwinfixup(double *d)
81205821Sedwin{
82205821Sedwin
83205821Sedwin	if (*d < 0) {
84205821Sedwin		while (*d < 0)
85205821Sedwin			*d += 360;
86205821Sedwin	} else {
87205821Sedwin		while (*d > 360)
88205821Sedwin			*d -= 360;
89205821Sedwin	}
90205821Sedwin
91205821Sedwin	return (*d);
92205821Sedwin}
93205821Sedwin
94205821Sedwinstatic double ZJtable[] = {
95205821Sedwin	0, -0.5, 30.5, 58.5, 89.5, 119.5, 150.5, 180.5, 211.5, 242.5, 272.5, 303.5, 333.5 };
96205821Sedwin
97205821Sedwinstatic void
98205821Sedwinsunpos(int inYY, int inMM, int inDD, double UTCOFFSET, int inHOUR, int inMIN,
99205821Sedwin    int inSEC, double eastlongitude, double latitude, double *L, double *DEC)
100205821Sedwin{
101205821Sedwin	int Y;
102205821Sedwin	double ZJ, D, T, M, epsilon, lambda, alpha, HA, UTHM;
103205821Sedwin
104205821Sedwin	ZJ = ZJtable[inMM];
105205821Sedwin	if (inMM <= 2 && isleap(inYY))
106205821Sedwin		ZJ -= 1.0;
107205821Sedwin
108205821Sedwin	UTHM = inHOUR + inMIN / FMINSPERHOUR + inSEC / FSECSPERHOUR - UTCOFFSET;
109205821Sedwin	Y = inYY - 1900;						/*  1 */
110205821Sedwin	D = floor(365.25 * Y) + ZJ + inDD + UTHM / FHOURSPERDAY;	/*  3 */
111205821Sedwin	T = D / 36525.0;						/*  4 */
112205821Sedwin	*L = 279.697 + 36000.769 * T;					/*  5 */
113205821Sedwin	fixup(L);
114205821Sedwin	M = 358.476 + 35999.050 * T;					/*  6 */
115205821Sedwin	fixup(&M);
116205821Sedwin	epsilon = 23.452 - 0.013 * T;					/*  7 */
117205821Sedwin	fixup(&epsilon);
118205821Sedwin
119205821Sedwin	lambda = *L + (1.919 - 0.005 * T) * SIN(M) + 0.020 * SIN(2 * M);/*  8 */
120205821Sedwin	fixup(&lambda);
121205821Sedwin	alpha = ATAN(TAN(lambda) * COS(epsilon));			/*  9 */
122205821Sedwin
123205821Sedwin	/* Alpha should be in the same quadrant as lamba */
124205821Sedwin	{
125205821Sedwin		int lssign = sin(D2R(lambda)) < 0 ? -1 : 1;
126205821Sedwin		int lcsign = cos(D2R(lambda)) < 0 ? -1 : 1;
127205821Sedwin		while (((sin(D2R(alpha)) < 0) ? -1 : 1) != lssign
128205821Sedwin		    || ((cos(D2R(alpha)) < 0) ? -1 : 1) != lcsign)
129205821Sedwin			alpha += 90.0;
130205821Sedwin	}
131205821Sedwin	fixup(&alpha);
132205821Sedwin
133205821Sedwin	*DEC = ASIN(SIN(lambda) * SIN(epsilon));			/* 10 */
134205821Sedwin	fixup(DEC);
135205821Sedwin	fixup(&eastlongitude);
136205821Sedwin	HA = *L - alpha + 180 + 15 * UTHM + eastlongitude;		/* 12 */
137205821Sedwin	fixup(&HA);
138205821Sedwin	fixup(&latitude);
139205821Sedwin#ifdef NOTDEF
140205821Sedwin	printf("%02d/%02d %02d:%02d:%02d l:%g d:%g h:%g\n",
141205821Sedwin	    inMM, inDD, inHOUR, inMIN, inSEC, latitude, *DEC, HA);
142205821Sedwin#endif
143205821Sedwin	return;
144205821Sedwin
145205821Sedwin	/*
146205821Sedwin	 * The following calculations are not used, so to save time
147205821Sedwin	 * they are not calculated.
148205821Sedwin	 */
149205821Sedwin#ifdef NOTDEF
150205821Sedwin	*ALT = ASIN(SIN(latitude) * SIN(*DEC) +
151205821Sedwin	    COS(latitude) * COS(*DEC) * COS(HA));			/* 13 */
152205821Sedwin	fixup(ALT);
153205821Sedwin	*AZ = ATAN(SIN(HA) /
154205821Sedwin	    (COS(HA) * SIN(latitude) - TAN(*DEC) * COS(latitude)));	/* 14 */
155205821Sedwin
156205821Sedwin	if (*ALT > 180)
157205821Sedwin		*ALT -= 360;
158205821Sedwin	if (*ALT < -180)
159205821Sedwin		*ALT += 360;
160205821Sedwin	printf("a:%g a:%g\n", *ALT, *AZ);
161205821Sedwin#endif
162205821Sedwin
163205821Sedwin#ifdef NOTDEF
164205821Sedwin	printf("Y:\t\t\t     %d\t\t     %d\t\t      %d\n", Y, expY, Y - expY);
165205821Sedwin	comp("ZJ", ZJ, expZJ);
166205821Sedwin	comp("UTHM", UTHM, expUTHM);
167205821Sedwin	comp("D", D, expD);
168205821Sedwin	comp("T", T, expT);
169205821Sedwin	comp("L", L, fixup(&expL));
170205821Sedwin	comp("M", M, fixup(&expM));
171205821Sedwin	comp("epsilon", epsilon, fixup(&expepsilon));
172205821Sedwin	comp("lambda", lambda, fixup(&explambda));
173205821Sedwin	comp("alpha", alpha, fixup(&expalpha));
174205821Sedwin	comp("DEC", DEC, fixup(&expDEC));
175205821Sedwin	comp("eastlongitude", eastlongitude, fixup(&expeastlongitude));
176205821Sedwin	comp("latitude", latitude, fixup(&explatitude));
177205821Sedwin	comp("HA", HA, fixup(&expHA));
178205821Sedwin	comp("ALT", ALT, fixup(&expALT));
179205821Sedwin	comp("AZ", AZ, fixup(&expAZ));
180205821Sedwin#endif
181205821Sedwin}
182205821Sedwin
183205821Sedwin
184205821Sedwin#define	SIGN(a)	(((a) > 180) ? -1 : 1)
185205821Sedwin#define ANGLE(a, b) (((a) < (b)) ? 1 : -1)
186205821Sedwin#define SHOUR(s) ((s) / 3600)
187205821Sedwin#define SMIN(s) (((s) % 3600) / 60)
188205821Sedwin#define SSEC(s) ((s) % 60)
189205821Sedwin#define HOUR(h) ((h) / 4)
190205821Sedwin#define MIN(h) (15 * ((h) % 4))
191205821Sedwin#define SEC(h)	0
192205821Sedwin#define	DEBUG1(y, m, d, hh, mm, pdec, dec) \
193205821Sedwin	printf("%4d-%02d-%02d %02d:%02d:00 - %7.7g -> %7.7g\n", \
194205821Sedwin	    y, m, d, hh, mm, pdec, dec)
195205821Sedwin#define	DEBUG2(y, m, d, hh, mm, pdec, dec, pang, ang) \
196205821Sedwin	printf("%4d-%02d-%02d %02d:%02d:00 - %7.7g -> %7.7g - %d -> %d\n", \
197205821Sedwin	    y, m, d, hh, mm, pdec, dec, pang, ang)
198205821Sedwinvoid
199205821Sedwinequinoxsolstice(int year, double UTCoffset, int *equinoxdays, int *solsticedays)
200205821Sedwin{
201205821Sedwin	double fe[2], fs[2];
202205821Sedwin
203205821Sedwin	fequinoxsolstice(year, UTCoffset, fe, fs);
204205821Sedwin	equinoxdays[0] = round(fe[0]);
205205821Sedwin	equinoxdays[1] = round(fe[1]);
206205821Sedwin	solsticedays[0] = round(fs[0]);
207205821Sedwin	solsticedays[1] = round(fs[1]);
208205821Sedwin}
209205821Sedwin
210205821Sedwinvoid
211205821Sedwinfequinoxsolstice(int year, double UTCoffset, double *equinoxdays, double *solsticedays)
212205821Sedwin{
213205821Sedwin	double dec, prevdec, L;
214205821Sedwin	int h, d, prevangle, angle;
215205821Sedwin	int found = 0;
216205821Sedwin
217205821Sedwin	double decleft, decright, decmiddle;
218205821Sedwin	int dial, s;
219205821Sedwin
220205821Sedwin	int *cumdays;
221205821Sedwin	cumdays = cumdaytab[isleap(year)];
222205821Sedwin
223205821Sedwin	/*
224205821Sedwin	 * Find the first equinox, somewhere in March:
225205821Sedwin	 * It happens when the returned value "dec" goes from
226205821Sedwin	 * [350 ... 360> -> [0 ... 10]
227205821Sedwin	 */
228205821Sedwin	found = 0;
229205821Sedwin	prevdec = 350;
230205821Sedwin	for (d = 18; d < 31; d++) {
231205821Sedwin//		printf("Comparing day %d to %d.\n", d, d+1);
232205821Sedwin		sunpos(year, 3, d, UTCoffset, 0, 0, 0, 0.0, 0.0, &L, &decleft);
233205821Sedwin		sunpos(year, 3, d + 1, UTCoffset, 0, 0, 0, 0.0, 0.0,
234205821Sedwin		    &L, &decright);
235205821Sedwin//		printf("Found %g and %g.\n", decleft, decright);
236205821Sedwin		if (SIGN(decleft) == SIGN(decright))
237205821Sedwin			continue;
238205821Sedwin
239205821Sedwin		dial = SECSPERDAY;
240205821Sedwin		s = SECSPERDAY / 2;
241205821Sedwin		while (s > 0) {
242205821Sedwin//			printf("Obtaining %d (%02d:%02d)\n",
243205821Sedwin//			    dial, SHOUR(dial), SMIN(dial));
244205821Sedwin			sunpos(year, 3, d, UTCoffset,
245205821Sedwin			    SHOUR(dial), SMIN(dial), SSEC(dial),
246205821Sedwin			    0.0, 0.0, &L, &decmiddle);
247205821Sedwin//			printf("Found %g\n", decmiddle);
248205821Sedwin			if (SIGN(decleft) == SIGN(decmiddle)) {
249205821Sedwin				decleft = decmiddle;
250205821Sedwin				dial += s;
251205821Sedwin			} else {
252205821Sedwin				decright = decmiddle;
253205821Sedwin				dial -= s;
254205821Sedwin			}
255205821Sedwin//			printf("New boundaries: %g - %g\n", decleft, decright);
256205821Sedwin
257205821Sedwin			s /= 2;
258205821Sedwin		}
259205821Sedwin		equinoxdays[0] = 1 + cumdays[3] + d + (dial / FSECSPERDAY);
260205821Sedwin		break;
261205821Sedwin	}
262205821Sedwin
263205821Sedwin	/* Find the second equinox, somewhere in September:
264205821Sedwin	 * It happens when the returned value "dec" goes from
265205821Sedwin	 * [10 ... 0] -> <360 ... 350]
266205821Sedwin	 */
267205821Sedwin	found = 0;
268205821Sedwin	prevdec = 10;
269205821Sedwin	for (d = 18; d < 31; d++) {
270205821Sedwin//		printf("Comparing day %d to %d.\n", d, d+1);
271205821Sedwin		sunpos(year, 9, d, UTCoffset, 0, 0, 0, 0.0, 0.0, &L, &decleft);
272205821Sedwin		sunpos(year, 9, d + 1, UTCoffset, 0, 0, 0, 0.0, 0.0,
273205821Sedwin		    &L, &decright);
274205821Sedwin//		printf("Found %g and %g.\n", decleft, decright);
275205821Sedwin		if (SIGN(decleft) == SIGN(decright))
276205821Sedwin			continue;
277205821Sedwin
278205821Sedwin		dial = SECSPERDAY;
279205821Sedwin		s = SECSPERDAY / 2;
280205821Sedwin		while (s > 0) {
281205821Sedwin//			printf("Obtaining %d (%02d:%02d)\n",
282205821Sedwin//			    dial, SHOUR(dial), SMIN(dial));
283205821Sedwin			sunpos(year, 9, d, UTCoffset,
284205821Sedwin			    SHOUR(dial), SMIN(dial), SSEC(dial),
285205821Sedwin			    0.0, 0.0, &L, &decmiddle);
286205821Sedwin//			printf("Found %g\n", decmiddle);
287205821Sedwin			if (SIGN(decleft) == SIGN(decmiddle)) {
288205821Sedwin				decleft = decmiddle;
289205821Sedwin				dial += s;
290205821Sedwin			} else {
291205821Sedwin				decright = decmiddle;
292205821Sedwin				dial -= s;
293205821Sedwin			}
294205821Sedwin//			printf("New boundaries: %g - %g\n", decleft, decright);
295205821Sedwin
296205821Sedwin			s /= 2;
297205821Sedwin		}
298205821Sedwin		equinoxdays[1] = 1 + cumdays[9] + d + (dial / FSECSPERDAY);
299205821Sedwin		break;
300205821Sedwin	}
301205821Sedwin
302205821Sedwin	/*
303205821Sedwin	 * Find the first solstice, somewhere in June:
304205821Sedwin	 * It happens when the returned value "dec" peaks
305205821Sedwin	 * [40 ... 45] -> [45 ... 40]
306205821Sedwin	 */
307205821Sedwin	found = 0;
308205821Sedwin	prevdec = 0;
309205821Sedwin	prevangle = 1;
310205821Sedwin	for (d = 18; d < 31; d++) {
311205821Sedwin		for (h = 0; h < 4 * HOURSPERDAY; h++) {
312205821Sedwin			sunpos(year, 6, d, UTCoffset, HOUR(h), MIN(h), SEC(h),
313205821Sedwin			    0.0, 0.0, &L, &dec);
314205821Sedwin			angle = ANGLE(prevdec, dec);
315205821Sedwin			if (prevangle != angle) {
316205821Sedwin#ifdef NOTDEF
317205821Sedwin				DEBUG2(year, 6, d, HOUR(h), MIN(h),
318205821Sedwin				    prevdec, dec, prevangle, angle);
319205821Sedwin#endif
320205821Sedwin				solsticedays[0] = 1 + cumdays[6] + d +
321205821Sedwin				    ((h / 4.0) / 24.0);
322205821Sedwin				found = 1;
323205821Sedwin				break;
324205821Sedwin			}
325205821Sedwin			prevdec = dec;
326205821Sedwin			prevangle = angle;
327205821Sedwin		}
328205821Sedwin		if (found)
329205821Sedwin			break;
330205821Sedwin	}
331205821Sedwin
332205821Sedwin	/*
333205821Sedwin	 * Find the second solstice, somewhere in December:
334205821Sedwin	 * It happens when the returned value "dec" peaks
335205821Sedwin	 * [315 ... 310] -> [310 ... 315]
336205821Sedwin	 */
337205821Sedwin	found = 0;
338205821Sedwin	prevdec = 360;
339205821Sedwin	prevangle = -1;
340205821Sedwin	for (d = 18; d < 31; d++) {
341205821Sedwin		for (h = 0; h < 4 * HOURSPERDAY; h++) {
342205821Sedwin			sunpos(year, 12, d, UTCoffset, HOUR(h), MIN(h), SEC(h),
343205821Sedwin			    0.0, 0.0, &L, &dec);
344205821Sedwin			angle = ANGLE(prevdec, dec);
345205821Sedwin			if (prevangle != angle) {
346205821Sedwin#ifdef NOTDEF
347205821Sedwin				DEBUG2(year, 12, d, HOUR(h), MIN(h),
348205821Sedwin				    prevdec, dec, prevangle, angle);
349205821Sedwin#endif
350205821Sedwin				solsticedays[1] = 1 + cumdays[12] + d +
351205821Sedwin				    ((h / 4.0) / 24.0);
352205821Sedwin				found = 1;
353205821Sedwin				break;
354205821Sedwin			}
355205821Sedwin			prevdec = dec;
356205821Sedwin			prevangle = angle;
357205821Sedwin		}
358205821Sedwin		if (found)
359205821Sedwin			break;
360205821Sedwin	}
361205821Sedwin
362205821Sedwin	return;
363205821Sedwin}
364205821Sedwin
365205821Sedwinint
366205821Sedwincalculatesunlongitude30(int year, int degreeGMToffset, int *ichinesemonths)
367205821Sedwin{
368205821Sedwin	int m, d, h;
369205821Sedwin	double dec;
370205821Sedwin	double curL, prevL;
371205821Sedwin	int *pichinesemonths, *monthdays, *cumdays, i;
372205821Sedwin	int firstmonth330 = -1;
373205821Sedwin
374205821Sedwin	cumdays = cumdaytab[isleap(year)];
375205821Sedwin	monthdays = mondaytab[isleap(year)];
376205821Sedwin	pichinesemonths = ichinesemonths;
377205821Sedwin
378205821Sedwin	h = 0;
379205821Sedwin	sunpos(year - 1, 12, 31,
380205821Sedwin	    -24 * (degreeGMToffset / 360.0),
381205821Sedwin	    HOUR(h), MIN(h), SEC(h), 0.0, 0.0, &prevL, &dec);
382205821Sedwin
383205821Sedwin	for (m = 1; m <= 12; m++) {
384205821Sedwin		for (d = 1; d <= monthdays[m]; d++) {
385205821Sedwin			for (h = 0; h < 4 * HOURSPERDAY; h++) {
386205821Sedwin				sunpos(year, m, d,
387205821Sedwin				    -24 * (degreeGMToffset / 360.0),
388205821Sedwin				    HOUR(h), MIN(h), SEC(h),
389205821Sedwin				    0.0, 0.0, &curL, &dec);
390205821Sedwin				if (curL < 180 && prevL > 180) {
391205821Sedwin					*pichinesemonths = cumdays[m] + d;
392205821Sedwin#ifdef DEBUG
393205821Sedwinprintf("%04d-%02d-%02d %02d:%02d - %d %g\n",
394205821Sedwin    year, m, d, HOUR(h), MIN(h), *pichinesemonths, curL);
395205821Sedwin#endif
396205821Sedwin					    pichinesemonths++;
397205821Sedwin				} else {
398205821Sedwin					for (i = 0; i <= 360; i += 30)
399205821Sedwin						if (curL > i && prevL < i) {
400205821Sedwin							*pichinesemonths =
401205821Sedwin							    cumdays[m] + d;
402205821Sedwin#ifdef DEBUG
403205821Sedwinprintf("%04d-%02d-%02d %02d:%02d - %d %g\n",
404205821Sedwin    year, m, d, HOUR(h), MIN(h), *pichinesemonths, curL);
405205821Sedwin#endif
406205821Sedwin							if (i == 330)
407205821Sedwin								firstmonth330 = *pichinesemonths;
408205821Sedwin							pichinesemonths++;
409205821Sedwin						}
410205821Sedwin				}
411205821Sedwin				prevL = curL;
412205821Sedwin			}
413205821Sedwin		}
414205821Sedwin	}
415205821Sedwin	*pichinesemonths = -1;
416205821Sedwin	return (firstmonth330);
417205821Sedwin}
418205821Sedwin
419205821Sedwin#ifdef NOTDEF
420205821Sedwinint
421205821Sedwinmain(int argc, char **argv)
422205821Sedwin{
423205821Sedwin/*
424205821Sedwin	year      Mar        June       Sept       Dec
425205821Sedwin	     day   time  day   time  day time  day time
426205821Sedwin	2004  20   06:49  21   00:57  22  16:30 21  12:42
427205821Sedwin	2005  20   12:33  21   06:46  22  22:23 21  18:35
428205821Sedwin	2006  20   18:26  21   12:26  23  04:03 22  00:22
429205821Sedwin	2007  21   00:07  21   18:06  23  09:51 22  06:08
430205821Sedwin	2008  20   05:48  20   23:59  22  15:44 21  12:04
431205821Sedwin	2009  20   11:44  21   05:45  22  21:18 21  17:47
432205821Sedwin	2010  20   17:32  21   11:28  23  03:09 21  23:38
433205821Sedwin	2011  20   23:21  21   17:16  23  09:04 22  05:30
434205821Sedwin	2012  20   05:14  20   23:09  22  14:49 21  11:11
435205821Sedwin	2013  20   11:02  21   05:04  22  20:44 21  17:11
436205821Sedwin	2014  20   16:57  21   10:51  23  02:29 21  23:03
437205821Sedwin	2015  20   22:45  21   16:38  23  08:20 22  04:48
438205821Sedwin	2016  20   04:30  20   22:34  22  14:21 21  10:44
439205821Sedwin	2017  20   10:28  21   04:24  22  20:02 21  16:28
440205821Sedwin*/
441205821Sedwin
442205821Sedwin	int eq[2], sol[2];
443205821Sedwin	equinoxsolstice(strtol(argv[1], NULL, 10), 0.0, eq, sol);
444205821Sedwin	printf("%d - %d - %d - %d\n", eq[0], sol[0], eq[1], sol[1]);
445205821Sedwin	return(0);
446205821Sedwin}
447205821Sedwin#endif
448