Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#333 wrong timezone info returned by GetTimeZoneInformation()

closed
win32 (141)
5
2009-07-12
2007-08-30
Bernhard
No

In my setting:

Windows XP (German), up-to-date patches applied (including the lated August 2007 timezone database patch)
Python 2.4
pywin 2.10
Timezone Europe/Berlin (+0100) with DST enabled

win32api.GetTimeZoneInformation() returns seemingly wrong information for the date DST ends.

This is shown by the little scripe I have attached, which prints:

>>>
Daylight time begins : Last Sunday in March
Daylight time ends : Last Thursday in October
<<<

Since I am pretty sure that our DST does not end on a Thursday, I suspect an error in either the implementation of GetTimeZoneInformation() or in the WinXP TZ database.

Discussion

1 2 > >> (Page 1 of 2)
  • Bernhard
    Bernhard
    2007-08-30

    script printing DST transition dates

     
    Attachments
  • Logged In: YES
    user_id=599869
    Originator: NO

    I am seeing this behavior on my US Win Vista machine also. I will investigate.

     
  • Logged In: YES
    user_id=599869
    Originator: NO

    It's not immediately clear to me what's going on here. It does appear as if GetTimeZoneInformation() is returning the wrong values.

    >>> win32api.GetTimeZoneInformation()
    (2, (300, u'Eastern Standard Time', <PyTime:01-Nov-2000 02:00:00>, 0, u'Eastern Daylight Time', <PyTime:02-Mar-2000 02:00:00>, -60))

    One interesting point to note is the date is 2000 (not 2007). I don't know why this would be. This year, it should be 04-Nov and 10-Mar. The 01-Nov and 02-Mar does coincide with first and second weeks, so perhaps pywin32 is misinterpreting the structure? It's just a SYSTEMTIME, so that seems unlikely.

    I suspect this problem emerged with the introduction of dynamic time zones. I'd be interested to see what the results of GetDynamicTimeZoneInformation or GetTimeZoneInformationForYear would produce.

    I think the next steps are to (a) double-check the source to confirm the fields are being parsed correctly and (b) to call this from another platform (native C++ or .NET) to see what the results of the call are.

    Bernhard, would you be willing to return the output of the raw GetTimeZoneInformation() call? I think that would help me prove or disprove my theory of the fields being mis-interpreted.

     
  • Logged In: YES
    user_id=599869
    Originator: NO

    I looked into the .NET platform, but it uses a completely different mechanism, apparently, so it was little help.

    ipy
    >>> from System import TimeZone
    >>> localZone = TimeZone.CurrentTimeZone
    >>> print localZone.StandardName
    Eastern Standard Time
    >>> localZone.GetDaylightChanges( 2007 ).Start
    <System.DateTime object at 0x000000000000002D [11-Mar-2007 02:00:00]>

    BTW, 11-Mar is correct (not 10-Mar like I mentioned earlier).

     
  • Bernhard
    Bernhard
    2007-09-04

    Logged In: YES
    user_id=1637368
    Originator: YES

    I had been doing some digging in the source code. I may well be that the problem stems from the fact that the date for changing time zones is stored as a float (seconds since the epoch). As such it does not explicitly store the day of week, but rather the day of week is recalculated in the Format() method.

    Thank you for looking into this.
    Bernhard

     
  • Logged In: YES
    user_id=599869
    Originator: NO

    Indeed, that's my finding as well. It's probably not appropriate to construct a PyTime from the SYSTEMTIME structure in GetTimeZoneInformation, as it's using the day of the week value explicitly.

    In the meantime, Bernhard, you may try using the win32timezone module. I wrote it, and it reads from the registry directly to provide richer timezone support than the Microsoft system calls.

    >>> import win32timezone
    >>> my_tz = win32timezone.GetLocalTimeZone()
    >>> my_tz.GetDSTStartTime(2007)
    datetime.datetime(2007, 3, 11, 2, 0)

    Note there are some changes to this module that aren't in the current release of pywin32 (build 210). I will attach the latest win32timezone.py to this bug for convenience.

     
  • Logged In: YES
    user_id=599869
    Originator: NO

    It seems I can't attach files to a bug I did not create.

     
  • Mark Hammond
    Mark Hammond
    2007-09-04

    • assigned_to: nobody --> jaraco
     
  • Mark Hammond
    Mark Hammond
    2007-09-04

    Logged In: YES
    user_id=14198
    Originator: NO

    Hi jason,
    Thanks for your comments. I've taken the liberty of adding you to the pywin32 project and making you an admin in various places, so now you can be assigned bugs (which I've done here) and should also be able to make any changes to them.

    Cheers

     
  • Logged In: YES
    user_id=599869
    Originator: NO

    I'm attaching a patch that demonstrates (perhaps incorrectly) a way to address this issue. I've never done PythonC programming (that is, extensions to python in C/C++). I used to know C++ like the back of my hand, and now it looks Greek to me.

    What I think I've proposed will change the return value for GetTimeZoneInformation, which will break prior implementations that depend on it. I think Bernhard has demonstrated, however, that any implementations that depend on it are probably flawed anyway, so that's why I'm suggesting changing the interface.

    I think the patch returns a tuple of 8 ints (they're defined as WORDs in the specs) instead of converting to the PyTime object (via PyWinObject_FromSYSTEMTIME).

    This could probably better be implemented with a different class (instead of PyTime) to represent SYSTEMTIME when converting to variant time is inadequate such as in this case.

    Although this is assigned to me, I'd like to defer to Mark as to how he would like to approach this issue. Mark, if you would like me to fully test and implement a full patch, I'll need some assistance on getting a PyWin32 development environment set up.
    File Added: win32apimodule.cpp.systemtime.patch

     
1 2 > >> (Page 1 of 2)