Machen Sie Python auf Windows-Zeitzonenänderungen

Wenn Python unter Windows läuft, gibt time.localtime nicht die korrekte Zeit, wenn die Zeitzone während der Lebensdauer der Python-Instanz geändert wird. Unter Linux kann time.tzset immer ausgeführt werden, um Probleme wie diese zu lindern, aber es scheint kein Äquivalent in Windows zu sein.

Gibt es eine Möglichkeit, dies zu beheben, ohne etwas absurdes zu machen, oh, ich weiß es nicht …

#!/bin/env python real_localtime = eval(subprocess.Popen( ["python","-c", "import time;repr(time.localtime())"], stdout=subprocess.PIPE).communicate()[0]) 

3 Solutions collect form web for “Machen Sie Python auf Windows-Zeitzonenänderungen”

Eine rationellere Lösung besteht darin, Kernel32s GetLocalTime mit pywin32 oder ctypes zu verwenden. Alle Zeitzonenänderungen werden sofort reflektiert.

 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 

Nein, das kann nicht behoben werden, ohne zu tun, was du getan hast. Es ist ein bisschen absurd, aber wenn man die richtige Zeitzone in Windows braucht und sich während der Ausführung des Programms geändert hat, muss es getan werden.

Das ist wohl kein Fehler (die Dokumentation ist ganz klar, dass die Funktion tzset() nur auf Unix verfügbar ist). Es ist eher eine Schwäche in Windows, die die Python-Programmierer daran hindert, tzset() unter ihm zu implementieren. Sie können eine Anfrage für eine Feature-Erweiterung machen, aber es ist so schon seit Python 2.3 (7 Jahre), also ist es unwahrscheinlich, dass es tatsächlich umgesetzt wird.

Die Quintessenz ist, dass bei VC ver 6 tzset () nicht richtig funktioniert. Allerdings mit VC ver 8 tzset () funktioniert jetzt (ich denke, es kann auch in ver 7 arbeiten, aber ich habe nicht diese Version zu überprüfen).

Also alles, was jetzt passieren muss, ist, HAVE_WORKING_TZSET im Quellcode zu aktivieren und neu zu kompilieren (und zu testen).

In meiner Erfahrung müssen alle Bedürfnisse von Funktionen für verschiedene Einstellungen von TZ eine funktionierende tzset () haben. Sie müssen tzset () anrufen, wenn Sie C Lang TZ var -oder- Windows TIME_ZONE_INFORMATION ändern. Dies war in VC ver 6 nicht möglich und deshalb ist HAVE_WORKING_TZSET nicht aktiviert (sollte aber jetzt mindestens VC ver 8 und höher sein).

BTW Für all das Datum / Zeit Zeug, das ich tue, habe ich immer eine SetUtcTime () und UnsetUtcTime (), die TZ auf GMT setzt und tzset () entsprechend anruft. Ich habe auch Funktionen, um auch auf eine andere Zeitzone zu setzen. Dies ist die einzige Möglichkeit, es richtig zu machen! In vielen Jahren der Erfahrung kann ich sagen, alles andere ist Ärger. Und calendar.timegm () ist nicht korrekt. Verwenden Sie tzset ().

Hier ist ein Beweis, dass es jetzt funktioniert (so gehen Bug-Autor, um den Windows-Code zu beheben):

(Ich tippte dies von einem anderen Computer, also hoffentlich keine Rechtschreibfehler, aber es ist der Punkt, den ich mache, nicht den Code).


HINWEIS: ALLE UNTEN IST PYTHON (ich rufe C Lang von der python-Ctype-Schnittstelle an) HINWEIS: Weil ich TZ über DLL-Grenze hier und Thread lokal und all das Mist, kann es nicht als Work-around verwendet werden. Muss HAVE_WORKING_TZSET wieder aktivieren.

 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:40 … (python)
-> … 21:02:40 … (C lang)

 cdll.msvcrt._putenv ('TZ=GMT') cdll.msvcrt._tzset () 

(Normalerweise time.tzset () würde aufgerufen und auch inittimezone () aufgerufen, um auch die Zeitzonenvariablen von python zu aktualisieren)

 print time.ctime (dTime) print c_char_p (cdll.msvcrt.ctime (addressof (intTime))).value 

-> … 21:02:40 … (python)
-> … 11:02:40 … (C lang) <- die zugrunde liegende VC ver 8 arbeitet jetzt!

(Also wenn HAVE_WORKING_TZSET für (ver 8 und up) definiert wurde, bekommst du das 🙂

-> … 11:02:40 … (python)
-> … 11:02:40 … (C lang)


Überprüfe einfach den Quellcode, um zu sehen, was ich meine.

Ich habe das mit der neuesten Python '2.0' Serie überprüft: 2.7.2 gerade jetzt.

Python ist die beste Programmiersprache der Welt.