aboutsummaryrefslogtreecommitdiff
path: root/src/lib9/tm2sec.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/tm2sec.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/tm2sec.c')
-rw-r--r--src/lib9/tm2sec.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/lib9/tm2sec.c b/src/lib9/tm2sec.c
new file mode 100644
index 00000000..5edf439d
--- /dev/null
+++ b/src/lib9/tm2sec.c
@@ -0,0 +1,110 @@
+#include <u.h>
+#include <libc.h>
+
+#include "zoneinfo.h"
+
+#define SEC2MIN 60L
+#define SEC2HOUR (60L*SEC2MIN)
+#define SEC2DAY (24L*SEC2HOUR)
+
+/*
+ * days per month plus days/year
+ */
+static int dmsize[] =
+{
+ 365, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+static int ldmsize[] =
+{
+ 366, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+/*
+ * return the days/month for the given year
+ */
+static int *
+yrsize(int y)
+{
+ if((y%4) == 0 && ((y%100) != 0 || (y%400) == 0))
+ return ldmsize;
+ else
+ return dmsize;
+}
+
+/*
+ * compute seconds since Jan 1 1970 GMT
+ * and convert to our timezone.
+ */
+long
+tm2sec(Tm *tm)
+{
+ Tinfo ti0, ti1, *ti;
+ long secs;
+ int i, yday, year, *d2m;
+
+ secs = 0;
+
+ /*
+ * seconds per year
+ */
+ year = tm->year + 1900;
+ for(i = 1970; i < year; i++){
+ d2m = yrsize(i);
+ secs += d2m[0] * SEC2DAY;
+ }
+
+ /*
+ * if mday is set, use mon and mday to compute yday
+ */
+ if(tm->mday){
+ yday = 0;
+ d2m = yrsize(year);
+ for(i=0; i<tm->mon; i++)
+ yday += d2m[i+1];
+ yday += tm->mday-1;
+ }else{
+ yday = tm->yday;
+ }
+ secs += yday * SEC2DAY;
+
+ /*
+ * hours, minutes, seconds
+ */
+ secs += tm->hour * SEC2HOUR;
+ secs += tm->min * SEC2MIN;
+ secs += tm->sec;
+
+ /*
+ * Assume the local time zone if zone is not GMT
+ */
+ if(strcmp(tm->zone, "GMT") != 0) {
+ i = zonelookuptinfo(&ti0, secs);
+ ti = &ti0;
+ if (i != -1)
+ if (ti->tzoff!=0) {
+ /*
+ * to what local time period `secs' belongs?
+ */
+ if (ti->tzoff>0) {
+ /*
+ * east of GMT; check previous local time transition
+ */
+ if (ti->t+ti->tzoff > secs)
+ if (zonetinfo(&ti1, i-1)!=-1)
+ ti = &ti1;
+ } else
+ /*
+ * west of GMT; check next local time transition
+ */
+ if (zonetinfo(&ti1, i+1))
+ if (ti1.t+ti->tzoff < secs)
+ ti = &ti1;
+// fprint(2, "tt: %ld+%d %ld\n", (long)ti->t, ti->tzoff, (long)secs);
+ secs -= ti->tzoff;
+ }
+ }
+
+ if(secs < 0)
+ secs = 0;
+ return secs;
+}