Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}