Gibt es eine Möglichkeit, den UTC-Zeitstempel durch Angabe des Datums abzurufen? Was ich erwarten würde:
datetime(2008, 1, 1, 0, 0, 0, 0)
sollte ergeben
1199145600
Das Erstellen eines naiven Datetime-Objekts bedeutet, dass keine Zeitzoneninformationen vorhanden sind. Wenn ich mir die Dokumentation zu datetime.utcfromtimestamp ansehe, bedeutet das Erstellen eines UTC-Zeitstempels, dass die Zeitzoneninformationen weggelassen werden. Ich würde also vermuten, dass das Erstellen eines naiven Datetime-Objekts (wie ich) zu einem UTC-Zeitstempel führen würde. Jedoch:
then = datetime(2008, 1, 1, 0, 0, 0, 0)
datetime.utcfromtimestamp(float(then.strftime('%s')))
führt zu
2007-12-31 23:00:00
Gibt es noch versteckte Zeitzoneninformationen im datetime-Objekt? Was mache ich falsch?
then.strftime('%s')
, dass die Ortszeit erwartet wird , der Zeitstempel jedoch anzeigt, dass diedatetime(2008, 1, 1)
UTC vorliegt.Antworten:
Naiv
datetime
versus bewusstdatetime
Standardobjekte
datetime
werden als "naiv" bezeichnet: Sie speichern Zeitinformationen ohne Zeitzoneninformationen. Stellen Sie sich naivdatetime
als relative Zahl (dh :)+4
ohne eindeutigen Ursprung vor (tatsächlich wird Ihr Ursprung über Ihre Systemgrenze hinweg gemeinsam sein).Denken Sie im Gegensatz dazu an Bewusstsein
datetime
als absolute Zahlen (dh:8
mit einem gemeinsamen Ursprung für die ganze Welt vor.Ohne Zeitzone Informationen Sie können nicht die „naive“ Datetime gegenüber jeder nicht-naive Zeitdarstellung umwandeln (woher kommt
+4
Ziele , wenn wir von nicht wissen , wo Sie anfangen sollen ?). Deshalb können Sie keinedatetime.datetime.toutctimestamp()
Methode haben. (vgl.: http://bugs.python.org/issue1457227 )Um zu überprüfen, ob Sie
datetime
dt
naiv sind, überprüfen Siedt.tzinfo
, obNone
, dann ist es naiv:datetime.now() ## DANGER: returns naïve datetime pointing on local time datetime(1970, 1, 1) ## returns naïve datetime pointing on user given time
Ich habe naive Daten, was kann ich tun?
Sie müssen abhängig von Ihrem speziellen Kontext eine Annahme treffen: Die Frage, die Sie sich stellen müssen, lautet: War Ihre
datetime
UTC? oder war es Ortszeit?Wenn Sie UTC verwendet haben (Sie haben keine Probleme):
import calendar def dt2ts(dt): """Converts a datetime object to UTC timestamp naive datetime will be considered UTC. """ return calendar.timegm(dt.utctimetuple())
Wenn Sie NICHT UTC verwendet haben , willkommen in der Hölle.
Sie müssen Ihre
datetime
nicht naiv machen, bevor Sie die erstere Funktion verwenden, indem Sie ihnen ihre beabsichtigte Zeitzone zurückgeben.Sie benötigen den Namen der Zeitzone und die Information darüber, ob die Sommerzeit bei der Erstellung der naiven Datumszeit des Ziels wirksam war (die letzten Informationen zur Sommerzeit sind für Eckfälle erforderlich):
import pytz ## pip install pytz mytz = pytz.timezone('Europe/Amsterdam') ## Set your timezone dt = mytz.normalize(mytz.localize(dt, is_dst=True)) ## Set is_dst accordingly
Folgen der Nichtbereitstellung
is_dst
:is_dst
Wenn Sie nicht verwenden, wird eine falsche Zeit (und ein falscher UTC-Zeitstempel) generiert, wenn die Zieldatenzeit erstellt wurde, während eine Rückwärts-Sommerzeit eingerichtet wurde (z. B. Ändern der Sommerzeit durch Entfernen einer Stunde).Wenn Sie eine falsche Angabe machen,
is_dst
wird natürlich nur bei DST-Überlappung oder Löchern eine falsche Zeit (und ein falscher UTC-Zeitstempel) generiert. Und wenn auch eine falsche Zeit angegeben wird, gibt das Auftreten in "Löchern" (Zeit, die aufgrund der Vorwärtsverschiebung der Sommerzeit nie existierte)is_dst
eine Interpretation darüber, wie diese falsche Zeit zu berücksichtigen ist, und dies ist der einzige Fall, in dem.normalize(..)
hier tatsächlich etwas getan wird. da es dann als tatsächlich gültige Zeit übersetzt wird (Ändern der Datum / Uhrzeit UND des DST-Objekts, falls erforderlich). Beachten Sie, dass dies.normalize()
nicht erforderlich ist, um am Ende einen korrekten UTC-Zeitstempel zu haben. Dies wird jedoch wahrscheinlich empfohlen, wenn Sie die Idee, falsche Zeiten in Ihren Variablen zu haben, nicht mögen, insbesondere wenn Sie diese Variable an anderer Stelle wiederverwenden.und VERMEIDEN SIE FOLGENDES : (vgl.: Datetime Timezone-Konvertierung mit Pytz )
dt = dt.replace(tzinfo=timezone('Europe/Amsterdam')) ## BAD !!
Warum? weil
.replace()
ersetzt blind dastzinfo
ohne Berücksichtigung der Zielzeit und wählt ein schlechtes DST-Objekt. Während.localize()
Anwendungen der Zielzeit und Ihris_dst
das Recht DST Objekt auszuwählen Hinweis.ALTE falsche Antwort (danke @JFSebastien für das Aufrufen):
Hoffentlich ist es ziemlich einfach, die Zeitzone (Ihren lokalen Ursprung) zu erraten, wenn Sie Ihr naives
datetime
Objekt erstellen, da es mit der Systemkonfiguration zusammenhängt, die Sie hoffentlich NICHT zwischen der naiven Datums- / Uhrzeit-Objekterstellung und dem Zeitpunkt ändern würden, an dem Sie das erhalten möchten UTC-Zeitstempel. Dieser Trick kann verwendet werden, um eine unvollständige Frage zu stellen.Mit verwenden können
time.mktime
wir eine erstellenutc_mktime
:def utc_mktime(utc_tuple): """Returns number of seconds elapsed since epoch Note that no timezone are taken into consideration. utc tuple must be: (year, month, day, hour, minute, second) """ if len(utc_tuple) == 6: utc_tuple += (0, 0, 0) return time.mktime(utc_tuple) - time.mktime((1970, 1, 1, 0, 0, 0, 0, 0, 0)) def datetime_to_timestamp(dt): """Converts a datetime object to UTC timestamp""" return int(utc_mktime(dt.timetuple()))
Sie müssen sicherstellen, dass Ihr
datetime
Objekt in derselben Zeitzone erstellt wird wie das , in dem Sie Ihr Objekt erstellt habendatetime
.Diese letzte Lösung ist falsch, da davon ausgegangen wird, dass der UTC-Offset von jetzt an der gleiche ist wie der UTC-Offset von EPOCH. Dies ist bei vielen Zeitzonen nicht der Fall (zu einem bestimmten Zeitpunkt des Jahres für die Sommerzeit-Offsets (DST)).
quelle
datetime.timestamp()
Methode in Python 3.3.time.mktime()
sollte nur für die Ortszeit verwendet werden.calendar.timegm()
könnte verwendet werden, um utc time tuple in posix timestamp umzuwandeln. Oder besser noch nur datetime-Methoden verwenden. Siehe meine Antwort.replace()
mit einer Zeitzone verwenden, die einen nicht festen utc-Offset hat, wie z'Europe/Amsterdam'
. Siehe Datetime Timezone-Konvertierung mit Pytz ..replace(tzinfo=get_localzone())
? 2-timegm()
kehrtint
bereits zurück. Keine Notwendigkeit, es mit zu wickelnint
. Auch.timetuple()
Tropfen Bruchteile einer Sekunde.Eine andere Möglichkeit ist:
d = datetime.datetime.utcnow() epoch = datetime.datetime(1970,1,1) t = (d - epoch).total_seconds()
Dies funktioniert, da sowohl "d" als auch "epoch" naive Datumsangaben sind, wodurch der Operator "-" gültig wird und ein Intervall zurückgegeben wird.
total_seconds()
wandelt das Intervall in Sekunden um. Beachten Sie, dasstotal_seconds()
sogar ein Float zurückgegeben wirdd.microsecond == 0
quelle
Beachten Sie auch die Funktion calendar.timegm () , wie in diesem Blogeintrag beschrieben:
import calendar calendar.timegm(utc_timetuple)
Die Ausgabe sollte mit der Lösung von Vaab übereinstimmen.
quelle
Wenn sich das eingegebene Datum / Uhrzeit-Objekt in UTC befindet:
>>> dt = datetime(2008, 1, 1, 0, 0, 0, 0) >>> timestamp = (dt - datetime(1970, 1, 1)).total_seconds() 1199145600.0
Hinweis: Es wird float zurückgegeben, dh Mikrosekunden werden als Sekundenbruchteile dargestellt.
Wenn sich das Eingabedatum in UTC befindet:
>>> from datetime import date >>> utc_date = date(2008, 1, 1) >>> timestamp = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * 24*60*60 1199145600
Weitere Informationen finden Sie unter Konvertieren von datetime.date in UTC-Zeitstempel in Python .
quelle
Ich denke, die Hauptantwort ist immer noch nicht so klar, und es lohnt sich, sich die Zeit zu nehmen, um Zeit und Zeitzonen zu verstehen .
Das Wichtigste im Umgang mit Zeit ist, dass Zeit relativ ist !
2017-08-30 13:23:00
: (eine naive Datumszeit), repräsentiert eine Ortszeit irgendwo auf der Welt, aber beachten Sie, dass2017-08-30 13:23:00
in London NICHT DIE GLEICHE ZEIT ist wie2017-08-30 13:23:00
in San Francisco.Da dieselbe Zeitzeichenfolge je nach Standort auf der Welt als unterschiedliche Zeitpunkte interpretiert werden kann, ist ein Absolutwert erforderlich Zeitbegriff .
Ein UTC-Zeitstempel ist eine Zahl in Sekunden (oder Millisekunden) ab Epoche (definiert als
1 January 1970 00:00:00
atGMT
Zeitzone +00: 00 - Offset).Die Epoche ist in der GMT-Zeitzone verankert und daher ein absoluter Zeitpunkt. Ein UTC-Zeitstempel , der ein Versatz von einer absoluten Zeit ist, definiert daher einen absoluten Zeitpunkt .
Dadurch ist es möglich, Ereignisse rechtzeitig zu bestellen.
Ohne Zeitzoneninformationen ist die Zeit relativ und kann nicht in einen absoluten Zeitbegriff umgewandelt werden, ohne einen Hinweis darauf zu geben, in welcher Zeitzone die naive Datumszeit verankert werden soll.
Welche Arten von Zeit werden im Computersystem verwendet?
naive datetime : normalerweise zur Anzeige in der Ortszeit (dh im Browser), wo das Betriebssystem dem Programm Zeitzoneninformationen bereitstellen kann.
UTC-Zeitstempel : Ein UTC-Zeitstempel ist, wie oben erwähnt, ein absoluter Zeitpunkt, der jedoch in einer bestimmten Zeitzone verankert ist. Daher kann ein UTC-Zeitstempel in jeder Zeitzone in eine Datumszeit konvertiert werden, enthält jedoch keine Zeitzoneninformationen. Was bedeutet das? Das bedeutet, dass 1504119325
2017-08-30T18:55:24Z
oder2017-08-30T17:55:24-0100
oder auch entspricht2017-08-30T10:55:24-0800
. Es sagt Ihnen nicht, woher die aufgezeichnete Datums- und Uhrzeitangabe stammt. Es ist in der Regel auf der Serverseite zu zeichnen Ereignisse (Protokolle, etc ...) oder verwendet eine konvertieren Zeitzone bewusst Datetime zu einem absoluten Zeitpunkt und Rechenzeitdifferenzen .ISO-8601-Datums- / Uhrzeitzeichenfolge : ISO-8601 ist ein standardisiertes Format zum Aufzeichnen von Datums- und Uhrzeitangaben mit Zeitzone. (Es gibt tatsächlich mehrere Formate, lesen Sie hier weiter: https://en.wikipedia.org/wiki/ISO_8601 ) Es wird verwendet, um zeitzonenbezogene Datums- / Uhrzeitinformationen auf serialisierbare Weise zwischen Systemen zu kommunizieren.
Wann welche verwenden? oder eher wann müssen Sie sich um Zeitzonen kümmern?
Wenn Sie sich in irgendeiner Weise um die Tageszeit kümmern müssen, benötigen Sie Zeitzoneninformationen. Ein Kalender oder Alarm benötigt eine Tageszeit, um ein Meeting zur richtigen Tageszeit für jeden Benutzer auf der Welt festzulegen. Wenn diese Daten auf einem Server gespeichert werden, muss der Server wissen, welcher Zeitzone die Datumszeit entspricht.
Um Zeitunterschiede zwischen Ereignissen zu berechnen, die von verschiedenen Orten auf der Welt kommen, reicht der UTC-Zeitstempel aus. Sie können jedoch nicht mehr analysieren, zu welcher Tageszeit Ereignisse aufgetreten sind (z. B. für Webanalysen möchten Sie möglicherweise wissen, wann Benutzer zu Ihnen kommen Website in ihrer Ortszeit : Sehen Sie morgens oder abends mehr Benutzer? Ohne Informationen zur Tageszeit können Sie das nicht herausfinden.
Zeitzonenversatz in einer Datumszeichenfolge :
Ein weiterer wichtiger Punkt ist, dass der Zeitzonenversatz in einer Datumszeichenfolge nicht festgelegt ist . Das heißt, weil
2017-08-30T10:55:24-0800
sagt der Offset-0800
oder 8 Stunden zurück , heißt das nicht, dass es immer sein wird!Im Sommer kann es durchaus Sommerzeit sein, und das wäre es auch
-0700
Dies bedeutet, dass der Zeitzonenversatz (+0100) nicht mit dem Zeitzonennamen (Europa / Frankreich) oder sogar der Zeitzonenbezeichnung (MEZ) identisch ist.
America/Los_Angeles
Die Zeitzone ist ein Ort auf der Welt , wird jedochPST
im Winter zur Zeitzonen-Offset-Notation (Pacific Standard Time) undPDT
im Sommer zur (Pacific Daylight Time).Zusätzlich zum Abrufen des Zeitzonenversatzes vom Datenring sollten Sie auch den Zeitzonennamen erhalten, um genau zu sein.
Die meisten Pakete sind in der Lage, numerische Offsets von der Sommerzeit selbst in die Standardzeit umzuwandeln, aber das ist nicht unbedingt trivial, wenn nur der Offset angegeben wird. Zum Beispiel ist die
WAT
Zeitzonenbezeichnung in Westafrika genau wie UTC + 0100CET
Zeitzone in Frankreich, aber Frankreich beobachtet die Sommerzeit, während Westafrika dies nicht tut (weil sie nahe am Äquator liegen).Kurz gesagt, es ist kompliziert. SEHR kompliziert, und deshalb sollten Sie dies nicht selbst tun, sondern einem Paket vertrauen, das es für Sie erledigt, und es auf dem neuesten Stand halten!
quelle
Eine einfache Lösung ohne externe Module:
from datetime import datetime, timezone dt = datetime(2008, 1, 1, 0, 0, 0, 0) int(dt.replace(tzinfo=timezone.utc).timestamp())
quelle
Es gibt tatsächlich ein Problem bei der Verwendung von utcfromtimestamp und der Angabe von Zeitzonen. Ein schönes Beispiel / eine Erklärung finden Sie zu folgender Frage:
Wie wird die Zeitzone (UTC) bei der Konvertierung in Unix-Zeit angegeben? (Python)
quelle
Ich denke, die richtige Art, Ihre Frage zu formulieren, ist
Is there a way to get the timestamp by specifying the date in UTC?
, weil der Zeitstempel nur eine Zahl ist, die absolut und nicht relativ ist. Das relative (oder zeitzonenbezogene) Stück ist das Datum.Ich finde Pandas sehr praktisch für Zeitstempel, also:
import pandas as pd dt1 = datetime(2008, 1, 1, 0, 0, 0, 0) ts1 = pd.Timestamp(dt1, tz='utc').timestamp() # make sure you get back dt1 datetime.utcfromtimestamp(ts1)
quelle
Die akzeptierte Antwort scheint für mich nicht zu funktionieren. Meine Lösung:
import time utc_0 = int(time.mktime(datetime(1970, 01, 01).timetuple())) def datetime2ts(dt): """Converts a datetime object to UTC timestamp""" return int(time.mktime(dt.utctimetuple())) - utc_0
quelle
dt
) UTC-Offset der lokalen Zeitzone und 1970 unterschiedlich ist.mktime()
erwartet Ortszeit.Einfachster Weg:
>>> from datetime import datetime >>> dt = datetime(2008, 1, 1, 0, 0, 0, 0) >>> dt.strftime("%s") '1199163600'
Bearbeiten: @Daniel ist korrekt, dies würde es in die Zeitzone der Maschine konvertieren. Hier ist eine überarbeitete Antwort:
>>> from datetime import datetime, timezone >>> epoch = datetime(1970, 1, 1, 0, 0, 0, 0, timezone.utc) >>> dt = datetime(2008, 1, 1, 0, 0, 0, 0, timezone.utc) >>> int((dt-epoch).total_seconds()) '1199145600'
Tatsächlich muss es nicht einmal angegeben werden
timezone.utc
, da der Zeitunterschied gleich ist, solange beidedatetime
dieselbe Zeitzone (oder keine Zeitzone) haben.>>> from datetime import datetime >>> epoch = datetime(1970, 1, 1, 0, 0, 0, 0) >>> dt = datetime(2008, 1, 1, 0, 0, 0, 0) >>> int((dt-epoch).total_seconds()) 1199145600
quelle
timezone.utc
Objekt (Python 3.2 und neuer) verwenden möchten, verwenden Sie es einfach mit.timestamp()
:datetime(2008, 1, 1, tzinfo=timezone.utc).timestamp()
. Keine Notwendigkeit, ein Epochenobjekt zu erstellen und zu subtrahieren.