2010-12-05 54 views
7

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

有没有办法解决这个问题没有做荒唐事一样,哦,我不知道......

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

我可以证实这一点,看起来像一个bug给我。 – AndiDog 2010-12-05 20:51:02

+1

为什么需要评估? – 2010-12-05 21:12:59

回答

4

更合理的解决方案是使用Kernel32的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 
3

不,这不可能是固定的没有做,你做了什么。这有点荒谬,但是如果你在Windows中需要正确的时区,并且在程序执行期间发生了变化,那么必须完成。

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

3

底线是VC ver 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以上)。

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

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

(我打这从另一台计算机,所以希望没有拼写错误,但它是 一点,我做,而不是代码)。


注:所有下面是PYTHON NOTE(我从Python的CTYPE接口调用C郎):因为我通过DLL边界这里设置TZ和线程本地和所有 废话,它不能被用来作为解决方法。必须重新启用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分四十秒......(蟒蛇)
- > ...... 21时02分四十秒...(C浪)

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秒......(蟒蛇)
- > ... 11 :02:40 ...(C lang)


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

我用最新的python'2.0'系列检查了这个:2.7.2刚才。