Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What I learned about Windows and Daylight Saving Time today...

1 view
Skip to first unread message

Jan Dubois

unread,
Mar 5, 2007, 5:47:49 PM3/5/07
to perl5-...@perl.org
Prompted by a bug report regarding the new DST rules I had a closer
look how localtime() determines DST on Windows. Below is my analysis
of the sorry state of affairs, as far as I can tell.

I guess for the vast majority of Windows users this just means that
DST will be wrong for older timestamps. I'm not sure how important
that is though. Providing a proper workaround probably means that
we would have to use the DateTime::TimeZone module within localtime().

=====================================================================
The daylight saving time (DST) for the localtime() function is
determined by the C runtime library function of the same name.

This function has 2 different operating modes:

1) The TZ environment variable has been set.

In this case MSVCRT calculates DST itself, based on the USA rules.
The latest released version (as of (March 5th 2007) of MSVCRT.dll has
not yet been updated for the 2007 DST rules. The localtime() function
will still apply the old rules to 2007. Microsoft claims to have a
hotfix for this, that is available from Microsoft Customer Support
Services only:

http://support.microsoft.com/kb/932590

2) The TZ environment variable has *not* been set.

In this case MSVCRT retrieves the DST transition times from the
GetTimeZoneInformation() API:

http://msdn2.microsoft.com/en-us/library/ms724421.aspx

This API only provides the transition times according to the *current*
DST rules. There is no database of historical transition times. That
means that localtime() applied to previous years will use the new
transition times even for old timestamps.

Windows Vista (and Longhorn Server) support a new API called
GetDynamicTimeZoneInformation() that implements a database of historic
DST rules. It is not known if the hotfix mentioned above will make
use of this API when running on Vista.
=====================================================================

Cheers,
-Jan

Dominic Dunlop

unread,
Mar 6, 2007, 2:48:53 AM3/6/07
to Jan Dubois, perl5-...@perl.org
On 2007–03–05, at 23:47, Jan Dubois wrote:

> Prompted by a bug report regarding the new DST rules I had a closer
> look how localtime() determines DST on Windows. Below is my analysis
> of the sorry state of affairs, as far as I can tell.

> ...


>
> 1) The TZ environment variable has been set.
>
> In this case MSVCRT calculates DST itself, based on the USA rules.
> The latest released version (as of (March 5th 2007) of MSVCRT.dll has
> not yet been updated for the 2007 DST rules. The localtime() function
> will still apply the old rules to 2007. Microsoft claims to have a
> hotfix for this, that is available from Microsoft Customer Support
> Services only:
>
> http://support.microsoft.com/kb/932590
>
> 2) The TZ environment variable has *not* been set.
>
> In this case MSVCRT retrieves the DST transition times from the
> GetTimeZoneInformation() API:
>
> http://msdn2.microsoft.com/en-us/library/ms724421.aspx
>
> This API only provides the transition times according to the *current*
> DST rules. There is no database of historical transition times. That
> means that localtime() applied to previous years will use the new
> transition times even for old timestamps.

I'm definitely not a Windows administrator, but it seems to me that
<http://support.microsoft.com/kb/931836>, which does reference free
downloads updating DST for many locales in several Windows Server
2003 and Windows XP flavours, is relevant. There's also "Daylight
Saving Time Help and Support Center" at <http://support.microsoft.com/
gp/cp_dst>, which seems to leads to a maze of twisty little forms,
all alike. Could somebody with more knowledge than me about comment
about if and how this affects Perl?
--
Dominic Dunlop


Jan Dubois

unread,
Mar 6, 2007, 3:49:31 AM3/6/07
to Dominic Dunlop, perl5-...@perl.org
On Mon, 05 Mar 2007, Dominic Dunlop wrote:

> On 2007-03-05, at 23:47, Jan Dubois wrote:
>
> > 2) The TZ environment variable has *not* been set.
> >
> > In this case MSVCRT retrieves the DST transition times from the
> > GetTimeZoneInformation() API:
> >
> > http://msdn2.microsoft.com/en-us/library/ms724421.aspx
> >
> > This API only provides the transition times according to the
> > *current* DST rules. There is no database of historical transition
> > times. That means that localtime() applied to previous years will
> > use the new transition times even for old timestamps.
>
> I'm definitely not a Windows administrator, but it seems to me that
> <http://support.microsoft.com/kb/931836>, which does reference free
> downloads updating DST for many locales in several Windows Server 2003
> and Windows XP flavours, is relevant. There's also "Daylight Saving
> Time Help and Support Center" at <http://support.microsoft.com/
> gp/cp_dst>, which seems to leads to a maze of twisty little forms, all
> alike. Could somebody with more knowledge than me about comment about
> if and how this affects Perl?

All of these downloads update the timezone "database" for the various
countries. This allows GetTimeZoneInformation() to return the correct
DST status for the current and future time for the timezone you selected
in the "Date & Time Properties" Control Panel applet.

The database is stored in the registry at

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones

It looks like Microsoft is also pushing the dynamic settings to older
Windows versions too, but the problem remains that
GetTimeZoneInformation() only returns the current settings and
GetDynamicTimeZoneInformation is only available on Windows Vista.

So unless MSVCRT.dll is being updated to let localtime() access the
timezone database directly, I don't see how any Windows updates can fix
this behavior for Perl. Somehow I doubt this is happening, given that
MSVCRT hasn't even been updated to do the right thing if you do set the
TZ environment variable.

Of course we may see a Windows XP SP3 service pack that backports
GetDynamicTImeZoneInformation() to XP and includes an updated MSVCRT.dll
that uses this new API, but I wouldn't hold my breath.

Note that we _could_ work around these issues for Perl by writing our
own localtime() function that either tries to use the updated dynamic
Windows timezone database directly, or that bundles a copy of the Olson
timezone database itself. I'm just afraid that this is a lot of effort
for a small effect.

Maybe we should start with a note in perlport.pod to note the limitation.

Cheers,
-Jan

0 new messages