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