2010-12-05 55 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剛纔。