Konvertieren von Zeitzone-bewusster Datumszeichenfolge in UTC und zurück in Python

9

Ich analysiere die Warnungen des National Weather Service in eine Webanwendung. Ich möchte die Benachrichtigungen löschen, wenn sie ihre Ablaufzeit erreicht haben. Ich möchte auch die Ablaufzeit im lokalen Zeitformat für den geografischen Bereich anzeigen, zu dem sie gehören.

Die Warnungen decken die gesamten USA ab, daher denke ich, dass es am besten ist, die Zeiten in UTC-Zeitstempeln zu speichern und zu vergleichen. Die Ablaufzeit wird im Feed als Zeichenfolge wie folgt angezeigt: 2011-09-09T22:12:00-04:00 .

Ich verwende das Paket Labix datautils , um die Zeichenfolge zeitzonensensitiv zu analysieren:

%Vor%

Ich bin auch in der Lage, den UTC-Offset in Stunden zu erfassen:

%Vor%

Mit den Methoden datetime.utctimetuple() und time.mktime() kann das analysierte Datum in einen UTC-Zeitstempel konvertiert werden:

%Vor%

An diesem Punkt fühle ich mich ziemlich gut, dass ich die rohen Strings in einen Zeitstempel umwandeln kann, der die Ablaufzeit in UTC darstellt. Ich kann die aktuelle Zeit als UTC-Zeitstempel mit dem Ablauf vergleichen und feststellen, ob sie gelöscht werden muss:

%Vor%

Die Schwierigkeit, die ich habe, ist, meinen gespeicherten UTC-Zeitstempel in das ursprüngliche lokalisierte Format zu konvertieren. Ich habe die Offset-Stunden von der ursprünglichen Konvertierung gespeichert und eine Zeichenfolge, die ich analysiert, um die Zeitzone Label zu speichern:

%Vor%

Ich möchte den UTC-Zeitstempel zurück in eine lokal formatierte Zeit konvertieren, aber die Konvertierung in ein datetime scheint nicht zu funktionieren:

%Vor%

Es sieht so aus als wäre es eine Stunde später. Ich bin nicht sicher, wo der Fehler eingeführt wurde? Ich habe einen weiteren Test zusammengestellt und ähnliche Ergebnisse erzielt:

%Vor%

Kann mir jemand helfen, meinen Fehler zu finden? Ich bin mir nicht sicher, ob es ein Sommerzeitproblem ist? Ich bin auf einige Sachen gestoßen, die mich glauben machen, dass ich versuche, meine Daten und Zeiten zu lokalisieren, aber zu diesem Zeitpunkt bin ich ziemlich ratlos. Ich hatte gehofft, all diese Berechnungen / Vergleiche in einer Zeitzonen-agnostischen Art zu machen.

    
Scott 19.09.2011, 01:39
quelle

2 Antworten

3

Das Problem ist, dass die Sommerzeit zweimal angewendet wird.

Ein triviales Beispiel:

%Vor%

Ich bin ziemlich sicher, dass der Fehler in time.mktime() liegt. Wie es in der Dokumentation heißt:

  

Dies ist die Umkehrfunktion von localtime (). Es ist   Argument ist die struct_time oder das vollständige 9-Tupel (da das dst-Flag ist   erforderlich; benutze -1 als das dst-Flag, wenn es unbekannt ist), was das ausdrückt   Zeit in Ortszeit, nicht UTC. Es gibt eine Gleitkommazahl zurück, z   Kompatibilität mit der Zeit (). Wenn der Eingabewert nicht als dargestellt werden kann   eine gültige Zeit, entweder OverflowError oder ValueError wird ausgelöst (was   hängt davon ab, ob der ungültige Wert von Python oder der   darunterliegende C-Bibliotheken). Das früheste Datum, für das es einen generieren kann   Die Zeit ist plattformabhängig.

Wenn Sie ein Zeittupel an time.mktime() übergeben, erwartet es ein Flag, ob die Zeit in der Sommerzeit ist oder nicht. Wie Sie oben sehen können, gibt utctimetuple() ein Tupel zurück, das mit 0 markiert ist, da es in seiner Funktion steht Dokumentation :

  

Wenn die Datetime-Instanz d naiv ist, ist dies dasselbe wie d.titupuple ()   außer dass tm_isdst unabhängig von dd.dst () auf 0 gesetzt wird   kehrt zurück. DST ist nie für eine UTC-Zeit wirksam.

     

Wenn d bekannt ist, wird d durch Subtraktion auf die UTC-Zeit normalisiert   d.utcoffset () und eine time.struct_time für die normalisierte Zeit ist   ist zurückgekommen. tm_isdst wird auf 0 gezwungen. Beachten Sie, dass das Ergebnis tm_year ist   Mitglied kann MINYEAR-1 oder MAXYEAR + 1 sein, wenn d.year MINYEAR oder MAXYEAR war   und die UTC-Anpassung wird über ein Jahr hinaus verschüttet.

Da Sie time.mktime() gesagt haben, dass Ihre Zeit nicht DST ist, und seine Aufgabe darin besteht, alle Zeiten in Ortszeit umzuwandeln, und es derzeit in Ihrer Region Sommerzeit ist, fügt eine Stunde um es zu Sommerzeit zu machen. Daher das Ergebnis.

Obwohl ich die Post nicht zur Hand habe, bin ich vor ein paar Tagen auf eine Methode gestoßen, um Zeitzonen-bewusste Datumsangaben in naive Ortszeiten umzurechnen. Dies funktioniert möglicherweise viel besser für Ihre Anwendung als das, was Sie gerade tun (verwendet das ausgezeichnete Modul pytz ):

%Vor%

Ersetze 'America / LosAngeles' mit deinem eigenen Zeitzonenstring, den du irgendwo in pytz.all_timezones finden kannst.

    
Dave 28.09.2011, 02:11
quelle
0

datetime.fromtimestamp() ist die richtige Methode, um die lokale Zeit vom POSIX-Zeitstempel zu erhalten. Das Problem in Ihrer Frage besteht darin, dass Sie ein bewusstes Datetime-Objekt mit falschem time.mktime() in den POSIX-Zeitstempel konvertieren. Hier ist einer der richtigen Wege, dies zu tun :

%Vor%     
jfs 20.08.2014 08:29
quelle

Tags und Links