Blob
1 #include "astro.h"4 char* month[] =5 {6 "January",7 "February",8 "March",9 "April",10 "May",11 "June",12 "July",13 "August",14 "September",15 "October",16 "November",17 "December",18 };20 double21 dsrc(double d, Tim *t, int i)22 {23 double y;25 do {26 t->ifa[i] += 1.;27 y = convdate(t);28 } while(d >= y);29 do {30 t->ifa[i] -= 1.;31 y = convdate(t);32 } while(d < y);33 return d - y;34 }36 void37 dtsetup(double d, Tim *t)38 {39 double v;41 t->ifa[0] = floor(1900 + d/365.24220);42 t->ifa[1] = 1;43 t->ifa[2] = 1;44 t->ifa[3] = 0;45 t->ifa[4] = 0;46 t->ifa[1] = floor(1 + dsrc(d, t, 0)/30);47 t->ifa[2] = floor(1 + dsrc(d, t, 1));48 dsrc(d, t, 2);50 v = (d - convdate(t)) * 24;51 t->ifa[3] = floor(v);52 t->ifa[4] = (v - t->ifa[3]) * 60;53 convdate(t); /* to set timezone */54 }56 void57 pdate(double d)58 {59 int i;60 Tim t;62 dtsetup(d, &t);63 if(flags['s']) {64 i = t.ifa[1];65 print("%s ", month[i-1]);66 i = t.ifa[2];67 numb(i);68 print("...");69 return;70 }72 /* year month day */73 print("%4d %2d %2d",74 (int)t.ifa[0],75 (int)t.ifa[1],76 (int)t.ifa[2]);77 }79 void80 ptime(double d)81 {82 int h, m, s;83 char *mer;84 Tim t;86 if(flags['s']) {87 /* hour minute */88 dtsetup(d + .5/(24*60), &t);89 h = t.ifa[3];90 m = floor(t.ifa[4]);92 mer = "AM";93 if(h >= 12) {94 mer = "PM";95 h -= 12;96 }97 if(h == 0)98 h = 12;99 numb(h);100 if(m < 10) {101 if(m == 0) {102 print("%s exactly ...", mer);103 return;104 }105 print("O ");106 }107 numb(m);108 print("%s ...", mer);109 return;110 }111 /* hour minute second */112 dtsetup(d, &t);113 h = t.ifa[3];114 m = floor(t.ifa[4]);115 s = floor((t.ifa[4]-m) * 60);116 print("%.2d:%.2d:%.2d %.*s", h, m, s, utfnlen(t.tz, 3), t.tz);117 }119 char* unit[] =120 {121 "zero",122 "one",123 "two",124 "three",125 "four",126 "five",127 "six",128 "seven",129 "eight",130 "nine",131 "ten",132 "eleven",133 "twelve",134 "thirteen",135 "fourteen",136 "fifteen",137 "sixteen",138 "seventeen",139 "eighteen",140 "nineteen"141 };142 char* decade[] =143 {144 "twenty",145 "thirty",146 "forty",147 "fifty",148 "sixty",149 "seventy",150 "eighty",151 "ninety"152 };154 void155 pstime(double d)156 {158 setime(d);160 semi = 0;161 motion = 0;162 rad = 1.e9;163 lambda = 0;164 beta = 0;166 // uses lambda, beta, rad, motion167 // sets alpha, delta, rp169 helio();171 // uses alpha, delta, rp172 // sets ra, decl, lha, decl2, az, el174 geo();176 print(" %R %D %D %4.0f", lha, nlat, awlong, elev/3.28084);177 }179 void180 numb(int n)181 {183 if(n >= 100) {184 print("%d ", n);185 return;186 }187 if(n >= 20) {188 print("%s ", decade[n/10 - 2]);189 n %= 10;190 if(n == 0)191 return;192 }193 print("%s ", unit[n]);194 }196 double197 tzone(double y, Tim *z)198 {199 double t, l1, l2;200 Tm t1, t2;202 /*203 * get a rough approximation to unix mean time204 */205 t = (y - 25567.5) * 86400;207 /*208 * if outside unix conversions,209 * just call it GMT210 */211 if(t < 0 || t > 2.1e9)212 return y;214 /*215 * convert by both local and gmt216 */217 t1 = *localtime((long)t);218 t2 = *gmtime((long)t);220 /*221 * pick up year crossings222 */223 if(t1.yday == 0 && t2.yday > 1)224 t1.yday = t2.yday+1;225 if(t2.yday == 0 && t1.yday > 1)226 t2.yday = t1.yday+1;228 /*229 * convert times to days230 */231 l1 = t1.yday + t1.hour/24. + t1.min/1440. + t1.sec/86400.;232 l2 = t2.yday + t2.hour/24. + t2.min/1440. + t2.sec/86400.;234 /*235 * return difference236 */237 strncpy(z->tz, t1.zone, sizeof(z->tz));238 return y + (l2 - l1);239 }241 int dmo[12] =242 {243 0,244 31,245 59,246 90,247 120,248 151,249 181,250 212,251 243,252 273,253 304,254 334255 };257 /*258 * input date conversion259 * output is done by zero crossing260 * on this input conversion.261 */262 double263 convdate(Tim *t)264 {265 double y, d;266 int m;268 y = t->ifa[0];269 m = t->ifa[1];270 d = t->ifa[2];272 /*273 * normalize the month274 */275 while(m < 1) {276 m += 12;277 y -= 1;278 }279 while(m > 12) {280 m -= 12;281 y += 1;282 }284 /*285 * bc correction286 */287 if(y < 0)288 y += 1;290 /*291 * normal conversion292 */293 y += 4712;294 if(fmod(y, 4) == 0 && m > 2)295 d += 1;296 y = y*365 + floor((y+3)/4) + dmo[m-1] + d - 1;298 /*299 * gregorian change300 */301 if(y > 2361232)302 y -= floor((y-1794167)/36524.220) -303 floor((y-1721117)/146100);304 y += t->ifa[3]/24 + t->ifa[4]/1440 - 2415020.5;306 /*307 * kitchen clock correction308 */309 strncpy(t->tz, "GMT", sizeof(t->tz));310 if(flags['k'])311 y = tzone(y, t);312 return y;313 }