让Python响应Windows时区更改

当Python在Windows下运行时,如果在Python实例的生命周期中更改时区,则time.localtime不会报告正确的时间。 在Linux下,time.tzset总是可以运行来缓解这样的问题,但是在Windows中似乎没有任何等价物。

有没有办法解决这个问题,而不做一些荒谬的事情,哦,我不知道…

#!/bin/env python real_localtime = eval(subprocess.Popen( ["python","-c", "import time;repr(time.localtime())"], stdout=subprocess.PIPE).communicate()[0]) 

更合理的解决方案是使用coreel32的GetLocalTime与pywin32或ctypes。 任何时区更改都会立即反映出来。

 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 

不,如果不做你做的事情,这是不能修复的。 这有点荒谬,但是如果你需要Windows中的正确时区,并且在程序执行期间已经改变,那么必须完成。

这可能不是一个错误(文档很清楚, tzset()函数只在Unix上可用)。 Windows中的一个弱点更可能是阻止Python程序员在它下面实现tzset() 你可以提出一个功能增强的请求,但是从Python 2.3(7年)开始就是这样的,所以不太可能实现。

底线是VC版本6,tzset()不能正常工作。 然而,用VC第8版tzset()现在可以工作(我认为它也可能在版本7中工作,但我没有该版本检查)。

所以现在只需要在源代码中启用HAVE_WORKING_TZSET并重新编译(和测试)。

根据我的经验,TZ不同设置的所有功能需求都需要有一个工作tzset()。 您必须在您更改C Lang TZ var – 或Windows TIME_ZONE_INFORMATION时调用tzset()。 在VC版本6中这是不可能的,这就是为什么HAVE_WORKING_TZSET没有被启用(但是现在应该至少是VC版本8以上)。

BTW。 对于所有日期/时间的东西,我总是有一个SetUtcTime()和UnsetUtcTime(),它将TZ设置为GMT,并相应地调用tzset()。 我也有温度设置为另一个时区的功能。 这是正确的做法! 在多年的经验中,我可以说任何事情都是麻烦的。 而calendar.timegm()不正确。 使用tzset()。

这是证明它现在正在工作(所以去bug作者修复Windows代码):

(我从另一台计算机输入了这个信息,所以希望没有拼写错误,但这是我所做的,而不是代码)。


注:下面的所有是PYTHON(我从python的ctype接口调用C语言)注意:因为我在这里设置TZ通过DLL边界和线程本地和所有废话,它不能用作解决方法。 必须重新启用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 () 

(通常会调用time.tzset(),并且也调用inittimezone()来更新python的时区变量)

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

– > … 21:02:40 …(python)
– > … 11:02:40 …(C lang)< – 底层的VC版本8正在工作!

(所以如果HAVE_WORKING_TZSET定义(版本8和以上),你会得到这:)

– > … 11:02:40 …(python)
– > … 11:02:40 …(C lang)


只要检查源代码,看看我的意思。

我用最新的python“2.0”系列进行了检查:2.7.2刚才。