diff options
author | Michael Teichgräber <devnull@localhost> | 2008-07-09 08:27:22 -0400 |
---|---|---|
committer | Michael Teichgräber <devnull@localhost> | 2008-07-09 08:27:22 -0400 |
commit | f35a04866f298aa4b0fa6846da0c0187751ce9b2 (patch) | |
tree | aa4b87fbc1f71b246c9c8975abb0cab936f7ef2b /src/lib9/tm2sec.c | |
parent | 1cccddd6b3fb4a90641b8d05dc0bed618380074c (diff) | |
download | plan9port-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.c | 110 |
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; +} |