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
Exit(0);
end;
var
timerLoUTC, timerHiUTC: int64;
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
i:=0;
while (i<num_types) and (types[i].isdst) do
@ -77,6 +91,15 @@ begin
trans_end:=high(trans_end);
end
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
// Use binary search.
L := 1;
@ -410,6 +433,13 @@ var
readdata:=true;
end;
procedure ClearCurrentTZinfo;
var
i:integer;
begin
for i:=low(CurrentTZinfo) to high(CurrentTZinfo) do
CurrentTZinfo[i] := Default(TTZInfo);
end;
begin
if fn='' then
fn:='localtime';
@ -422,6 +452,7 @@ begin
tzhead:=default(ttzhead);
LockTZInfo;
ReadTimezoneFile:=(readheader() and readdata());
ClearCurrentTZinfo;
UnlockTZInfo;
fpclose(f);
end;

View File

@ -31,9 +31,10 @@ begin
end;
begin
if not ReadTimezoneFile('Europe/Vienna') then // check against Europe/Vienna file
// check against Europe/Vienna file
if not ReadTimezoneFile('Europe/Vienna') then
begin
writeln('timezone file not found');
writeln('Europe/Vienna timezone file not found');
halt(10);
end;
@ -52,5 +53,49 @@ begin
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);
// 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');
end.