2013-04-22 38 views
7

在Windows Python環境,我可以得到當地時區這樣的,但它不是使用與pytz:如何將窗口時區轉換爲時區pytz理解?

>>> import win32timezone 
>>> win32timezone.TimeZoneInfo.local() 
TimeZoneInfo(u'US Mountain Standard Time', True) 
>>> win32timezone.TimeZoneInfo.local().timeZoneName 
u'US Mountain Standard Time' 
>>> tz = pytz.timezone(win32timezone.TimeZoneInfo.local().timeZoneName) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Python27\lib\site-packages\pytz\__init__.py", line 185, in timezone 
    raise UnknownTimeZoneError(zone) 
pytz.exceptions.UnknownTimeZoneError: 'US Mountain Standard Time' 

什麼到輸出到區名稱pytz.timezone轉換的好辦法()會明白嗎?


下面是使用tzlocal(感謝馬特)答案:

>>> from tzlocal.win32 import get_localzone_name 
>>> get_localzone_name() 
'America/Phoenix' 
>>> tz = pytz.timezone(get_localzone_name()) 
>>> tz 
<DstTzInfo 'America/Phoenix' MST-1 day, 17:00:00 STD> 

回答

9

不要根據Windows的時區ID的名稱對其名稱做出任何假設。例如US Mountain Standard Time實際上是亞利桑那州大部分地區的Windows時區,亞利桑那州永遠在MST中,因爲它不實施夏令時。但山區其餘時區的Windows ID爲Mountain Standard Time - 其中確實在山區夏令時期間遵循夏令時,但時區ID不變!這兩個區域ID之間的唯一區別是「US」前綴。在IANA/Olson數據庫中,這兩個區域非常明顯 - America/PhoenixAmerica/Denver

您需要的是從Windows到由Unicode CLDR項目提供的Olson時區標識的映射。有關信息和鏈接,請閱讀TimeZone tag wiki。我不確定是否已經有一個用Python實現它的庫 - 你可能需要做一些研究,或者從原始數據中自己實現它。

UPDATE

搜索的位,我發現一個Python庫調用tzlocal具有CLDR映射。它甚至包括一個腳本,可以從CLDR網站獲取當前映射並進行更新。我沒有嘗試過,但似乎有正確的方法。它主要關注於返回當前系統時區,以IANA/Olson身份標識符適用於pytz。 Here is the author's blog post describing its usage.

+0

馬特,謝謝你指出。這似乎是比我原先想象的更復雜的問題。奇怪的是,沒有任何Windows python庫將所有這些考慮在內...... – 2013-04-23 13:36:52

+0

奧爾森數據庫幾乎在任何方面都優越,這就是pytz實現的目標。您是否有理由必須使用Windows時區? – 2013-04-23 15:08:10

+0

我可能錯過了它,但有沒有辦法使用pytz來獲取機器當前時區的奧爾森名稱? – 2013-04-23 16:26:04

4

Anurag Uniyal has posted一種替代的方式來發現它們是由計算機報TZNAME和UTCOFFSET一致的時區的名稱。


跟進馬特·約翰遜的解決方案,在這裏是如何加載從Windows時區ID的Unicode Common Locale Data Repository (CLDR) mapping的Olson時區名:如果你不

import lxml.etree as ET 
import collections 
import pprint 
result = {} 
doc = ET.parse('http://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml') 
for zone in doc.xpath('//mapZone'): 
    attrib = zone.attrib 
    if attrib['territory'] == '001': 
     result[attrib['other']] = attrib['type'] 
pprint.pprint(dict(result)) 

產量

{'AUS Central Standard Time': 'Australia/Darwin', 
'AUS Eastern Standard Time': 'Australia/Sydney', 
'Afghanistan Standard Time': 'Asia/Kabul', 
'Alaskan Standard Time': 'America/Anchorage', 
'Arab Standard Time': 'Asia/Riyadh', 
'Arabian Standard Time': 'Asia/Dubai', 
'Arabic Standard Time': 'Asia/Baghdad', 
'Argentina Standard Time': 'America/Buenos_Aires', 
'Atlantic Standard Time': 'America/Halifax', 
'Azerbaijan Standard Time': 'Asia/Baku', 
'Azores Standard Time': 'Atlantic/Azores', 
'Bahia Standard Time': 'America/Bahia', 
'Bangladesh Standard Time': 'Asia/Dhaka', 
'Canada Central Standard Time': 'America/Regina', 
'Cape Verde Standard Time': 'Atlantic/Cape_Verde', 
'Caucasus Standard Time': 'Asia/Yerevan', 
'Cen. Australia Standard Time': 'Australia/Adelaide', 
'Central America Standard Time': 'America/Guatemala', 
'Central Asia Standard Time': 'Asia/Almaty', 
'Central Brazilian Standard Time': 'America/Cuiaba', 
'Central Europe Standard Time': 'Europe/Budapest', 
'Central European Standard Time': 'Europe/Warsaw', 
'Central Pacific Standard Time': 'Pacific/Guadalcanal', 
'Central Standard Time': 'America/Chicago', 
'Central Standard Time (Mexico)': 'America/Mexico_City', 
'China Standard Time': 'Asia/Shanghai', 
'Dateline Standard Time': 'Etc/GMT+12', 
'E. Africa Standard Time': 'Africa/Nairobi', 
'E. Australia Standard Time': 'Australia/Brisbane', 
'E. Europe Standard Time': 'Asia/Nicosia', 
'E. South America Standard Time': 'America/Sao_Paulo', 
'Eastern Standard Time': 'America/New_York', 
'Egypt Standard Time': 'Africa/Cairo', 
'Ekaterinburg Standard Time': 'Asia/Yekaterinburg', 
'FLE Standard Time': 'Europe/Kiev', 
'Fiji Standard Time': 'Pacific/Fiji', 
'GMT Standard Time': 'Europe/London', 
'GTB Standard Time': 'Europe/Bucharest', 
'Georgian Standard Time': 'Asia/Tbilisi', 
'Greenland Standard Time': 'America/Godthab', 
'Greenwich Standard Time': 'Atlantic/Reykjavik', 
'Hawaiian Standard Time': 'Pacific/Honolulu', 
'India Standard Time': 'Asia/Calcutta', 
'Iran Standard Time': 'Asia/Tehran', 
'Israel Standard Time': 'Asia/Jerusalem', 
'Jordan Standard Time': 'Asia/Amman', 
'Kaliningrad Standard Time': 'Europe/Kaliningrad', 
'Korea Standard Time': 'Asia/Seoul', 
'Magadan Standard Time': 'Asia/Magadan', 
'Mauritius Standard Time': 'Indian/Mauritius', 
'Middle East Standard Time': 'Asia/Beirut', 
'Montevideo Standard Time': 'America/Montevideo', 
'Morocco Standard Time': 'Africa/Casablanca', 
'Mountain Standard Time': 'America/Denver', 
'Mountain Standard Time (Mexico)': 'America/Chihuahua', 
'Myanmar Standard Time': 'Asia/Rangoon', 
'N. Central Asia Standard Time': 'Asia/Novosibirsk', 
'Namibia Standard Time': 'Africa/Windhoek', 
'Nepal Standard Time': 'Asia/Katmandu', 
'New Zealand Standard Time': 'Pacific/Auckland', 
'Newfoundland Standard Time': 'America/St_Johns', 
'North Asia East Standard Time': 'Asia/Irkutsk', 
'North Asia Standard Time': 'Asia/Krasnoyarsk', 
'Pacific SA Standard Time': 'America/Santiago', 
'Pacific Standard Time': 'America/Los_Angeles', 
'Pacific Standard Time (Mexico)': 'America/Santa_Isabel', 
'Pakistan Standard Time': 'Asia/Karachi', 
'Paraguay Standard Time': 'America/Asuncion', 
'Romance Standard Time': 'Europe/Paris', 
'Russian Standard Time': 'Europe/Moscow', 
'SA Eastern Standard Time': 'America/Cayenne', 
'SA Pacific Standard Time': 'America/Bogota', 
'SA Western Standard Time': 'America/La_Paz', 
'SE Asia Standard Time': 'Asia/Bangkok', 
'Samoa Standard Time': 'Pacific/Apia', 
'Singapore Standard Time': 'Asia/Singapore', 
'South Africa Standard Time': 'Africa/Johannesburg', 
'Sri Lanka Standard Time': 'Asia/Colombo', 
'Syria Standard Time': 'Asia/Damascus', 
'Taipei Standard Time': 'Asia/Taipei', 
'Tasmania Standard Time': 'Australia/Hobart', 
'Tokyo Standard Time': 'Asia/Tokyo', 
'Tonga Standard Time': 'Pacific/Tongatapu', 
'Turkey Standard Time': 'Europe/Istanbul', 
'US Eastern Standard Time': 'America/Indianapolis', 
'US Mountain Standard Time': 'America/Phoenix', 
'UTC': 'Etc/GMT', 
'UTC+12': 'Etc/GMT-12', 
'UTC-02': 'Etc/GMT+2', 
'UTC-11': 'Etc/GMT+11', 
'Ulaanbaatar Standard Time': 'Asia/Ulaanbaatar', 
'Venezuela Standard Time': 'America/Caracas', 
'Vladivostok Standard Time': 'Asia/Vladivostok', 
'W. Australia Standard Time': 'Australia/Perth', 
'W. Central Africa Standard Time': 'Africa/Lagos', 
'W. Europe Standard Time': 'Europe/Berlin', 
'West Asia Standard Time': 'Asia/Tashkent', 
'West Pacific Standard Time': 'Pacific/Port_Moresby', 
'Yakutsk Standard Time': 'Asia/Yakutsk'} 

希望您的程序依賴於lxml或網絡連接,您可以將此字典粘貼到模塊中並從此處使用它。

+0

有意思的技巧...我會在明天運行一些常見的時區,讓你知道它是如何工作的! – 2013-04-22 21:35:15

+0

當你談論任何事物的ID時,關閉匹配不是一個好主意。如果他們只是名字,那麼肯定。但每個區域的具體ID具有非常特別的含義。查看我的答案瞭解更多詳情。 – 2013-04-22 21:50:31

+0

更新中有趣的鏈接。我很好奇 - 這對Windows區域有什麼幫助?另外,我不明白他們在那篇文章中看到的是什麼源數據,他們表示他們從linux的'TZ'變量中獲得了價值,但據我所知,這已經是一個Olson標識符,不是? – 2013-04-23 15:17:16