aboutsummaryrefslogtreecommitdiff
path: root/src/lib9/ctime.c
diff options
context:
space:
mode:
authorMichael Teichgräber <devnull@localhost>2008-07-09 08:27:22 -0400
committerMichael Teichgräber <devnull@localhost>2008-07-09 08:27:22 -0400
commitf35a04866f298aa4b0fa6846da0c0187751ce9b2 (patch)
treeaa4b87fbc1f71b246c9c8975abb0cab936f7ef2b /src/lib9/ctime.c
parent1cccddd6b3fb4a90641b8d05dc0bed618380074c (diff)
downloadplan9port-f35a04866f298aa4b0fa6846da0c0187751ce9b2.tar.gz
plan9port-f35a04866f298aa4b0fa6846da0c0187751ce9b2.tar.bz2
plan9port-f35a04866f298aa4b0fa6846da0c0187751ce9b2.zip
lib9: rewrite date routines to use /usr/share/zoneinfo directly
Diffstat (limited to 'src/lib9/ctime.c')
-rw-r--r--src/lib9/ctime.c157
1 files changed, 140 insertions, 17 deletions
diff --git a/src/lib9/ctime.c b/src/lib9/ctime.c
index 0782d099..c5e11569 100644
--- a/src/lib9/ctime.c
+++ b/src/lib9/ctime.c
@@ -1,21 +1,135 @@
+/*
+ * This routine converts time as follows.
+ * The epoch is 0000 Jan 1 1970 GMT.
+ * The argument time is in seconds since then.
+ * The localtime(t) entry returns a pointer to an array
+ * containing
+ *
+ * seconds (0-59)
+ * minutes (0-59)
+ * hours (0-23)
+ * day of month (1-31)
+ * month (0-11)
+ * year-1970
+ * weekday (0-6, Sun is 0)
+ * day of the year
+ * daylight savings flag
+ *
+ * The routine gets the daylight savings time from the environment.
+ *
+ * asctime(tvec))
+ * where tvec is produced by localtime
+ * returns a ptr to a character string
+ * that has the ascii time in the form
+ *
+ * \\
+ * Thu Jan 01 00:00:00 GMT 1970n0
+ * 012345678901234567890123456789
+ * 0 1 2
+ *
+ * ctime(t) just calls localtime, then asctime.
+ */
+
#include <u.h>
#include <libc.h>
-static
-void
-ct_numb(char *cp, int n)
+#include "zoneinfo.h"
+
+static char dmsize[12] =
{
+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
- cp[0] = ' ';
- if(n >= 10)
- cp[0] = (n/10)%10 + '0';
- cp[1] = n%10 + '0';
+#define dysize ctimedysize
+static int dysize(int);
+static void ct_numb(char*, int);
+
+char*
+ctime(long t)
+{
+ return asctime(localtime(t));
+}
+
+Tm*
+localtime(long tim)
+{
+ Tinfo ti;
+ Tm *ct;
+
+ if (zonelookuptinfo(&ti, tim)!=-1) {
+ ct = gmtime(tim+ti.tzoff);
+ strncpy(ct->zone, ti.zone, sizeof ct->zone);
+ ct->zone[sizeof ct->zone-1] = 0;
+ ct->tzoff = ti.tzoff;
+ return ct;
+ }
+ return gmtime(tim);
+}
+
+Tm*
+gmtime(long tim)
+{
+ int d0, d1;
+ long hms, day;
+ static Tm xtime;
+
+ /*
+ * break initial number into days
+ */
+ hms = tim % 86400L;
+ day = tim / 86400L;
+ if(hms < 0) {
+ hms += 86400L;
+ day -= 1;
+ }
+
+ /*
+ * generate hours:minutes:seconds
+ */
+ xtime.sec = hms % 60;
+ d1 = hms / 60;
+ xtime.min = d1 % 60;
+ d1 /= 60;
+ xtime.hour = d1;
+
+ /*
+ * day is the day number.
+ * generate day of the week.
+ * The addend is 4 mod 7 (1/1/1970 was Thursday)
+ */
+
+ xtime.wday = (day + 7340036L) % 7;
+
+ /*
+ * year number
+ */
+ if(day >= 0)
+ for(d1 = 1970; day >= dysize(d1); d1++)
+ day -= dysize(d1);
+ else
+ for (d1 = 1970; day < 0; d1--)
+ day += dysize(d1-1);
+ xtime.year = d1-1900;
+ xtime.yday = d0 = day;
+
+ /*
+ * generate month
+ */
+
+ if(dysize(d1) == 366)
+ dmsize[1] = 29;
+ for(d1 = 0; d0 >= dmsize[d1]; d1++)
+ d0 -= dmsize[d1];
+ dmsize[1] = 28;
+ xtime.mday = d0 + 1;
+ xtime.mon = d1;
+ strcpy(xtime.zone, "GMT");
+ return &xtime;
}
char*
asctime(Tm *t)
{
- int i;
char *ncp;
static char cbuf[30];
@@ -33,12 +147,6 @@ asctime(Tm *t)
ct_numb(cbuf+14, t->min+100);
ct_numb(cbuf+17, t->sec+100);
ncp = t->zone;
- for(i=0; i<3; i++)
- if(ncp[i] == 0)
- break;
- for(; i<3; i++)
- ncp[i] = '?';
- ncp = t->zone;
cbuf[20] = *ncp++;
cbuf[21] = *ncp++;
cbuf[22] = *ncp;
@@ -50,9 +158,24 @@ asctime(Tm *t)
return cbuf;
}
-char*
-ctime(long t)
+static
+int
+dysize(int y)
{
- return asctime(localtime(t));
+
+ if(y%4 == 0 && (y%100 != 0 || y%400 == 0))
+ return 366;
+ return 365;
+}
+
+static
+void
+ct_numb(char *cp, int n)
+{
+
+ cp[0] = ' ';
+ if(n >= 10)
+ cp[0] = (n/10)%10 + '0';
+ cp[1] = n%10 + '0';
}