|  | #include "astro.h" | 
|  |  | 
|  |  | 
|  | char*	month[] = | 
|  | { | 
|  | "January", | 
|  | "February", | 
|  | "March", | 
|  | "April", | 
|  | "May", | 
|  | "June", | 
|  | "July", | 
|  | "August", | 
|  | "September", | 
|  | "October", | 
|  | "November", | 
|  | "December" | 
|  | }; | 
|  |  | 
|  | double | 
|  | dsrc(double d, Tim *t, int i) | 
|  | { | 
|  | double y; | 
|  |  | 
|  | do { | 
|  | t->ifa[i] += 1.; | 
|  | y = convdate(t); | 
|  | } while(d >= y); | 
|  | do { | 
|  | t->ifa[i] -= 1.; | 
|  | y = convdate(t); | 
|  | } while(d < y); | 
|  | return d - y; | 
|  | } | 
|  |  | 
|  | void | 
|  | dtsetup(double d, Tim *t) | 
|  | { | 
|  | double v; | 
|  |  | 
|  | t->ifa[0] = floor(1900 + d/365.24220); | 
|  | t->ifa[1] = 1; | 
|  | t->ifa[2] = 1; | 
|  | t->ifa[3] = 0; | 
|  | t->ifa[4] = 0; | 
|  | t->ifa[1] = floor(1 + dsrc(d, t, 0)/30); | 
|  | t->ifa[2] = floor(1 + dsrc(d, t, 1)); | 
|  | dsrc(d, t, 2); | 
|  |  | 
|  | v = (d - convdate(t)) * 24; | 
|  | t->ifa[3] = floor(v); | 
|  | t->ifa[4] = (v - t->ifa[3]) * 60; | 
|  | convdate(t);	/* to set timezone */ | 
|  | } | 
|  |  | 
|  | void | 
|  | pdate(double d) | 
|  | { | 
|  | int i; | 
|  | Tim t; | 
|  |  | 
|  | dtsetup(d, &t); | 
|  | if(flags['s']) { | 
|  | i = t.ifa[1]; | 
|  | print("%s ", month[i-1]); | 
|  | i = t.ifa[2]; | 
|  | numb(i); | 
|  | print("..."); | 
|  | return; | 
|  | } | 
|  |  | 
|  | /* year month day */ | 
|  | print("%4d %2d %2d", | 
|  | (int)t.ifa[0], | 
|  | (int)t.ifa[1], | 
|  | (int)t.ifa[2]); | 
|  | } | 
|  |  | 
|  | void | 
|  | ptime(double d) | 
|  | { | 
|  | int h, m, s; | 
|  | char *mer; | 
|  | Tim t; | 
|  |  | 
|  | if(flags['s']) { | 
|  | /* hour minute */ | 
|  | dtsetup(d + .5/(24*60), &t); | 
|  | h = t.ifa[3]; | 
|  | m = floor(t.ifa[4]); | 
|  |  | 
|  | mer = "AM"; | 
|  | if(h >= 12) { | 
|  | mer = "PM"; | 
|  | h -= 12; | 
|  | } | 
|  | if(h == 0) | 
|  | h = 12; | 
|  | numb(h); | 
|  | if(m < 10) { | 
|  | if(m == 0) { | 
|  | print("%s exactly ...", mer); | 
|  | return; | 
|  | } | 
|  | print("O "); | 
|  | } | 
|  | numb(m); | 
|  | print("%s ...", mer); | 
|  | return; | 
|  | } | 
|  | /* hour minute second */ | 
|  | dtsetup(d, &t); | 
|  | h = t.ifa[3]; | 
|  | m = floor(t.ifa[4]); | 
|  | s = floor((t.ifa[4]-m) * 60); | 
|  | print("%.2d:%.2d:%.2d %.*s", h, m, s, utfnlen(t.tz, 3), t.tz); | 
|  | } | 
|  |  | 
|  | char*	unit[] = | 
|  | { | 
|  | "zero", | 
|  | "one", | 
|  | "two", | 
|  | "three", | 
|  | "four", | 
|  | "five", | 
|  | "six", | 
|  | "seven", | 
|  | "eight", | 
|  | "nine", | 
|  | "ten", | 
|  | "eleven", | 
|  | "twelve", | 
|  | "thirteen", | 
|  | "fourteen", | 
|  | "fifteen", | 
|  | "sixteen", | 
|  | "seventeen", | 
|  | "eighteen", | 
|  | "nineteen" | 
|  | }; | 
|  | char*	decade[] = | 
|  | { | 
|  | "twenty", | 
|  | "thirty", | 
|  | "forty", | 
|  | "fifty", | 
|  | "sixty", | 
|  | "seventy", | 
|  | "eighty", | 
|  | "ninety" | 
|  | }; | 
|  |  | 
|  | void | 
|  | pstime(double d) | 
|  | { | 
|  |  | 
|  | setime(d); | 
|  |  | 
|  | semi = 0; | 
|  | motion = 0; | 
|  | rad = 1.e9; | 
|  | lambda = 0; | 
|  | beta = 0; | 
|  |  | 
|  | /* uses lambda, beta, rad, motion */ | 
|  | /* sets alpha, delta, rp */ | 
|  |  | 
|  | helio(); | 
|  |  | 
|  | /* uses alpha, delta, rp */ | 
|  | /* sets ra, decl, lha, decl2, az, el */ | 
|  |  | 
|  | geo(); | 
|  |  | 
|  | print(" %R %D %D %4.0f", lha, nlat, awlong, elev/3.28084); | 
|  | } | 
|  |  | 
|  | void | 
|  | numb(int n) | 
|  | { | 
|  |  | 
|  | if(n >= 100) { | 
|  | print("%d ", n); | 
|  | return; | 
|  | } | 
|  | if(n >= 20) { | 
|  | print("%s ", decade[n/10 - 2]); | 
|  | n %= 10; | 
|  | if(n == 0) | 
|  | return; | 
|  | } | 
|  | print("%s ", unit[n]); | 
|  | } | 
|  |  | 
|  | double | 
|  | tzone(double y, Tim *z) | 
|  | { | 
|  | double t, l1, l2; | 
|  | Tm t1, t2; | 
|  |  | 
|  | /* | 
|  | * get a rough approximation to unix mean time | 
|  | */ | 
|  | t = (y - 25567.5) * 86400; | 
|  |  | 
|  | /* | 
|  | * if outside unix conversions, | 
|  | * just call it GMT | 
|  | */ | 
|  | if(t < 0 || t > 2.1e9) | 
|  | return y; | 
|  |  | 
|  | /* | 
|  | * convert by both local and gmt | 
|  | */ | 
|  | t1 = *localtime((long)t); | 
|  | t2 = *gmtime((long)t); | 
|  |  | 
|  | /* | 
|  | * pick up year crossings | 
|  | */ | 
|  | if(t1.yday == 0 && t2.yday > 1) | 
|  | t1.yday = t2.yday+1; | 
|  | if(t2.yday == 0 && t1.yday > 1) | 
|  | t2.yday = t1.yday+1; | 
|  |  | 
|  | /* | 
|  | * convert times to days | 
|  | */ | 
|  | l1 = t1.yday + t1.hour/24. + t1.min/1440. + t1.sec/86400.; | 
|  | l2 = t2.yday + t2.hour/24. + t2.min/1440. + t2.sec/86400.; | 
|  |  | 
|  | /* | 
|  | * return difference | 
|  | */ | 
|  | strncpy(z->tz, t1.zone, sizeof(z->tz)); | 
|  | return y + (l2 - l1); | 
|  | } | 
|  |  | 
|  | int	dmo[12] = | 
|  | { | 
|  | 0, | 
|  | 31, | 
|  | 59, | 
|  | 90, | 
|  | 120, | 
|  | 151, | 
|  | 181, | 
|  | 212, | 
|  | 243, | 
|  | 273, | 
|  | 304, | 
|  | 334 | 
|  | }; | 
|  |  | 
|  | /* | 
|  | * input date conversion | 
|  | * output is done by zero crossing | 
|  | * on this input conversion. | 
|  | */ | 
|  | double | 
|  | convdate(Tim *t) | 
|  | { | 
|  | double y, d; | 
|  | int m; | 
|  |  | 
|  | y = t->ifa[0]; | 
|  | m = t->ifa[1]; | 
|  | d = t->ifa[2]; | 
|  |  | 
|  | /* | 
|  | * normalize the month | 
|  | */ | 
|  | while(m < 1) { | 
|  | m += 12; | 
|  | y -= 1; | 
|  | } | 
|  | while(m > 12) { | 
|  | m -= 12; | 
|  | y += 1; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * bc correction | 
|  | */ | 
|  | if(y < 0) | 
|  | y += 1; | 
|  |  | 
|  | /* | 
|  | * normal conversion | 
|  | */ | 
|  | y += 4712; | 
|  | if(fmod(y, 4) == 0 && m > 2) | 
|  | d += 1; | 
|  | y = y*365 + floor((y+3)/4) + dmo[m-1] + d - 1; | 
|  |  | 
|  | /* | 
|  | * gregorian change | 
|  | */ | 
|  | if(y > 2361232) | 
|  | y -= floor((y-1794167)/36524.220) - | 
|  | floor((y-1721117)/146100); | 
|  | y += t->ifa[3]/24 + t->ifa[4]/1440 - 2415020.5; | 
|  |  | 
|  | /* | 
|  | * kitchen clock correction | 
|  | */ | 
|  | strncpy(t->tz, "GMT", sizeof(t->tz)); | 
|  | if(flags['k']) | 
|  | y = tzone(y, t); | 
|  | return y; | 
|  | } |