libc: correct dst transition times

The transition time in the timezone info file is,
confusingly, in local time and not UTC, so we need
to translate it before we do the comparison.

While we're here, revert the Australian timezone
change that made the offsets UTC, and add some test
to make sure we get this right.
This commit is contained in:
Ori Bernstein 2024-04-27 02:19:11 +00:00
parent 498f4f15b5
commit ce86e64ee0
3 changed files with 63 additions and 38 deletions

View file

@ -1,12 +1,24 @@
CST 34200 CDT 37800 CST 34200 CST 37800
1538836200 1554568200 57722400 68608800 89172000 100058400 120621600 131508000
1570293000 1586017800 152071200 162957600 183520800 195012000 215575200 226461600
1601742600 1617467400 247024800 257911200 278474400 289360800 309924000 320810400
1633192200 1648917000 341373600 352260000 372823200 384314400 404877600 415764000
1664641800 1680366600 436327200 447213600 467776800 478663200 499226400 511322400
1696091400 1712421000 530676000 542772000 562125600 574826400 594180000 606276000
1728145800 1743870600 625629600 638330400 657079200 667965600 688528800 701229600
1759595400 1775320200 719978400 731469600 752032800 764733600 783482400 794368800
1791045000 1806769800 814932000 827632800 846381600 857268000 877831200 890532000
1822494600 1838219400 909280800 920772000 941335200 954036000 972784800 983671200
1853944200 1869669000 1004234400 1016935200 1035684000 1046570400 1067133600 1080439200
1099188000 1110074400 1130637600 1143338400 1162087200 1172973600
1193536800 1206237600 1224986400 1235872800 1256436000 1269741600
1288490400 1299376800 1319940000 1332640800 1351389600 1362276000
1382839200 1395540000 1414288800 1425175200 1445738400 1459044000
1477792800 1488679200 1509242400 1521943200 1540692000 1551578400
1572141600 1584842400 1603591200 1615082400 1635645600 1648346400
1667095200 1677981600 1698544800 1711245600 1729994400 1740880800
1761444000 1774144800 1792893600 1804384800 1824948000 1837648800
1856397600 1867284000 1887847200 1900548000 1919296800 1930183200
1950746400 1964052000 1982800800 1993687200 2014250400 2026951200
2045700000 2056586400 2077149600 2089850400 2108599200 2119485600
2140048800

View file

@ -7,63 +7,75 @@ nl='
' '
fn check { fn check {
r=`$nl{../$O.seconds $1} r=`$nl{../$O.$1 $2}
if(! ~ $r $2){ if(! ~ $r $3){
echo "$"r" echo "$"r"
echo "$"2" echo "$"3"
echo $status echo $status
>[1=2] echo fail: $1: got $r expected $2 >[1=2] echo fail: $1 $2: got $r expected $3
exit 'fail' exit 'fail'
} }
} }
# examples from manpage, and shuffles # examples from manpage, and shuffles
rfork ne rfork ne
check '23 may 2011' 1306108800 check seconds '23 may 2011' 1306108800
check 'may 23 2011' 1306108800 check seconds 'may 23 2011' 1306108800
check 'may 2011 23' 1306108800 check seconds 'may 2011 23' 1306108800
check '23 2011 may' 1306108800 check seconds '23 2011 may' 1306108800
check '2011 may 23' 1306108800 check seconds '2011 may 23' 1306108800
check '2011 23 may' 1306108800 check seconds '2011 23 may' 1306108800
# now with timezones # now with timezones
check '23 may 2011 edt' 1306123200 check seconds '23 may 2011 edt' 1306123200
check '23 may 2011 gmt' 1306108800 check seconds '23 may 2011 gmt' 1306108800
# If the tz is present, the results should stay # If the tz is present, the results should stay
# the same if we change zones. # the same if we change zones.
@{ @{
rfork en rfork en
cat /adm/timezone/US_Pacific >/env/timezone cat /adm/timezone/US_Pacific >/env/timezone
check '23 may 2011 edt' 1306123200 check seconds '23 may 2011 edt' 1306123200
check '23 may 2011 gmt' 1306108800 check seconds '23 may 2011 gmt' 1306108800
} }
# now with all variations on times. # now with all variations on times.
check 'may 23 2011 0' 1306108800 check seconds 'may 23 2011 0' 1306108800
check 'may 23 2011 0:1' 1306108860 check seconds 'may 23 2011 0:1' 1306108860
check 'may 23 2011 0:1:2' 1306108862 check seconds 'may 23 2011 0:1:2' 1306108862
# now with times and timezones # now with times and timezones
check '23 may 2011 edt' 1306123200 check seconds '23 may 2011 edt' 1306123200
check '23 may 2011 gmt' 1306108800 check seconds '23 may 2011 gmt' 1306108800
# formats from ../$O.date(1) # formats from ../$O.date(1)
check 'Sun, 14 Jun 2020 22:08:48 -0700' 1592197728 check seconds 'Sun, 14 Jun 2020 22:08:48 -0700' 1592197728
check 'Sun, 14 Jun 2020 -0700' 1592118000 check seconds 'Sun, 14 Jun 2020 -0700' 1592118000
check '2020-06-14' 1592092800 check seconds '2020-06-14' 1592092800
check '2020-06-14T22:14:17-07:00' 1592198057 check seconds '2020-06-14T22:14:17-07:00' 1592198057
# colloquial american format (eww) # colloquial american format (eww)
check '06/14/2020' 1592092800 check seconds '06/14/2020' 1592092800
check '06/01/2020' 1590969600 check seconds '06/01/2020' 1590969600
# Do we transition at the right DST?
@{
rfork en
cat /adm/timezone/US_Eastern >/env/timezone
check date 1710053999 'Sun Mar 10 01:59:59 EST 2024'
check date 1710054000 'Sun Mar 10 02:00:00 EST 2024'
check date 1710054001 'Sun Mar 10 03:00:01 EDT 2024'
check date 1730617200 'Sun Nov 3 03:00:00 EDT 2024'
check date 1730617201 'Sun Nov 3 02:00:01 EST 2024'
check date 1730620800 'Sun Nov 3 03:00:00 EST 2024'
}
# Arizona has no DST # Arizona has no DST
@{ @{
rfork en rfork en
cat /adm/timezone/US_Arizona >/env/timezone cat /adm/timezone/US_Arizona >/env/timezone
check 'Mon, Jun 21 17:38:02 MST 2020' 1592786282 check seconds 'Mon, Jun 21 17:38:02 MST 2020' 1592786282
} }
# CET is a timezone with no hard-coded # CET is a timezone with no hard-coded

View file

@ -254,6 +254,7 @@ tzoffset(Tzone *tz, vlong abs, Tm *tm)
tm->tzoff = 0; tm->tzoff = 0;
return; return;
} }
abs += tz->stdiff;
for(p = tz->dlpairs; *p; p += 2) for(p = tz->dlpairs; *p; p += 2)
if(abs > p[0] && abs <= p[1]){ if(abs > p[0] && abs <= p[1]){
dl = 1; dl = 1;