unfortunately ken's keen dst solution doesn't extend to the rest of the world. this uses /adm/timezone/* to solve this problem. Reference: /n/sources/patch/sorry/fs-alltzdst Date: Tue Mar 13 14:18:27 CET 2007 Signed-off-by: quanstro@quanstro.net --- /sys/src/fs/9netics32.16k/mkfile Tue Mar 13 14:13:50 2007 +++ /sys/src/fs/9netics32.16k/mkfile Tue Mar 13 14:13:48 2007 @@ -1,4 +1,5 @@ CONF=net32.16k +ZONE=/adm/timezone/US_Eastern p=9 objtype=386 @@ -142,4 +143,4 @@ %.$O: $HFILES clean:V: - rm -f *.[$OS] [$OS].out $TARG + rm -f *.[$OS] [$OS].out $TARG timezone.h --- /sys/src/fs/9netics64.8k/mkfile Tue Mar 13 14:14:00 2007 +++ /sys/src/fs/9netics64.8k/mkfile Tue Mar 13 14:13:58 2007 @@ -1,4 +1,5 @@ CONF=net64.8k +ZONE=/adm/timezone/US_Eastern p=9 objtype=386 @@ -142,4 +143,4 @@ %.$O: $HFILES clean:V: - rm -f *.[$OS] [$OS].out $TARG + rm -f *.[$OS] [$OS].out $TARG timezone.h --- /sys/src/fs/choline/mkfile Tue Mar 13 14:14:12 2007 +++ /sys/src/fs/choline/mkfile Tue Mar 13 14:14:10 2007 @@ -1,4 +1,5 @@ CONF=choline +ZONE=/adm/timezone/US_Eastern p=9 objtype=386 @@ -144,4 +145,4 @@ %.$O: $HFILES clean:V: - rm -f *.[$OS] [$OS].out $TARG + rm -f *.[$OS] [$OS].out $TARG timezone.h --- /sys/src/fs/emelie/mkfile Tue Mar 13 14:14:25 2007 +++ /sys/src/fs/emelie/mkfile Tue Mar 13 14:14:23 2007 @@ -1,4 +1,5 @@ CONF=emelie +ZONE=/adm/timezone/US_Eastern p=9 objtype=386 @@ -144,4 +145,4 @@ %.$O: $HFILES clean:V: - rm -f *.[$OS] [$OS].out $TARG + rm -f *.[$OS] [$OS].out $TARG timezone.h --- /sys/src/fs/fs/mkfile Tue Mar 13 14:14:41 2007 +++ /sys/src/fs/fs/mkfile Tue Mar 13 14:14:39 2007 @@ -1,4 +1,5 @@ CONF=fs +ZONE=/adm/timezone/US_Eastern p=9 objtype=386 @@ -143,4 +144,4 @@ %.$O: $HFILES clean:V: - rm -f *.[$OS] [$OS].out $TARG + rm -f *.[$OS] [$OS].out $TARG timezone.h --- /sys/src/fs/fs64/mkfile Tue Mar 13 14:15:00 2007 +++ /sys/src/fs/fs64/mkfile Tue Mar 13 14:14:58 2007 @@ -1,4 +1,5 @@ CONF=fs +ZONE=/adm/timezone/US_Eastern p=9 objtype=386 @@ -55,7 +56,6 @@ devsd.$O\ sdscsi.$O\ sdata.$O\ - sdmv50xx.$O\ dosfs.$O\ floppy.$O\ kbd.$O\ @@ -142,4 +142,4 @@ %.$O: $HFILES clean:V: - rm -f *.[$OS] [$OS].out $TARG + rm -f *.[$OS] [$OS].out $TARG timezone.h --- /sys/src/fs/port/mkfile Tue Mar 13 14:15:19 2007 +++ /sys/src/fs/port/mkfile Tue Mar 13 14:15:17 2007 @@ -4,3 +4,6 @@ 9p1.$O 9p1lib.$O console.$O main.$O: ../port/9p1.h devsd.$O: ../pc/compat.h +time.$O: timezone.h mkfile +timezone.h: mkfile + ../fs64/tzgen $ZONE > timezone.h --- /sys/src/fs/port/portdat.h Tue Mar 13 14:15:46 2007 +++ /sys/src/fs/port/portdat.h Tue Mar 13 14:15:39 2007 @@ -713,8 +713,8 @@ int mon; int year; int wday; - int yday; - int isdst; + char zone[4]; + int tzoff; }; struct Rtc --- /sys/src/fs/port/time.c Tue Mar 13 14:16:10 2007 +++ /sys/src/fs/port/time.c Tue Mar 13 14:16:07 2007 @@ -171,77 +171,42 @@ }; /* - * The following table is used for 1974 and 1975 and - * gives the day number of the first day after the Sunday of the - * change. + * since we are the fileserver and can't depend on files being where + * they belong, we keep the equivalent of /adm/timezone/local in + * the following structure, which is compiled into the executable. */ -static struct -{ - short yrfrom; - short yrto; - short daylb; - short dayle; -} daytab[] = -{ - 107, ~(ushort)0>>1, 66, 310, - 87, 106, 90, 303, - 76, 86, 119, 303, - 75, 75, 58, 303, - 74, 74, 5, 333, - -1, 73, 119, 303, -}; - -static -prevsunday(Tm *t, int d) -{ - if(d >= 58) - d += dysize(t->year) - 365; - return d - (d - t->yday + t->wday + 700) % 7; -} +typedef struct{ + char stname[4]; + char dlname[4]; + long stdiff; + long dldiff; + long dlpairs[150]; +} Timezone; -static -succsunday(Tm *t, int d) -{ - int dd; - - if(d >= 58) - d += dysize(t->year) - 365; - dd = (d - t->yday + t->wday + 700) % 7; - if(dd == 0) - return d; - else - return d + 7 - dd; -} +#include "timezone.h" void localtime(Timet tim, Tm *ct) { - int daylbegin, daylend, dayno, i; - Timet copyt; + long t, *p; + int dlflag; - copyt = tim - conf.minuteswest*60L; - gmtime(copyt, ct); - dayno = ct->yday; - - /* enforce sane bounds for daytab */ - if (ct->year < -1) /* 1 jan 1970 00:00 GMT can be 31 dec 1969 locally */ - ct->year = -1; - else if (ct->year > 60000) - ct->year = 60000; - - for(i = 0; ; i++) - if(ct->year >= daytab[i].yrfrom && - ct->year <= daytab[i].yrto) { - daylbegin = succsunday(ct, daytab[i].daylb); - daylend = prevsunday(ct, daytab[i].dayle); + t = tim + timezone.stdiff; + dlflag = 0; + for(p = timezone.dlpairs; *p; p += 2) + if(t >= p[0]) + if(t < p[1]) { + t = tim + timezone.dldiff; + dlflag++; break; } - if(conf.dsttime && - (dayno>daylbegin || (dayno==daylbegin && ct->hour >= 2)) && - (daynohour < 1))) { - copyt += 60L*60L; - gmtime(copyt, ct); - ct->isdst++; + gmtime(t, ct); + if(dlflag){ + strcpy(ct->zone, timezone.dlname); + ct->tzoff = timezone.dldiff; + } else { + strcpy(ct->zone, timezone.stname); + ct->tzoff = timezone.stdiff; } } @@ -300,7 +265,8 @@ dmsize[1] = 28; ct->mday = d0 + 1; ct->mon = d1; - ct->isdst = 0; + ct->tzoff = 0; + strcpy(ct->zone, "GMT"); } void @@ -325,7 +291,7 @@ return fmtstrcpy(fmt, "The Epoch"); localtime(t, &tm); - strcpy(s, "Day Mon 00 00:00:00 1900"); + strcpy(s, "Day Mon 00 00:00:00 GMT 1900"); cp = &"SunMonTueWedThuFriSat"[tm.wday*3]; s[0] = cp[0]; s[1] = cp[1]; @@ -338,11 +304,15 @@ ct_numb(s+11, tm.hour+100); ct_numb(s+14, tm.min+100); ct_numb(s+17, tm.sec+100); + cp = tm.zone; + s[20] = *cp++; + s[21] = *cp++; + s[22] = *cp; if(tm.year >= 100) { - s[20] = '2'; - s[21] = '0'; + s[24] = '2'; + s[25] = '0'; } - ct_numb(s+22, tm.year+100); + ct_numb(s+26, tm.year+100); return fmtstrcpy(fmt, s); } --- /sys/src/fs/fs64/tzgen Thu Jan 1 00:00:00 1970 +++ /sys/src/fs/fs64/tzgen Tue Mar 13 14:16:32 2007 @@ -0,0 +1,34 @@ +#!/bin/rc +if(~ $#* 0) + zone = /adm/timezone/local +if not + zone = $1 + +echo 'Timezone timezone = {' + +awk ' +NR==1{ + print ".stname = " utf(34) $1 utf(34) "," + print ".stdiff = " $2 "," + print ".dlname = " utf(34) $3 utf(34) "," + print ".dldiff = " $4 "," + print ".dlpairs = {" +} +NR!=1{ + for(i = 1; i < NF; i++) + tab[n++] = $i +} +END{ + for(i = 0; n-i > 4; i +=4) + printf("\t\t%d, %d, %d, %d,\n", tab[i], tab[i+1], tab[i+2], tab[i+3]); + if(i != n){ + printf("\t\t"); + for(;i < n; i++) + printf("%d, ", tab[i]) + printf("\n"); + } +} +' < $zone + +echo ' }' ; echo '};' +