unix: fix timezone info for timers after the last transition

git-svn-id: trunk@49005 -
This commit is contained in:
ondrej 2021-03-19 08:11:10 +00:00
parent 85a8169c48
commit 2a61397d37
2 changed files with 79 additions and 3 deletions

View File

@ -64,8 +64,22 @@ var
else else
Exit(0); Exit(0);
end; end;
var
timerLoUTC, timerHiUTC: int64;
begin begin
if (num_transitions=0) or (timer<transitions[0]) then if (num_transitions>0) and not timerIsUTC then
begin
timerLoUTC:=timer-types[type_idxs[0]].offset;
timerHiUTC:=timer-types[type_idxs[num_transitions-1]].offset;
end
else
begin
timerLoUTC:=timer;
timerHiUTC:=timer;
end;
if (num_transitions=0) or (timerLoUTC<transitions[0]) then
{ timer is before the first transition }
begin begin
i:=0; i:=0;
while (i<num_types) and (types[i].isdst) do while (i<num_types) and (types[i].isdst) do
@ -77,6 +91,15 @@ begin
trans_end:=high(trans_end); trans_end:=high(trans_end);
end end
else else
if (num_transitions>0) and (timerHiUTC>=transitions[num_transitions-1]) then
{ timer is after the last transition }
begin
i:=type_idxs[num_transitions-1];
trans_start:=transitions[num_transitions-1];
trans_end:=high(trans_end);
end
else
{ timer inbetween }
begin begin
// Use binary search. // Use binary search.
L := 1; L := 1;
@ -410,6 +433,13 @@ var
readdata:=true; readdata:=true;
end; end;
procedure ClearCurrentTZinfo;
var
i:integer;
begin
for i:=low(CurrentTZinfo) to high(CurrentTZinfo) do
CurrentTZinfo[i] := Default(TTZInfo);
end;
begin begin
if fn='' then if fn='' then
fn:='localtime'; fn:='localtime';
@ -422,6 +452,7 @@ begin
tzhead:=default(ttzhead); tzhead:=default(ttzhead);
LockTZInfo; LockTZInfo;
ReadTimezoneFile:=(readheader() and readdata()); ReadTimezoneFile:=(readheader() and readdata());
ClearCurrentTZinfo;
UnlockTZInfo; UnlockTZInfo;
fpclose(f); fpclose(f);
end; end;

View File

@ -31,9 +31,10 @@ begin
end; end;
begin begin
if not ReadTimezoneFile('Europe/Vienna') then // check against Europe/Vienna file // check against Europe/Vienna file
if not ReadTimezoneFile('Europe/Vienna') then
begin begin
writeln('timezone file not found'); writeln('Europe/Vienna timezone file not found');
halt(10); halt(10);
end; end;
@ -52,5 +53,49 @@ begin
if GetOffset(2019, 10, 27, 0, 59, 0, True)<>2 then Halt(17); if GetOffset(2019, 10, 27, 0, 59, 0, True)<>2 then Halt(17);
if GetOffset(2019, 10, 27, 1, 0, 0, True)<>1 then Halt(18); if GetOffset(2019, 10, 27, 1, 0, 0, True)<>1 then Halt(18);
// check against Europe/Moscow file
if not ReadTimezoneFile('Europe/Moscow') then
begin
writeln('Europe/Moscow timezone file not found');
halt(20);
end;
{
https://en.wikipedia.org/wiki/Time_in_Russia
Daylight saving time was re-introduced in the USSR in 1981, beginning on 1 April and ending on 1 October each year,
until mid-1984, when the USSR began following European daylight saving time rules, moving clocks forward one hour
at 02:00 local standard time on the last Sunday in March, and back one hour at 03:00 local daylight time on the last
Sunday in September until 1995, after which the change back occurred on the last Sunday in October.
On 27 March 2011, clocks were advanced as usual, but they did not go back on 30 October 2011, effectively making
Moscow Time UTC+04:00 permanently. On 26 October 2014, following another change in the law, the clocks in most
of the country were moved back one hour, but summer Daylight Time was not reintroduced; Moscow Time returned
to UTC+03:00 permanently.
}
if GetOffset(1994, 03, 26, 0, 0, 0, True)<>3 then Halt(21);
if GetOffset(1994, 03, 27, 0, 0, 0, True)<>4 then Halt(22);
if GetOffset(1994, 09, 24, 0, 0, 0, True)<>4 then Halt(23);
if GetOffset(1994, 09, 25, 0, 0, 0, True)<>3 then Halt(24);
if GetOffset(1996, 03, 30, 0, 0, 0, True)<>3 then Halt(25);
if GetOffset(1996, 03, 31, 0, 0, 0, True)<>4 then Halt(26);
if GetOffset(1996, 10, 26, 0, 0, 0, True)<>4 then Halt(27);
if GetOffset(1996, 10, 27, 0, 0, 0, True)<>3 then Halt(28);
if GetOffset(2011, 03, 26, 0, 0, 0, True)<>3 then Halt(29);
if GetOffset(2011, 03, 27, 0, 0, 0, True)<>4 then Halt(30);
if GetOffset(2011, 09, 01, 0, 0, 0, True)<>4 then Halt(31);
if GetOffset(2011, 11, 01, 0, 0, 0, True)<>4 then Halt(32);
if GetOffset(2012, 06, 01, 0, 0, 0, True)<>4 then Halt(33);
if GetOffset(2014, 10, 25, 0, 0, 0, True)<>4 then Halt(34);
if GetOffset(2014, 10, 26, 0, 0, 0, True)<>3 then Halt(35);
if GetOffset(2021, 03, 31, 0, 0, 0, True)<>3 then Halt(36);
writeln('ok'); writeln('ok');
end. end.