]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/astro/pdate.c
devproc: can't wait for ourselfs to stop (thanks Shamar)
[plan9front.git] / sys / src / cmd / astro / pdate.c
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 }