2013-04-22 61 views
7

Trong môi trường windows python Tôi có thể lấy múi giờ địa phương như thế này, nhưng nó không sử dụng được với pytz:Làm thế nào tôi có thể chuyển đổi múi giờ của windows thành múi giờ mà pytz hiểu được?

>>> 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' 

một cách tốt để chuyển đổi mà đầu ra để một tên múi giờ pytz.timezone là gì() sẽ hiểu?


Dưới đây là câu trả lời bằng tzlocal (nhờ Matt):

>>> 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> 

Trả lời

9

Đừng đưa ra bất kỳ giả định nào về ID thời gian Windows có nghĩa là gì dựa trên tên của nó. Ví dụ: US Mountain Standard Time thực sự là múi giờ của Windows cho phần lớn Arizona, là vĩnh viễn trong MST vì nó không thực hiện tiết kiệm ánh sáng ban ngày. Nhưng ID Windows cho phần còn lại của múi giờ miền núi là Mountain Standard Time - trong đó không theo dõi tiết kiệm ánh sáng ban ngày trong Giờ ban ngày miền núi, nhưng ID múi giờ không thay đổi! Sự khác biệt duy nhất giữa các ID của hai khu vực này là tiền tố "Hoa Kỳ". Trong cơ sở dữ liệu IANA/Olson, đây là hai vùng rất riêng biệt - America/PhoenixAmerica/Denver.

Những gì bạn cần là ánh xạ từ Windows đến ID múi giờ Olson được cung cấp bởi dự án CLDR Unicode. Đọc số TimeZone tag wiki để biết thông tin và liên kết. Tôi không chắc liệu đã có một thư viện thực hiện điều này bằng Python chưa - bạn có thể cần thực hiện một số nghiên cứu hoặc tự thực hiện nó từ dữ liệu thô.

CẬP NHẬT

Một chút tìm kiếm, và tôi tìm thấy một thư viện Python gọi tzlocal có ánh xạ CLDR. Nó thậm chí là loại, đủ để bao gồm một kịch bản mà sẽ đi lấy ánh xạ hiện tại từ trang web CLDR và ​​cập nhật chính nó. Tôi đã không thử nó bản thân mình, nhưng nó dường như có cách tiếp cận chính xác. Nó chủ yếu tập trung vào việc trả về múi giờ hệ thống hiện tại, trong một id IANA/Olson phù hợp để sử dụng với pytz. Here is the author's blog post describing its usage.

+0

Matt, cảm ơn vì đã chỉ ra điều đó. Điều này có vẻ như một vấn đề phức tạp hơn tôi nghĩ ban đầu. Thật lạ lùng khi không có cửa sổ thư viện python nào đưa tất cả điều này vào tài khoản ... –

+0

Cơ sở dữ liệu Olson có ưu thế hơn về mọi mặt, và đó là những gì pytz thực hiện. Có lý do nào bạn phải làm việc với các múi giờ của Windows không? –

+0

Tôi có thể đã bỏ lỡ nó, nhưng có cách nào để sử dụng pytz để có được tên Olsen của múi giờ hiện tại của máy? –

4

Anurag Uniyal has posted một cách khác để khám phá tên múi giờ mà phù hợp với tzname và UTCOFFSET báo cáo của máy tính.


Theo dõi trên giải pháp Matt Johnson, đây là cách bạn có thể tải các Unicode Common Locale Data Repository (CLDR) mapping từ ID múi giờ Windows để tên múi giờ 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)) 

sản lượng

{'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'} 

Nếu bạn không muốn chương trình của bạn phụ thuộc vào lxml hoặc kết nối mạng, bạn có thể dán dict này vào một mô-đun và sử dụng nó từ đó.

+0

kỹ thuật thú vị ... Tôi sẽ chạy qua một số múi giờ chung của tôi vào ngày mai và cho bạn biết cách hoạt động! –

+0

Đóng các trận đấu không phải là một ý tưởng hay khi bạn nói về ID của bất cứ thứ gì. Nếu họ chỉ là tên, thì chắc chắn. Nhưng các ID cụ thể của từng khu vực có ý nghĩa rất cụ thể. Xem câu trả lời của tôi để biết thêm chi tiết. –

+0

Liên kết thú vị trong bản cập nhật của bạn. Tôi đang tò mò mặc dù - làm thế nào điều này giúp với các khu Windows? Ngoài ra, tôi không hiểu dữ liệu nguồn mà họ đang xem trong bài đăng đó, họ nói rằng họ đang nhận được giá trị từ biến 'TZ' của Linux, nhưng theo như tôi có thể nói, đó là một số nhận dạng Olson, phải không? –

Các vấn đề liên quan