aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/astro/pdate.c
diff options
context:
space:
mode:
authorwkj <devnull@localhost>2004-04-21 02:16:43 +0000
committerwkj <devnull@localhost>2004-04-21 02:16:43 +0000
commitcd5bae7871bc0f0bc68b4d2a84703929a7a3c9d1 (patch)
tree336db54785d2b77113a6e570574be715c7eb7d1d /src/cmd/astro/pdate.c
parent95f57b01e21feb457e79eaf52d593422c318024f (diff)
downloadplan9port-cd5bae7871bc0f0bc68b4d2a84703929a7a3c9d1.tar.gz
plan9port-cd5bae7871bc0f0bc68b4d2a84703929a7a3c9d1.tar.bz2
plan9port-cd5bae7871bc0f0bc68b4d2a84703929a7a3c9d1.zip
Astro with some minor changes to placate Unix.
Diffstat (limited to 'src/cmd/astro/pdate.c')
-rw-r--r--src/cmd/astro/pdate.c313
1 files changed, 313 insertions, 0 deletions
diff --git a/src/cmd/astro/pdate.c b/src/cmd/astro/pdate.c
new file mode 100644
index 00000000..e88d7006
--- /dev/null
+++ b/src/cmd/astro/pdate.c
@@ -0,0 +1,313 @@
+#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;
+}