Subject: | Time::Local v1.10 problem with transition to GMT daylight saving time |
When using ActivePerl 5.8.6.811 (which includes Time::Local v1.10) on
Windows NT, 2000 and XP with a time zone of GMT, timelocal returns the
wrong number of seconds from the epoch when given a time during the 24
hours after the transition from standard to daylight saving time.
The following shows this (to see the problem you must switch your PC to
the "(GMT) Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London" time
zone if it's not already there):
use Time::Local;
use POSIX;
foreach $hour (0..23)
{
# GMT to BST switch will occur on 27th March 2005
$secs = timelocal(0, 0, $hour, 27, 2, 2005);
printf "Hour %2d -> %s\n", $hour, strftime(
'%Y-%m-%d %H:%M:%S %z', localtime($secs));
}
The same problem occurs with Time::Local v1.11 (from CPAN) but not with
v1.07 (which was included with ActivePerl 5.8.4.810).
The problem doesn't occur with most other time zones I've tried but does
occur with "(GMT-01:00) Azores, Cape Verde Is." just after the opposite
transition (from daylight saving to standard time - 30th October 2005).
I think the problem may be caused by the introduction of the "one-day
delta" at v1.10 and v1.11 (line 156 in v1.10) which wasn't there at
v1.07. If the year is given as >= 100 (as above) $delta will be -86400.
This means that the localtime call on the following line will think it's
in standard time causing $zone_off on line 160 to be zero. In turn that
will cause the 'or return $loc_t' on line 161 to return.
This may also explain the "Azores" case above (their daylight saving
time is actually GMT). Also, changing the year supplied in the code
above from 2005 to 5 gives the right answer - presumably because $delta
will now be +86400 and so gives a localtime during daylight saving.
I don't understand the details of the code well enough to suggest a
patch but I hope the above will give an expert enough to go on!
Roger Picton
Fujitsu Services
Telford, UK
roger.picton@opre.co.uk
25th February 2005