313 lines
4 KiB
C
313 lines
4 KiB
C
#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;
|
|
}
|