#include "astro.h"
char* month[] =
{
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
};
double
dsrc(double d, Tim *t, int i)
{
double y;
do {
t->ifa[i] += 1.;
y = convdate(t);
} while(d >= y);
do {
t->ifa[i] -= 1.;
y = convdate(t);
} while(d < y);
return d - y;
}
void
dtsetup(double d, Tim *t)
{
double v;
t->ifa[0] = floor(1900 + d/365.24220);
t->ifa[1] = 1;
t->ifa[2] = 1;
t->ifa[3] = 0;
t->ifa[4] = 0;
t->ifa[1] = floor(1 + dsrc(d, t, 0)/30);
t->ifa[2] = floor(1 + dsrc(d, t, 1));
dsrc(d, t, 2);
v = (d - convdate(t)) * 24;
t->ifa[3] = floor(v);
t->ifa[4] = (v - t->ifa[3]) * 60;
convdate(t); /* to set timezone */
}
void
pdate(double d)
{
int i;
Tim t;
dtsetup(d, &t);
if(flags['s']) {
i = t.ifa[1];
print("%s ", month[i-1]);
i = t.ifa[2];
numb(i);
print("...");
return;
}
/* year month day */
print("%4d %2d %2d",
(int)t.ifa[0],
(int)t.ifa[1],
(int)t.ifa[2]);
}
void
ptime(double d)
{
int h, m, s;
char *mer;
Tim t;
if(flags['s']) {
/* hour minute */
dtsetup(d + .5/(24*60), &t);
h = t.ifa[3];
m = floor(t.ifa[4]);
mer = "AM";
if(h >= 12) {
mer = "PM";
h -= 12;
}
if(h == 0)
h = 12;
numb(h);
if(m < 10) {
if(m == 0) {
print("%s exactly ...", mer);
return;
}
print("O ");
}
numb(m);
print("%s ...", mer);
return;
}
/* hour minute second */
dtsetup(d, &t);
h = t.ifa[3];
m = floor(t.ifa[4]);
s = floor((t.ifa[4]-m) * 60);
print("%.2d:%.2d:%.2d %.*s", h, m, s, utfnlen(t.tz, 3), t.tz);
}
char* unit[] =
{
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen"
};
char* decade[] =
{
"twenty",
"thirty",
"forty",
"fifty",
"sixty",
"seventy",
"eighty",
"ninety"
};
void
pstime(double d)
{
setime(d);
semi = 0;
motion = 0;
rad = 1.e9;
lambda = 0;
beta = 0;
// uses lambda, beta, rad, motion
// sets alpha, delta, rp
helio();
// uses alpha, delta, rp
// sets ra, decl, lha, decl2, az, el
geo();
print(" %R %D %D %4.0f", lha, nlat, awlong, elev/3.28084);
}
void
numb(int n)
{
if(n >= 100) {
print("%d ", n);
return;
}
if(n >= 20) {
print("%s ", decade[n/10 - 2]);
n %= 10;
if(n == 0)
return;
}
print("%s ", unit[n]);
}
double
tzone(double y, Tim *z)
{
double t, l1, l2;
Tm t1, t2;
/*
* get a rough approximation to unix mean time
*/
t = (y - 25567.5) * 86400;
/*
* if outside unix conversions,
* just call it GMT
*/
if(t < 0 || t > 2.1e9)
return y;
/*
* convert by both local and gmt
*/
t1 = *localtime((long)t);
t2 = *gmtime((long)t);
/*
* pick up year crossings
*/
if(t1.yday == 0 && t2.yday > 1)
t1.yday = t2.yday+1;
if(t2.yday == 0 && t1.yday > 1)
t2.yday = t1.yday+1;
/*
* convert times to days
*/
l1 = t1.yday + t1.hour/24. + t1.min/1440. + t1.sec/86400.;
l2 = t2.yday + t2.hour/24. + t2.min/1440. + t2.sec/86400.;
/*
* return difference
*/
strncpy(z->tz, t1.zone, sizeof(z->tz));
return y + (l2 - l1);
}
int dmo[12] =
{
0,
31,
59,
90,
120,
151,
181,
212,
243,
273,
304,
334
};
/*
* input date conversion
* output is done by zero crossing
* on this input conversion.
*/
double
convdate(Tim *t)
{
double y, d;
int m;
y = t->ifa[0];
m = t->ifa[1];
d = t->ifa[2];
/*
* normalize the month
*/
while(m < 1) {
m += 12;
y -= 1;
}
while(m > 12) {
m -= 12;
y += 1;
}
/*
* bc correction
*/
if(y < 0)
y += 1;
/*
* normal conversion
*/
y += 4712;
if(fmod(y, 4) == 0 && m > 2)
d += 1;
y = y*365 + floor((y+3)/4) + dmo[m-1] + d - 1;
/*
* gregorian change
*/
if(y > 2361232)
y -= floor((y-1794167)/36524.220) -
floor((y-1721117)/146100);
y += t->ifa[3]/24 + t->ifa[4]/1440 - 2415020.5;
/*
* kitchen clock correction
*/
strncpy(t->tz, "GMT", sizeof(t->tz));
if(flags['k'])
y = tzone(y, t);
return y;
}
|