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 double
21 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 void
37 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 void
57 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 void
80 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;
105 print("O ");
107 numb(m);
108 print("%s ...", mer);
109 return;
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);
119 char* unit[] =
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[] =
144 "twenty",
145 "thirty",
146 "forty",
147 "fifty",
148 "sixty",
149 "seventy",
150 "eighty",
151 "ninety"
152 };
154 void
155 pstime(double d)
158 setime(d);
160 semi = 0;
161 motion = 0;
162 rad = 1.e9;
163 lambda = 0;
164 beta = 0;
166 /* uses lambda, beta, rad, motion */
167 /* sets alpha, delta, rp */
169 helio();
171 /* uses alpha, delta, rp */
172 /* sets ra, decl, lha, decl2, az, el */
174 geo();
176 print(" %R %D %D %4.0f", lha, nlat, awlong, elev/3.28084);
179 void
180 numb(int n)
183 if(n >= 100) {
184 print("%d ", n);
185 return;
187 if(n >= 20) {
188 print("%s ", decade[n/10 - 2]);
189 n %= 10;
190 if(n == 0)
191 return;
193 print("%s ", unit[n]);
196 double
197 tzone(double y, Tim *z)
199 double t, l1, l2;
200 Tm t1, t2;
202 /*
203 * get a rough approximation to unix mean time
204 */
205 t = (y - 25567.5) * 86400;
207 /*
208 * if outside unix conversions,
209 * just call it GMT
210 */
211 if(t < 0 || t > 2.1e9)
212 return y;
214 /*
215 * convert by both local and gmt
216 */
217 t1 = *localtime((long)t);
218 t2 = *gmtime((long)t);
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;
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.;
234 /*
235 * return difference
236 */
237 strncpy(z->tz, t1.zone, sizeof(z->tz));
238 return y + (l2 - l1);
241 int dmo[12] =
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 };
257 /*
258 * input date conversion
259 * output is done by zero crossing
260 * on this input conversion.
261 */
262 double
263 convdate(Tim *t)
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 month
274 */
275 while(m < 1) {
276 m += 12;
277 y -= 1;
279 while(m > 12) {
280 m -= 12;
281 y += 1;
284 /*
285 * bc correction
286 */
287 if(y < 0)
288 y += 1;
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;
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;
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;