2013-04-22 35 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