2013-04-22 5 views
7

In einer Python-Umgebung Fenster kann ich die lokale Zeitzone wie diese erhalten, aber es ist nicht verwendbar mit pytz:Wie kann ich Windows-Zeitzonen in Zeitzonen konvertieren, die pytz versteht?

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

Was ist ein guter Weg, um die Ausgabe in einem Zeitzone Namen pytz.timezone() verstehen zu konvertieren?


Hier ist die Antwort mit tzlocal (dank 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> 

Antwort

9

Machen Sie keine Annahmen darüber, was eine Windows-Zeitzonen-ID aufgrund ihres Namens bedeutet. Zum Beispiel US Mountain Standard Time ist eigentlich die Windows-Zeitzone für die Mehrheit von Arizona, die dauerhaft in MST ist, weil es keine Sommerzeiteinsparungen implementiert. Aber die Windows ID für den Rest der Berg Zeitzone ist Mountain Standard Time - die tut folgen Sommerzeit während Mountain Daylight Time, aber die Zeitzone ID ändert sich nicht! Der einzige Unterschied zwischen den IDs dieser beiden Zonen ist das Präfix "US". In der IANA/Olson-Datenbank sind dies zwei sehr unterschiedliche Zonen - America/Phoenix und America/Denver.

Sie benötigen die Zuordnungen von Windows zu Olson-Zeitzonen-IDs, die vom Unicode-CLDR-Projekt bereitgestellt werden. Lesen Sie die TimeZone tag wiki für Informationen und Links. Ich bin unsicher, ob es bereits eine Bibliothek gibt, die dies in Python implementiert - Sie müssen möglicherweise etwas recherchieren oder es selbst aus den Rohdaten implementieren.

UPDATE

Ein bisschen suchen, und fand ich eine Python-Bibliothek tzlocal genannt, die die CLDR Zuordnungen hat. Es ist sogar nett genug, ein Skript aufzunehmen, das die aktuellen Zuordnungen von der CLDR-Website holt und sich selbst aktualisiert. Ich habe es selbst nicht versucht, aber es scheint die richtige Herangehensweise zu haben. Es konzentriert sich hauptsächlich auf die Rückgabe der aktuellen Systemzeitzone in einer IANA/Olson-ID, die für die Verwendung mit Pytz geeignet ist. Here is the author's blog post describing its usage.

+0

Matt, danke für das Hinzeigen. Dies scheint ein komplizierteres Problem zu sein, als ich ursprünglich dachte. Es ist merkwürdig, dass es keine Windows-Python-Bibliothek gibt, die all dies berücksichtigt ... –

+0

Die Olson-Datenbank ist in jeder Hinsicht überlegen, und genau das setzt Pytz ein. Gibt es einen Grund, warum Sie überhaupt mit den Windows-Zeitzonen arbeiten müssen? –

+0

Ich habe es vielleicht verpasst, aber gibt es eine Möglichkeit, Pytz zu verwenden, um den Olsen-Namen der aktuellen Zeitzone der Maschine zu erhalten? –

4

Anurag Uniyal has posted eine alternative Möglichkeit, Zeitzone Namen zu entdecken, die mit dem tzname und UTCOFFSET durch den Computer gemeldet konsistent sind.


Im Anschluss an Matt Johnson-Lösung auf, hier ist, wie Sie die Unicode Common Locale Data Repository (CLDR) mapping von Windows-Zeitzone-IDs Olson Zeitzone Namen laden kann:

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

Erträge

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

Wenn Sie nicht tun Möchte Ihr Programm von lxml oder einer Netzwerkverbindung abhängig sein, könnten Sie dieses Diktat in ein Modul stecken und von dort aus verwenden.

+0

interessante Technik ... Ich werde es morgen durch einige meiner gemeinsamen Zeitzonen laufen lassen und Sie wissen lassen, wie es funktioniert! –

+0

Enge Übereinstimmungen sind keine gute Idee, wenn Sie über IDs von irgendetwas sprechen. Wenn sie nur Namen waren, dann sicher. Aber die spezifischen IDs jeder Zone haben sehr spezielle Bedeutungen. Siehe meine Antwort für weitere Details. –

+0

Interessanter Link in Ihrem Update. Ich bin allerdings neugierig - wie hilft das bei Windows-Zonen? Außerdem verstehe ich nicht, welche Quelldaten sie in diesem Beitrag betrachten, sie geben an, dass sie den Wert von der Linux 'TZ'-Variable bekommen, aber soweit ich das beurteilen kann, ist das schon ein Olson-Bezeichner, nein? –

Verwandte Themen