xref: /plan9/sys/src/cmd/astro/pdate.c (revision 59cc4ca53493a3c6d2349fe2b7f7c40f7dce7294)
13e12c5d1SDavid du Colombier #include "astro.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier 
43e12c5d1SDavid du Colombier char*	month[] =
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier 	"January",
73e12c5d1SDavid du Colombier 	"February",
83e12c5d1SDavid du Colombier 	"March",
93e12c5d1SDavid du Colombier 	"April",
103e12c5d1SDavid du Colombier 	"May",
113e12c5d1SDavid du Colombier 	"June",
123e12c5d1SDavid du Colombier 	"July",
133e12c5d1SDavid du Colombier 	"August",
143e12c5d1SDavid du Colombier 	"September",
153e12c5d1SDavid du Colombier 	"October",
163e12c5d1SDavid du Colombier 	"November",
173e12c5d1SDavid du Colombier 	"December",
183e12c5d1SDavid du Colombier };
193e12c5d1SDavid du Colombier 
203e12c5d1SDavid du Colombier double
dsrc(double d,Tim * t,int i)213e12c5d1SDavid du Colombier dsrc(double d, Tim *t, int i)
223e12c5d1SDavid du Colombier {
233e12c5d1SDavid du Colombier 	double y;
243e12c5d1SDavid du Colombier 
253e12c5d1SDavid du Colombier 	do {
263e12c5d1SDavid du Colombier 		t->ifa[i] += 1.;
273e12c5d1SDavid du Colombier 		y = convdate(t);
283e12c5d1SDavid du Colombier 	} while(d >= y);
293e12c5d1SDavid du Colombier 	do {
303e12c5d1SDavid du Colombier 		t->ifa[i] -= 1.;
313e12c5d1SDavid du Colombier 		y = convdate(t);
323e12c5d1SDavid du Colombier 	} while(d < y);
333e12c5d1SDavid du Colombier 	return d - y;
343e12c5d1SDavid du Colombier }
353e12c5d1SDavid du Colombier 
363e12c5d1SDavid du Colombier void
dtsetup(double d,Tim * t)373e12c5d1SDavid du Colombier dtsetup(double d, Tim *t)
383e12c5d1SDavid du Colombier {
393e12c5d1SDavid du Colombier 	double v;
403e12c5d1SDavid du Colombier 
41*59cc4ca5SDavid du Colombier 	t->ifa[0] = floor(1900 + d/365.24220);
423e12c5d1SDavid du Colombier 	t->ifa[1] = 1;
433e12c5d1SDavid du Colombier 	t->ifa[2] = 1;
443e12c5d1SDavid du Colombier 	t->ifa[3] = 0;
453e12c5d1SDavid du Colombier 	t->ifa[4] = 0;
463e12c5d1SDavid du Colombier 	t->ifa[1] = floor(1 + dsrc(d, t, 0)/30);
473e12c5d1SDavid du Colombier 	t->ifa[2] = floor(1 + dsrc(d, t, 1));
483e12c5d1SDavid du Colombier 	dsrc(d, t, 2);
493e12c5d1SDavid du Colombier 
503e12c5d1SDavid du Colombier 	v = (d - convdate(t)) * 24;
513e12c5d1SDavid du Colombier 	t->ifa[3] = floor(v);
523e12c5d1SDavid du Colombier 	t->ifa[4] = (v - t->ifa[3]) * 60;
533e12c5d1SDavid du Colombier 	convdate(t);	/* to set timezone */
543e12c5d1SDavid du Colombier }
553e12c5d1SDavid du Colombier 
563e12c5d1SDavid du Colombier void
pdate(double d)573e12c5d1SDavid du Colombier pdate(double d)
583e12c5d1SDavid du Colombier {
593e12c5d1SDavid du Colombier 	int i;
603e12c5d1SDavid du Colombier 	Tim t;
613e12c5d1SDavid du Colombier 
623e12c5d1SDavid du Colombier 	dtsetup(d, &t);
633e12c5d1SDavid du Colombier 	if(flags['s']) {
643e12c5d1SDavid du Colombier 		i = t.ifa[1];
653e12c5d1SDavid du Colombier 		print("%s ", month[i-1]);
663e12c5d1SDavid du Colombier 		i = t.ifa[2];
673e12c5d1SDavid du Colombier 		numb(i);
683e12c5d1SDavid du Colombier 		print("...");
693e12c5d1SDavid du Colombier 		return;
703e12c5d1SDavid du Colombier 	}
71*59cc4ca5SDavid du Colombier 
723e12c5d1SDavid du Colombier 	/* year month day */
733e12c5d1SDavid du Colombier 	print("%4d %2d %2d",
743e12c5d1SDavid du Colombier 		(int)t.ifa[0],
753e12c5d1SDavid du Colombier 		(int)t.ifa[1],
763e12c5d1SDavid du Colombier 		(int)t.ifa[2]);
773e12c5d1SDavid du Colombier }
783e12c5d1SDavid du Colombier 
793e12c5d1SDavid du Colombier void
ptime(double d)803e12c5d1SDavid du Colombier ptime(double d)
813e12c5d1SDavid du Colombier {
823e12c5d1SDavid du Colombier 	int h, m, s;
833e12c5d1SDavid du Colombier 	char *mer;
843e12c5d1SDavid du Colombier 	Tim t;
853e12c5d1SDavid du Colombier 
863e12c5d1SDavid du Colombier 	if(flags['s']) {
873e12c5d1SDavid du Colombier 		/* hour minute */
883e12c5d1SDavid du Colombier 		dtsetup(d + .5/(24*60), &t);
893e12c5d1SDavid du Colombier 		h = t.ifa[3];
903e12c5d1SDavid du Colombier 		m = floor(t.ifa[4]);
913e12c5d1SDavid du Colombier 
923e12c5d1SDavid du Colombier 		mer = "AM";
933e12c5d1SDavid du Colombier 		if(h >= 12) {
943e12c5d1SDavid du Colombier 			mer = "PM";
953e12c5d1SDavid du Colombier 			h -= 12;
963e12c5d1SDavid du Colombier 		}
973e12c5d1SDavid du Colombier 		if(h == 0)
983e12c5d1SDavid du Colombier 			h = 12;
993e12c5d1SDavid du Colombier 		numb(h);
1003e12c5d1SDavid du Colombier 		if(m < 10) {
1013e12c5d1SDavid du Colombier 			if(m == 0) {
1023e12c5d1SDavid du Colombier 				print("%s exactly ...", mer);
1033e12c5d1SDavid du Colombier 				return;
1043e12c5d1SDavid du Colombier 			}
1053e12c5d1SDavid du Colombier 			print("O ");
1063e12c5d1SDavid du Colombier 		}
1073e12c5d1SDavid du Colombier 		numb(m);
1083e12c5d1SDavid du Colombier 		print("%s ...", mer);
1093e12c5d1SDavid du Colombier 		return;
1103e12c5d1SDavid du Colombier 	}
1113e12c5d1SDavid du Colombier 	/* hour minute second */
1123e12c5d1SDavid du Colombier 	dtsetup(d, &t);
1133e12c5d1SDavid du Colombier 	h = t.ifa[3];
1143e12c5d1SDavid du Colombier 	m = floor(t.ifa[4]);
1153e12c5d1SDavid du Colombier 	s = floor((t.ifa[4]-m) * 60);
116*59cc4ca5SDavid du Colombier 	print("%.2d:%.2d:%.2d %.*s", h, m, s, utfnlen(t.tz, 3), t.tz);
1173e12c5d1SDavid du Colombier }
1183e12c5d1SDavid du Colombier 
1193e12c5d1SDavid du Colombier char*	unit[] =
1203e12c5d1SDavid du Colombier {
1213e12c5d1SDavid du Colombier 	"zero",
1223e12c5d1SDavid du Colombier 	"one",
1233e12c5d1SDavid du Colombier 	"two",
1243e12c5d1SDavid du Colombier 	"three",
1253e12c5d1SDavid du Colombier 	"four",
1263e12c5d1SDavid du Colombier 	"five",
1273e12c5d1SDavid du Colombier 	"six",
1283e12c5d1SDavid du Colombier 	"seven",
1293e12c5d1SDavid du Colombier 	"eight",
1303e12c5d1SDavid du Colombier 	"nine",
1313e12c5d1SDavid du Colombier 	"ten",
1323e12c5d1SDavid du Colombier 	"eleven",
1333e12c5d1SDavid du Colombier 	"twelve",
1343e12c5d1SDavid du Colombier 	"thirteen",
1353e12c5d1SDavid du Colombier 	"fourteen",
1363e12c5d1SDavid du Colombier 	"fifteen",
1373e12c5d1SDavid du Colombier 	"sixteen",
1383e12c5d1SDavid du Colombier 	"seventeen",
1393e12c5d1SDavid du Colombier 	"eighteen",
1403e12c5d1SDavid du Colombier 	"nineteen"
1413e12c5d1SDavid du Colombier };
1423e12c5d1SDavid du Colombier char*	decade[] =
1433e12c5d1SDavid du Colombier {
1443e12c5d1SDavid du Colombier 	"twenty",
1453e12c5d1SDavid du Colombier 	"thirty",
1463e12c5d1SDavid du Colombier 	"forty",
1473e12c5d1SDavid du Colombier 	"fifty",
1483e12c5d1SDavid du Colombier 	"sixty",
1493e12c5d1SDavid du Colombier 	"seventy",
1503e12c5d1SDavid du Colombier 	"eighty",
1513e12c5d1SDavid du Colombier 	"ninety"
1523e12c5d1SDavid du Colombier };
1533e12c5d1SDavid du Colombier 
1543e12c5d1SDavid du Colombier void
pstime(double d)155*59cc4ca5SDavid du Colombier pstime(double d)
156*59cc4ca5SDavid du Colombier {
157*59cc4ca5SDavid du Colombier 
158*59cc4ca5SDavid du Colombier 	setime(d);
159*59cc4ca5SDavid du Colombier 
160*59cc4ca5SDavid du Colombier 	semi = 0;
161*59cc4ca5SDavid du Colombier 	motion = 0;
162*59cc4ca5SDavid du Colombier 	rad = 1.e9;
163*59cc4ca5SDavid du Colombier 	lambda = 0;
164*59cc4ca5SDavid du Colombier 	beta = 0;
165*59cc4ca5SDavid du Colombier 
166*59cc4ca5SDavid du Colombier // uses lambda, beta, rad, motion
167*59cc4ca5SDavid du Colombier // sets alpha, delta, rp
168*59cc4ca5SDavid du Colombier 
169*59cc4ca5SDavid du Colombier 	helio();
170*59cc4ca5SDavid du Colombier 
171*59cc4ca5SDavid du Colombier // uses alpha, delta, rp
172*59cc4ca5SDavid du Colombier // sets ra, decl, lha, decl2, az, el
173*59cc4ca5SDavid du Colombier 
174*59cc4ca5SDavid du Colombier 	geo();
175*59cc4ca5SDavid du Colombier 
176*59cc4ca5SDavid du Colombier 	print(" %R %D %D %4.0f", lha, nlat, awlong, elev/3.28084);
177*59cc4ca5SDavid du Colombier }
178*59cc4ca5SDavid du Colombier 
179*59cc4ca5SDavid du Colombier void
numb(int n)1803e12c5d1SDavid du Colombier numb(int n)
1813e12c5d1SDavid du Colombier {
1823e12c5d1SDavid du Colombier 
1833e12c5d1SDavid du Colombier 	if(n >= 100) {
1847dd7cddfSDavid du Colombier 		print("%d ", n);
1853e12c5d1SDavid du Colombier 		return;
1863e12c5d1SDavid du Colombier 	}
1873e12c5d1SDavid du Colombier 	if(n >= 20) {
1883e12c5d1SDavid du Colombier 		print("%s ", decade[n/10 - 2]);
1893e12c5d1SDavid du Colombier 		n %= 10;
1903e12c5d1SDavid du Colombier 		if(n == 0)
1913e12c5d1SDavid du Colombier 			return;
1923e12c5d1SDavid du Colombier 	}
1933e12c5d1SDavid du Colombier 	print("%s ", unit[n]);
1943e12c5d1SDavid du Colombier }
1953e12c5d1SDavid du Colombier 
1963e12c5d1SDavid du Colombier double
tzone(double y,Tim * z)1973e12c5d1SDavid du Colombier tzone(double y, Tim *z)
1983e12c5d1SDavid du Colombier {
1993e12c5d1SDavid du Colombier 	double t, l1, l2;
2003e12c5d1SDavid du Colombier 	Tm t1, t2;
2013e12c5d1SDavid du Colombier 
2023e12c5d1SDavid du Colombier 	/*
2033e12c5d1SDavid du Colombier 	 * get a rough approximation to unix mean time
2043e12c5d1SDavid du Colombier 	 */
2053e12c5d1SDavid du Colombier 	t = (y - 25567.5) * 86400;
2063e12c5d1SDavid du Colombier 
2073e12c5d1SDavid du Colombier 	/*
2083e12c5d1SDavid du Colombier 	 * if outside unix conversions,
2093e12c5d1SDavid du Colombier 	 * just call it GMT
2103e12c5d1SDavid du Colombier 	 */
2113e12c5d1SDavid du Colombier 	if(t < 0 || t > 2.1e9)
2123e12c5d1SDavid du Colombier 		return y;
2133e12c5d1SDavid du Colombier 
2143e12c5d1SDavid du Colombier 	/*
2153e12c5d1SDavid du Colombier 	 * convert by both local and gmt
2163e12c5d1SDavid du Colombier 	 */
2173e12c5d1SDavid du Colombier 	t1 = *localtime((long)t);
2183e12c5d1SDavid du Colombier 	t2 = *gmtime((long)t);
2193e12c5d1SDavid du Colombier 
2203e12c5d1SDavid du Colombier 	/*
2213e12c5d1SDavid du Colombier 	 * pick up year crossings
2223e12c5d1SDavid du Colombier 	 */
2233e12c5d1SDavid du Colombier 	if(t1.yday == 0 && t2.yday > 1)
2243e12c5d1SDavid du Colombier 		t1.yday = t2.yday+1;
2253e12c5d1SDavid du Colombier 	if(t2.yday == 0 && t1.yday > 1)
2263e12c5d1SDavid du Colombier 		t2.yday = t1.yday+1;
2273e12c5d1SDavid du Colombier 
2283e12c5d1SDavid du Colombier 	/*
2293e12c5d1SDavid du Colombier 	 * convert times to days
2303e12c5d1SDavid du Colombier 	 */
2313e12c5d1SDavid du Colombier 	l1 = t1.yday + t1.hour/24. + t1.min/1440. + t1.sec/86400.;
2323e12c5d1SDavid du Colombier 	l2 = t2.yday + t2.hour/24. + t2.min/1440. + t2.sec/86400.;
2333e12c5d1SDavid du Colombier 
2343e12c5d1SDavid du Colombier 	/*
2353e12c5d1SDavid du Colombier 	 * return difference
2363e12c5d1SDavid du Colombier 	 */
2373e12c5d1SDavid du Colombier 	strncpy(z->tz, t1.zone, sizeof(z->tz));
2383e12c5d1SDavid du Colombier 	return y + (l2 - l1);
2393e12c5d1SDavid du Colombier }
2403e12c5d1SDavid du Colombier 
2413e12c5d1SDavid du Colombier int	dmo[12] =
2423e12c5d1SDavid du Colombier {
2433e12c5d1SDavid du Colombier 	0,
2443e12c5d1SDavid du Colombier 	31,
2453e12c5d1SDavid du Colombier 	59,
2463e12c5d1SDavid du Colombier 	90,
2473e12c5d1SDavid du Colombier 	120,
2483e12c5d1SDavid du Colombier 	151,
2493e12c5d1SDavid du Colombier 	181,
2503e12c5d1SDavid du Colombier 	212,
2513e12c5d1SDavid du Colombier 	243,
2523e12c5d1SDavid du Colombier 	273,
2533e12c5d1SDavid du Colombier 	304,
2543e12c5d1SDavid du Colombier 	334
2553e12c5d1SDavid du Colombier };
2563e12c5d1SDavid du Colombier 
2573e12c5d1SDavid du Colombier /*
2583e12c5d1SDavid du Colombier  * input date conversion
2593e12c5d1SDavid du Colombier  * output is done by zero crossing
2603e12c5d1SDavid du Colombier  * on this input conversion.
2613e12c5d1SDavid du Colombier  */
2623e12c5d1SDavid du Colombier double
convdate(Tim * t)2633e12c5d1SDavid du Colombier convdate(Tim *t)
2643e12c5d1SDavid du Colombier {
2653e12c5d1SDavid du Colombier 	double y, d;
2663e12c5d1SDavid du Colombier 	int m;
2673e12c5d1SDavid du Colombier 
2683e12c5d1SDavid du Colombier 	y = t->ifa[0];
2693e12c5d1SDavid du Colombier 	m = t->ifa[1];
2703e12c5d1SDavid du Colombier 	d = t->ifa[2];
2713e12c5d1SDavid du Colombier 
2723e12c5d1SDavid du Colombier 	/*
2733e12c5d1SDavid du Colombier 	 * normalize the month
2743e12c5d1SDavid du Colombier 	 */
2753e12c5d1SDavid du Colombier 	while(m < 1) {
2763e12c5d1SDavid du Colombier 		m += 12;
2773e12c5d1SDavid du Colombier 		y -= 1;
2783e12c5d1SDavid du Colombier 	}
2793e12c5d1SDavid du Colombier 	while(m > 12) {
2803e12c5d1SDavid du Colombier 		m -= 12;
2813e12c5d1SDavid du Colombier 		y += 1;
2823e12c5d1SDavid du Colombier 	}
2833e12c5d1SDavid du Colombier 
2843e12c5d1SDavid du Colombier 	/*
2853e12c5d1SDavid du Colombier 	 * bc correction
2863e12c5d1SDavid du Colombier 	 */
2873e12c5d1SDavid du Colombier 	if(y < 0)
2883e12c5d1SDavid du Colombier 		y += 1;
2893e12c5d1SDavid du Colombier 
2903e12c5d1SDavid du Colombier 	/*
2913e12c5d1SDavid du Colombier 	 * normal conversion
2923e12c5d1SDavid du Colombier 	 */
2933e12c5d1SDavid du Colombier 	y += 4712;
2943e12c5d1SDavid du Colombier 	if(fmod(y, 4) == 0 && m > 2)
2953e12c5d1SDavid du Colombier 		d += 1;
2963e12c5d1SDavid du Colombier 	y = y*365 + floor((y+3)/4) + dmo[m-1] + d - 1;
2973e12c5d1SDavid du Colombier 
2983e12c5d1SDavid du Colombier 	/*
2993e12c5d1SDavid du Colombier 	 * gregorian change
3003e12c5d1SDavid du Colombier 	 */
3013e12c5d1SDavid du Colombier 	if(y > 2361232)
302*59cc4ca5SDavid du Colombier 		y -= floor((y-1794167)/36524.220) -
3033e12c5d1SDavid du Colombier 			floor((y-1721117)/146100);
3043e12c5d1SDavid du Colombier 	y += t->ifa[3]/24 + t->ifa[4]/1440 - 2415020.5;
3053e12c5d1SDavid du Colombier 
3063e12c5d1SDavid du Colombier 	/*
3073e12c5d1SDavid du Colombier 	 * kitchen clock correction
3083e12c5d1SDavid du Colombier 	 */
3093e12c5d1SDavid du Colombier 	strncpy(t->tz, "GMT", sizeof(t->tz));
3103e12c5d1SDavid du Colombier 	if(flags['k'])
3113e12c5d1SDavid du Colombier 		y = tzone(y, t);
3123e12c5d1SDavid du Colombier 	return y;
3133e12c5d1SDavid du Colombier }
314