Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#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;
}