Don't get into the zone too soon....

by Michael S. Kaplan, published on 2006/12/18 13:13 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2006/12/18/1314233.aspx


Yesterday when I finally got a chance to look at mail I found the following in my inbox:

Michael,

The following is from a post in the microsoft.public.vc.language managed newsgroup; I wasn't sure where else to put it. A person by the name of Jochen Kalmbach suggested I contact you.

Just a few comments with regard to the new Microsoft design of how DST info is stored (for certain time zones), after applying the update KB928388 (http://www.microsoft.com/downloads/details.aspx?familyid=2D0ECBBC-FE8F-4BFC-8667-C1D46662B5B7&displaylang=en).

For those who are not familiar with what the update KB928388 does, here is some info:
http://support.microsoft.com/default.aspx/kb/928388.
http://www.microsoft.com/windows/timezone/dst2007.mspx

After applying the update the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones registry info is updated but a new way of storing the DST (Daylight Saving Time) information has been implemented for time zones where the DST may change from one year to another (e.g. the DST is changing dramatically for 2007 in the US and all US timezones where DST is observed are affected). The new design is interesting. However, after applying the update GetTimeZoneInformation is now returning the DST values for 2007, even though the year is 2006 (tested Windows XP SP2). This affects UTC dates that fall within the four week period (represented by the change in DST between 2006 and 2007) for dates that are converted from that period from UTC to local time (or visa versa). Essentially, these dates are one hour off when converted using the TIME_ZONE_INFORMATION returned via the GetTimeZoneInformation API.

Questions:

  1. I understand that Windows Vista has a new API named GetDynamicTimeZoneInformation, that is designed to return the new DST info implemented in KB928388. Will Windows Vista return the DST info for the actual current year using this API?
  2. If we have to convert a UTC to local time for a year other than the current year (not considering the 2006/2007 bug after applying KB928388), it now makes sense that we should have at least two new APIs that allow you to pass in the "year" that we want the TIME_ZONE_INFORMATION (or DYNAMIC_TIME_ZONE_INFORMATION ) for. Example:

    DWORD GetTimeZoneInformationEx(
      WORD wYear,
      LPTIME_ZONE_INFORMATION lpTimeZoneInformation );

    DWORD WINAPI GetDynamicTimeZoneInformationEx(
      WORD wYear,
      PDYNAMIC_TIME_ZONE_INFORMATION pTimeZoneInformation );

Thanks.

Well, to start with this is just the kind of scenario that dynamic time zones in Vista are there to help out with!

The fact that there is no historical information stored in prior versions is just the way Windows was designed, so the reported problem (especially in prior versions like XP) is by design since attempting to get historical time zone information once the time zone information has changed is simply not possible.

But the design of dynamic time zones is such that the Vista versions of the existing GetTimeZoneInformation/SetTimeZoneInformation functions will continue to work as is, even though the results that GetTimeZoneInformation will return can in fact change from year to year (and the registry will contain the changing information as described in the DYNAMIC_TIME_ZONE_INFORMATION topic (the new struct is used by the GetDynamicTimeZoneInformation and SetDynamicTimeZoneInformation topics).

One could argue (as Michael has, above) that new functions are needed to get and perhaps even set the values for another year beyond the current one. Though I have trouble seeing the actual need, since in the current design we are instructed that the wYear member of both the StandardDate and DaylightDate SYSTEMTIME stucts must always be 0. So why not make a future extension to the existing function(s) that allows one to set the wYear member appropriately if one wants the results of as specific year in a dynamic time zone?

This is not what happens here in Vista now but the updated semantic could be simple -- the whole structure has to be zeroed out, and if it is then the struct becomes an inout struct and the wYear member will then represent the year (according to the semantics of the SYSTEMTIME struct, of course).

More importantly, perhaps in the future TzSpecificLocalTimeToSystemTime and SystemTimeToTzSpecificLocalTime could do something special here in the face of an actual date with a year in it, when running on Vista in a dynamic time zone?

And of course absent such functionality either in Vista or in an update one could still look in the registry, where this information has now been officially documented for the first time ever (not that people were scared off by the lack of documentation here in the past!). So even if none of the above works then one still has the tools in Vista to get the right answer.

The argument one could make in the meantime is that the update described in KB928388 should not be installed until one is ready and willing for the change to happen.

 

This post brought to you by (U+19e0, a.k.a. KHMER SYMBOL PATHAMASAT)


# Maurits [MSFT] on 18 Dec 2006 2:51 PM:

The "tz database" has a list of historical time zone changes.  Some of them are quite perverse...

http://www.twinsun.com/tz/tz-link.htm

http://webexhibits.org/daylightsaving/e.html

Political leader: What time is it?

Scientist: What time do you want it to be?

# Dean Harding on 18 Dec 2006 5:31 PM:

Yeah, I use the tz database myself. It's quite a useful resource, but you've got to make sure you update the database every couple of months, because there are several updates a year (due to all the changes!)

I've been meaning to write a .NET wrapper around the tz database, but I've been too lazy :)

# Kevin Dente on 18 Dec 2006 6:02 PM:

>not that people were scared off by the lack of documentation

>here in the past!

Hmm, yes, it turns out one of our products falls into that category. We have code that reads the time zones from the registry, which breaks on Vista because the "Index" registry entry associated with each time zone no longer exists in Vista. Why the omission? Is there something about the new time zone model that makes the notion of a time zone index invalid?

# Michael Cessna on 5 Jan 2007 1:09 PM:

Thanks for the original response and other responses.

[History]

I've worked with UTC and time zone conversion for the last four years and am pretty intimate with the Microsoft APIs (limited though they are) for dealing with UTC as well as the registry time zone data. My education came from having to create a tool that converted local datetime values into UTC for multiple time zones within a database (both MSSQL and Oracle). That is, each table could contain datetime columns that represented local datetime values for multiple time zones...and each datetime value had to be converted to UTC based on the corresponding time zone (where a time zone was associated with a record via the user that created/modified the record). Needless to say, it was a fun (read lost lots of sleep) experience. :o)

[Challenges]

So I understand the challenges in implementing APIs that work correctly, especially the difficulty of being able to support the new Dynamic DST stuff in versions prior to Vista/Longhorn, which is pretty much impossible given the design. However, I would have hoped for much better support in Vista. Already we've seen problems with Microsoft products after applying the patch (Outlook is especially notable). While these problems don't necessarily break anything (other than throwing dates off for certain periods) they have caused plenty of frustration. There are other areas that return potentially invalid data as well, most notable is the CLR native implementation used for TimeZone.ToUniversalTime (see nativeGetDaylightChanges in the CLR). Essentially, anywhere where a Microsoft product enumerates the time zone data or uses the GetTimeZoneInformation API...is going to return incorrect data for certain dates (see Windows Sidebar [Gadget] (System.Time.timeZones), Microsoft.SharePoint.SPTimeZoneCollection, and others).

[Ideas]

Regarding your ideas with regard to StandardDate and DaylightDate (SYSTEMTIME), I don't think it will be found appropriate to use the Year value to pass in the year. Also, the TzSpecificLocalTimeToSystemTime and SystemTimeToTzSpecificLocalTime APIs should be OK...as long as the correct TIME_ZONE_INFORMATION data is passed in.

[Recommendations]

Provide APIs for fully enumerating time zones and converting dates correctly based on the new Dynamic DST values. This would benefit Microsoft products as well as third party applications.

Thanks.

Regards,

Michael Cessna

old programmer on 9 Dec 2008 7:07 PM:

I wrote a VBScript script for turning TZinfo files into INF files, one for each zone, but after reading these comments I find that not all the assumptions wheron the program was written are right, and then there is also the supposed problem that this design does not work in southern DST. Is that the reason for Namibian DST: runs from April through October with the DST offset 1h west, not east?


referenced by

2008/06/29 Did someone break GetTimeZoneInformation in XP?

2007/01/29 Think of Windows as a hedonist

2006/12/22 Sometimes when sorting the index is the last thing you want to use

go to newer or older post, or back to index or month or day