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