Ich habe dt = datetime(2013,9,1,11)
und möchte einen Unix-Zeitstempel für dieses Datum / Uhrzeit-Objekt erhalten.
Wenn ich das tue, (dt - datetime(1970,1,1)).total_seconds()
bekomme ich den Zeitstempel 1378033200
.
Beim Zurückkonvertieren habe datetime.fromtimestamp
ich bekommen datetime.datetime(2013, 9, 1, 6, 0)
.
Die Stunde stimmt nicht überein. Was habe ich hier vermisst?
timestamp
Methode wirklich, wirklich verwenden , anstatt zu versuchen, es selbst zu tun. Zum einen wird dadurch die Möglichkeit, naive Zeiten von verschiedenen Zeitzonen zu subtrahieren, vollständig vermieden.dt
das? Ist es eine Ortszeit oder eine Zeit in UTC?Antworten:
Was Sie hier verpasst haben, sind Zeitzonen.
Vermutlich haben Sie fünf Stunden vor UTC, also sind 2013-09-01T11: 00: 00 local und 2013-09-01T06: 00: 00Z dieselbe Zeit.
Sie müssen den Anfang der
datetime
Dokumente lesen , in denen Zeitzonen sowie "naive" und "bewusste" Objekte erläutert werden.Wenn Ihre ursprüngliche naive Datumszeit UTC war, können Sie sie
utcfromtimestamp
anstelle von verwendenfromtimestamp
.Wenn andererseits Ihre ursprüngliche naive Datumszeit lokal war, hätten Sie keinen UTC-Zeitstempel davon subtrahieren sollen. Verwenden Sie
datetime.fromtimestamp(0)
stattdessen.Wenn Sie ein bewusstes Datum / Uhrzeit-Objekt hatten, müssen Sie entweder eine lokale (bewusste) Epoche auf beiden Seiten verwenden oder explizit in und von UTC konvertieren.
Wenn Sie Python 3.3 oder höher haben oder auf dieses aktualisieren können, können Sie all diese Probleme vermeiden, indem Sie einfach die
timestamp
Methode verwenden, anstatt herauszufinden, wie Sie es selbst tun können. Und selbst wenn Sie dies nicht tun, sollten Sie den Quellcode ausleihen .(Und wenn Sie auf Python 3.4 warten können, sieht es so aus, als würde PEP 341 es wahrscheinlich in die endgültige Version schaffen, was bedeutet, dass all die Dinge, über die JF Sebastian und ich in den Kommentaren gesprochen haben, nur mit der stdlib und möglich sein sollten unter Unix und Windows gleich funktionieren.)
quelle
dt
es sich in der lokalen Zeitzone befindet, ist die Formel in der Frage falschdatetime.fromtimestamp(0)
(Epoche in der aktuellen Zeitzone) sollte anstelle vondatetime(1970, 1,1)
(Unix-Epoche in UTC) verwendet werden.fromtimestamp(0)
fehlschlagen, wenn das System keine historischen Zeitzoneninformationen speichert, z. B. unter Windows.pytz
könnte in diesem Fall verwendet werden.pytz
hilft nur, wenn Sie bereits wissen, in welcher Zeitzone Sie sich befinden. Um dies programmgesteuert zu tun, benötigen Sie eine andere Bibliothek, die die aktuelle Windows-Zeitzone abruft und in einepytz
Zeitzone konvertiert und / oder nach Namen sucht.tzlocal
Modul, das auch unter Windows funktioniert. Hier erfahren Sie , wie Sie die UTC-Zeit in die Ortszeit umwandeln können .Lösung ist
quelle
d
ausgegangen, dass es sich um ein naives Datums- / Datums- / Uhrzeitobjekt handelt, das die Ortszeit darstellt (es kann für mehrdeutige Zeiten oder für vergangene / zukünftige Daten fehlschlagen, wenn das Betriebssystem keine historische tz-Datenbank bereitstellt (der UTC-Offset war in der Vergangenheit möglicherweise anders als in der Ortszeit) Zeitzone)). Weitere Optionen .Wenn Sie eine Python-Datumszeit in Sekunden seit der Epoche konvertieren möchten, sollten Sie dies explizit tun:
In Python 3.3+ können Sie
timestamp()
stattdessen Folgendes verwenden :quelle
%s
, da es auf der Uhr des Systems lokalisiert ist, auf dem Sie sich gerade befinden. Sie sollten immer nur verwenden.timestamp()
, um die richtige Epoch / UNIX-Zeit zu erhalten.%s
funktioniert nicht auf Windows-Systemen (ValueError: Invalid format string
)8
oder9
Anstelle dieses Ausdrucks zum Erstellen eines POSIX-Zeitstempels aus
dt
,Benutze das:
Ich bekomme die richtige Antwort in Ihrem Beispiel mit der zweiten Methode.
EDIT: Einige Follow-up ... Nach einigen Kommentaren (siehe unten) war ich neugierig auf den Mangel an Unterstützung oder Dokumentation für
%s
instrftime
. Folgendes habe ich gefunden:In der Python-Quelle für
datetime
undtime
STRFTIME_FORMAT_CODES
sagt uns der String :Also jetzt, wenn wir
man strftime
(auf BSD-Systemen wie Mac OS X) Unterstützung finden für%s
:Aus diesem Grund
%s
funktioniert es auf den Systemen, die es verwendet. Es gibt jedoch bessere Lösungen für das Problem von OP (die Zeitzonen berücksichtigen). Siehe @ abarnerts akzeptierte Antwort hier.quelle
strftime("%s")
in der Dokumentation sehe , habe ich dies nur für Mac und Linux bestätigt. Vielen Dank.time.strftime()
unddatetime.strftime
die an die Plattformen delegierte Dokumentationstrftime(3)
funktionieren für nicht unterstützte Anweisungen.%s
kann sogar unter Mac OS X fehlschlagen, z. B. sollte datetime.strftime ('% s') tzinfo berücksichtigen .%s
da Sie nur die lokalisierte Systemzeit des Systems verwenden, auf dem Sie sich befinden. Sie möchten verwenden,.timestamp()
wenn Sie versuchen, den tatsächlichen UNIX-Zeitstempel abzurufen.Für die Arbeit mit UTC-Zeitzonen:
quelle
Sie haben die Zeitzoneninformationen verpasst (bereits beantwortet, vereinbart)
arrow
Paket ermöglicht es, diese Folter mit datetimes zu vermeiden; Es ist bereits geschrieben, getestet, pypi-veröffentlicht, Cross-Python (2.6 - 3.xx).Alles was Sie brauchen:
pip install arrow
(oder zu Abhängigkeiten hinzufügen)Lösung für Ihren Fall
quelle
Wenn Ihr datetime-Objekt die UTC-Zeit darstellt, verwenden Sie time.mktime nicht, da davon ausgegangen wird, dass sich das Tupel in Ihrer lokalen Zeitzone befindet. Verwenden Sie stattdessen calendar.timegm:
quelle
Nun, wenn Sie in einen Unix-Zeitstempel konvertieren, geht Python grundsätzlich von UTC aus, aber beim Konvertieren erhalten Sie ein Datum, das in Ihre lokale Zeitzone konvertiert wurde.
Siehe diese Frage / Antwort; Ruft die von datetime.datetime.fromtimestamp () verwendete Zeitzone ab.
quelle
Wenn Sie einen UTC-Zeitstempel wünschen:
time.mktime
nur für lokales dt. Die Verwendungcalendar.timegm
ist sicher, aber dt muss die utc-Zone sein, also ändern Sie die Zone in utc. Wenn dt in UTC einfach verwendencalendar.timegm
.quelle
quelle
Diese Klasse deckt Ihre Anforderungen ab. Sie können die Variable an ConvertUnixToDatetime übergeben und aufrufen, von welcher Funktion sie ausgeführt werden soll.
quelle