pdate.c (4059B)
1 #include "astro.h" 2 3 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 }; 19 20 double 21 dsrc(double d, Tim *t, int i) 22 { 23 double y; 24 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 } 35 36 void 37 dtsetup(double d, Tim *t) 38 { 39 double v; 40 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); 49 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 } 55 56 void 57 pdate(double d) 58 { 59 int i; 60 Tim t; 61 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 } 71 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 } 78 79 void 80 ptime(double d) 81 { 82 int h, m, s; 83 char *mer; 84 Tim t; 85 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]); 91 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 } 118 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 }; 153 154 void 155 pstime(double d) 156 { 157 158 setime(d); 159 160 semi = 0; 161 motion = 0; 162 rad = 1.e9; 163 lambda = 0; 164 beta = 0; 165 166 /* uses lambda, beta, rad, motion */ 167 /* sets alpha, delta, rp */ 168 169 helio(); 170 171 /* uses alpha, delta, rp */ 172 /* sets ra, decl, lha, decl2, az, el */ 173 174 geo(); 175 176 print(" %R %D %D %4.0f", lha, nlat, awlong, elev/3.28084); 177 } 178 179 void 180 numb(int n) 181 { 182 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 } 195 196 double 197 tzone(double y, Tim *z) 198 { 199 double t, l1, l2; 200 Tm t1, t2; 201 202 /* 203 * get a rough approximation to unix mean time 204 */ 205 t = (y - 25567.5) * 86400; 206 207 /* 208 * if outside unix conversions, 209 * just call it GMT 210 */ 211 if(t < 0 || t > 2.1e9) 212 return y; 213 214 /* 215 * convert by both local and gmt 216 */ 217 t1 = *localtime((long)t); 218 t2 = *gmtime((long)t); 219 220 /* 221 * pick up year crossings 222 */ 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; 227 228 /* 229 * convert times to days 230 */ 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.; 233 234 /* 235 * return difference 236 */ 237 strncpy(z->tz, t1.zone, sizeof(z->tz)); 238 return y + (l2 - l1); 239 } 240 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 334 255 }; 256 257 /* 258 * input date conversion 259 * output is done by zero crossing 260 * on this input conversion. 261 */ 262 double 263 convdate(Tim *t) 264 { 265 double y, d; 266 int m; 267 268 y = t->ifa[0]; 269 m = t->ifa[1]; 270 d = t->ifa[2]; 271 272 /* 273 * normalize the month 274 */ 275 while(m < 1) { 276 m += 12; 277 y -= 1; 278 } 279 while(m > 12) { 280 m -= 12; 281 y += 1; 282 } 283 284 /* 285 * bc correction 286 */ 287 if(y < 0) 288 y += 1; 289 290 /* 291 * normal conversion 292 */ 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; 297 298 /* 299 * gregorian change 300 */ 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; 305 306 /* 307 * kitchen clock correction 308 */ 309 strncpy(t->tz, "GMT", sizeof(t->tz)); 310 if(flags['k']) 311 y = tzone(y, t); 312 return y; 313 }