Make Python respond to Windows timezone changes

前端 未结 3 737
别那么骄傲
别那么骄傲 2020-12-10 15:33

When Python is running under Windows, time.localtime does not report the correct time if the timezone is changed during the life time of the Python instance. Under Linux, ti

相关标签:
3条回答
  • 2020-12-10 15:51

    A more rational solution is to use Kernel32's GetLocalTime with pywin32 or ctypes. Any time zone changes are reflected immediately.

    import ctypes
    class SYSTEMTIME(ctypes.Structure):
        _fields_ = [
            ('wYear', ctypes.c_int16),
            ('wMonth', ctypes.c_int16),
            ('wDayOfWeek', ctypes.c_int16),
            ('wDay', ctypes.c_int16),
            ('wHour', ctypes.c_int16),
            ('wMinute', ctypes.c_int16),
            ('wSecond', ctypes.c_int16),
            ('wMilliseconds', ctypes.c_int16)]
    
    SystemTime = SYSTEMTIME()
    lpSystemTime = ctypes.pointer(SystemTime)
    ctypes.windll.kernel32.GetLocalTime(lpSystemTime)
    print SystemTime.wHour, SystemTime.wMinute 
    
    0 讨论(0)
  • 2020-12-10 15:59

    No, this can't be fixed without doing what you did. It is a bit absurd, but if you need the correct time zone in Windows and it has changed during the program's execution, it must be done.

    This probably isn't a bug (the documentation is very clear that the tzset() function is only available on Unix). It's more likely a weakness in Windows that prevents the Python programmers from implementing tzset() under it. You can make a request for a feature enhancement, but it's been this way since Python 2.3 (7 years), so it's unlikely it will actually get implemented.

    0 讨论(0)
  • 2020-12-10 16:03

    The bottom line is that with VC ver 6, tzset() does not work properly. However with VC ver 8 tzset() does work now (I think it may be working in ver 7 also, but I don't have that version to check with).

    So all that has to happen now is to enable HAVE_WORKING_TZSET in the source code and re-compile (and test).

    In my experience, all the needs of functions for different settings of TZ need to have a working tzset(). You must call tzset() any time you change C Lang TZ var -or- Windows TIME_ZONE_INFORMATION. This was not possible in VC ver 6 and that is why HAVE_WORKING_TZSET is not enabled (but should now be for at least VC ver 8 and up).

    BTW. For all the date/time stuff I do, I always have a SetUtcTime() and UnsetUtcTime() which sets TZ to GMT and calls tzset() accordingly. I also have functions to temp set to another timezone as well. This is the ONLY way to do it properly! In many years of experience, I can say anything else is trouble. And calendar.timegm() is not correct. Use tzset().

    Here is proof it is now working (so go bug author to fix the windows code):

    (I typed this from another computer, so hopefully no spelling errors, but it is the point that I making, not the code).


    NOTE: ALL BELOW IS PYTHON (I am calling C Lang from python's ctype interface) NOTE: Because I am setting TZ via DLL boundary here and thread local and all that crap, it cannot be used as a work-around. Must re-enable HAVE_WORKING_TZSET.

    import time
    from ctypes import *
    
    dTime = time.time ()
    nTime = int (dTime)
    intTime = c_int (nTime)
    
    print time.ctime (dTime)
    print c_char_p (cdll.msvcrt.ctime (addressof (intTime))).value
    

    -> ... 21:02:40 ... (python)
    -> ... 21:02:40 ... (C lang)

    cdll.msvcrt._putenv ('TZ=GMT')
    cdll.msvcrt._tzset ()
    

    (normally time.tzset() would be called and also calling inittimezone () to update python's timezone variables as well)

    print time.ctime (dTime)
    print c_char_p (cdll.msvcrt.ctime (addressof (intTime))).value
    

    -> ... 21:02:40 ... (python)
    -> ... 11:02:40 ... (C lang) <- the underlying VC ver 8 is working now!

    (so if HAVE_WORKING_TZSET defined for (ver 8 and up) you would get this:)

    -> ... 11:02:40 ... (python)
    -> ... 11:02:40 ... (C lang)


    Just check the source code to see what I mean.

    I checked this with the latest python '2.0' series: 2.7.2 just now.

    0 讨论(0)
提交回复
热议问题