Wie konvertiert man ein time.struct_time-Objekt in ein datetime-Objekt?

288

Wie konvertiert man ein Python- time.struct_timeObjekt in ein datetime.datetimeObjekt?

Ich habe eine Bibliothek, die die erste und eine zweite Bibliothek bereitstellt, die die zweite will.

static_rtti
quelle

Antworten:

384

Verwenden Sie time.mktime () , um das Zeittupel (in Ortszeit) in Sekunden seit der Epoche umzuwandeln , und verwenden Sie dann datetime.fromtimestamp () , um das datetime-Objekt abzurufen.

from datetime import datetime
from time import mktime

dt = datetime.fromtimestamp(mktime(struct))
Rod Hyde
quelle
45
Beachten Sie, dass dies vor 1900 fehlschlägt. Sie modernen Menschen erinnern sich nie an diese Einschränkung!
mlissner
3
Wird dies die tm_isdstDaten verlieren ? Ich denke , so wird die resultierende Datetime - Objekt in dem Maße naiv bleibt zurück Noneauf .dst()selbst wenn struct.tm_isdstist 1.
n611x007
3
Dies wird normalerweise funktionieren. Es schlägt jedoch fehl, wenn das Zeittupel über den von mktime akzeptierten Werten liegt, z. B. für den Wert (1970, 1, 1, 0, 0, 0, 0, 1, -1). Ich habe dies festgestellt, nachdem ich den Date-Header auf einer HTTP-Anforderung analysiert habe, die dieses Tupel zurückgegeben hat.
user3820547
3
@richvdh: C-Standard gibt an, dass mktime()dies tm_isdstberücksichtigt werden soll, und Python time.mktime()ruft die C- mktime()Funktion in CPython auf. mktime()kann die falsche Ortszeit wählen, wenn sie nicht eindeutig ist (z. B. während des Übergangs am Ende der Sommerzeit ("Fallback")), wenn dies der Fall struct.tm_isdstist -1oder wenn mktime()auf der angegebenen Plattform die Eingabe ignoriert wird tm_isdst . Wenn die lokale Zeitzone in der Vergangenheit einen anderen utc-Offset hatte und C mktime()keine historische tz-Datenbank verwendet, die die alten utc-Offset-Werte bereitstellen kann, wird mktime()möglicherweise auch ein falscher Wert (z. B. um eine Stunde) zurückgegeben.
JFS
1
@naxa: Wenn mktime()es tm_isdstauf der angegebenen Plattform nicht ignoriert wird (auf meiner), verliert es fromtimestamp()definitiv die Information: Das zurückgegebene naive datetime Objekt, das die Ortszeit darstellt, kann mehrdeutig sein (Zeitstempel -> Ortszeit ist deterministisch (wenn wir Schaltsekunden ignorieren), aber local time -> timestamp may be ambiguous e.g., during end-of-DST transition). Also, fromtimestamp () `wählt möglicherweise einen falschen utc-Offset, wenn keine historische tz-Datenbank verwendet wird.
jfs
123

So was:

>>> structTime = time.localtime()
>>> datetime.datetime(*structTime[:6])
datetime.datetime(2009, 11, 8, 20, 32, 35)
Nadia Alramli
quelle
3
Vergessen Sie nicht, Zeit, Datum
Uhrzeit zu
7
@jhwist - einige Dinge können Menschen vertraut werden, um es selbst herauszufinden :)
orip
14
Mit @rodling the *und **Syntax können Sie ein Objekt vom Typ listy oder dicty erweitern, um Argumente zu trennen - es ist eines meiner Lieblingsstücke der Python-Schönheit. Siehe docs.python.org/2/tutorial/… für weitere Informationen
OrganicPanda
10
Denken Sie daran, dies gibt Ihnen einen ValueError, wenn die struct_time eine Schaltsekunde hat, zB:t=time.strptime("30 Jun 1997 22:59:60", "%d %b %Y %H:%M:%S"); datetime.datetime(*t[:6])
berdario
7
@berdario: um Werte zurückzugeben, die kompatibel sind mit datetime: datetime(*t[:5]+(min(t[5], 59),))zB zu akzeptieren "2015-06-30 16:59:60 PDT".
JFS
37

Dies ist keine direkte Antwort auf Ihre Frage (die bereits ziemlich gut beantwortet wurde). Nachdem ich mich jedoch mehrmals auf das Fundament gebissen habe, kann ich nicht genug betonen, dass es für Sie wichtig wäre, genau zu betrachten, was Ihr time.struct_time-Objekt bereitstellt, im Vergleich zu den anderen Zeitfeldern.

Angenommen, Sie haben sowohl ein time.struct_time-Objekt als auch eine andere Datums- / Zeitzeichenfolge, vergleichen Sie die beiden und stellen Sie sicher, dass Sie keine Daten verlieren und versehentlich ein naives datetime-Objekt erstellen, wenn Sie dies anders tun können.

Zum Beispiel gibt das ausgezeichnete Feedparser-Modul ein "veröffentlichtes" Feld zurück und kann ein time.struct_time-Objekt in seinem "Published_parsed" -Feld zurückgeben:

time.struct_time(tm_year=2013, tm_mon=9, tm_mday=9, tm_hour=23, tm_min=57, tm_sec=42, tm_wday=0, tm_yday=252, tm_isdst=0)

Beachten Sie nun, was Sie tatsächlich mit dem Feld "Veröffentlicht" erhalten.

Mon, 09 Sep 2013 19:57:42 -0400

Bei Stallmans Bart! Zeitzoneninformationen!

In diesem Fall möchte der faule Mann möglicherweise das hervorragende Dateutil-Modul verwenden, um die Zeitzoneninformationen zu speichern:

from dateutil import parser
dt = parser.parse(entry["published"])
print "published", entry["published"])
print "dt", dt
print "utcoffset", dt.utcoffset()
print "tzinfo", dt.tzinfo
print "dst", dt.dst()

was uns gibt:

published Mon, 09 Sep 2013 19:57:42 -0400
dt 2013-09-09 19:57:42-04:00
utcoffset -1 day, 20:00:00
tzinfo tzoffset(None, -14400)
dst 0:00:00

Man könnte dann das zeitzonenbewusste datetime-Objekt verwenden, um die gesamte Zeit auf UTC zu normalisieren oder was auch immer Sie für fantastisch halten.

Lysdexie
quelle
7
Alle *_parsedFelder von feedparsed sind bereits auf UTC normalisiert, wie in der Datumsanalyse-Dokumentation überprüft werden kann, sodass dies redundant ist.
Itorres
1
@itorres: Wenn ich es verstehe, geht es bei dieser Antwort nicht darum, auf UTC zu normalisieren, sondern darum, die Zeitzoneninformationen in einem datetimeObjekt zu behalten, das verloren geht, wenn feedparserRohdaten von Zeichenfolgen analysiert werden.
Davidag