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/ctime.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/ctime.c')
-rw-r--r-- | src/lib9/ctime.c | 157 |
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'; } |