Ich versuche, einen Datumswert vom Wert von zu subtrahieren, um datetime.today()
zu berechnen, wie lange etwas her ist. Aber es beschwert sich:
TypeError: can't subtract offset-naive and offset-aware datetimes
Der Wert datetime.today()
scheint nicht "zeitzonenbewusst" zu sein, während mein anderer Datumswert ist. Wie erhalte ich einen datetime.today()
zeitzonenabhängigen Wert ?
Im Moment gibt es mir die Zeit in der Ortszeit, die zufällig PST ist, dh UTC - 8 Stunden. Gibt es im schlimmsten Fall eine Möglichkeit, einen Zeitzonenwert manuell in das von zurückgegebene datetime
Objekt einzugeben datetime.today()
und auf UTC-8 zu setzen?
Die ideale Lösung wäre natürlich, die Zeitzone automatisch zu kennen.
datetime.now().astimezone()
seit Python 3.6Antworten:
In der Standardbibliothek gibt es keine plattformübergreifende Möglichkeit, bewusste Zeitzonen zu erstellen, ohne eine eigene Zeitzonenklasse zu erstellen.
Unter Windows gibt es
win32timezone.utcnow()
, aber das ist Teil von pywin32. Ich würde eher vorschlagen, die Pytz-Bibliothek zu verwenden , die eine ständig aktualisierte Datenbank der meisten Zeitzonen enthält.Das Arbeiten mit lokalen Zeitzonen kann sehr schwierig sein (siehe Links "Weiterführende Literatur" weiter unten). Daher möchten Sie möglicherweise lieber UTC in Ihrer gesamten Anwendung verwenden, insbesondere für arithmetische Operationen wie die Berechnung der Differenz zwischen zwei Zeitpunkten.
Sie können das aktuelle Datum / die aktuelle Uhrzeit wie folgt abrufen:
Beachten Sie dies
datetime.today()
unddatetime.now()
geben Sie die Ortszeit und nicht die UTC-Zeit zurück, sodass eine Bewerbung.replace(tzinfo=pytz.utc)
nicht korrekt wäre.Ein weiterer guter Weg, dies zu tun, ist:
Das ist etwas kürzer und macht das gleiche.
Lesen Sie weiter / beobachten Sie, warum Sie UTC in vielen Fällen bevorzugen:
quelle
datetime.now(pytz.utc)
stattdatetime.utcnow().replace(tzinfo = pytz.utc)
?now(utc)
kehrt heute nicht zurück (es sei denn, es ist Mitternacht in UTC), sondern gibt die aktuelle Zeit in UTC zurück. Sie müssen auch.replace(hour=0, minute=0, ...)
den Anfang des Tages bekommen (wiedatetime.today()
)today()
die aktuelle Zeit zurückgegeben wird, nicht Mitternacht. Wenn es einen Anwendungsfall gibt, in dem Mitternacht erforderlich ist, muss der Austausch entsprechend erfolgen. Da die ursprüngliche Frage den Unterschied zwischen Datum und Uhrzeit betraf, glaube ich nicht, dass Mitternacht erforderlich ist.datetime.today()
istcombine(date.today(), time())
.datetime
hat beides.now()
und.today()
Methoden, die (wie Sie richtig betont haben) (fast) dasselbe zurückgeben. Es gibt keinedate.now()
Methode.date
unddatetime
Objekte sind nicht austauschbar. Die Verwendung eines datetime-Objekts anstelle einesdate
Objekts kann zu subtilen Fehlern führen. Ich sehe keinen Grunddatetime.today()
zu existieren, wenn es ein nahezu Duplikat von istdatetime.now()
.timezone.now()
anstelle von,datetime.now()
da UTC automatisch verwendet wird, wennUSE_TZ = True
.timezone
befindet sich unterdjango.utils.timezone
, Dokumentation: docs.djangoproject.com/de/1.11/topics/i18n/timezonesHolen Sie sich die aktuelle Zeit in einer bestimmten Zeitzone:
quelle
datetime.datetime(2016, 11, 5, 9, 43, 45, tzinfo=pytz.timezone('US/Pacific'))
und prüfen Sie, ob dies das ist, was Sie erwartet habenIn Python 3 erleichtert die Standardbibliothek die Angabe von UTC als Zeitzone erheblich:
Wenn Sie eine Lösung suchen, die nur die Standardbibliothek verwendet und sowohl in Python 2 als auch in Python 3 funktioniert, lesen Sie die Antwort von jfs .
Wenn Sie die lokale Zeitzone und nicht UTC benötigen, lesen Sie die Antwort von Mihai Capotă
quelle
Hier ist eine stdlib-Lösung, die sowohl auf Python 2 als auch auf Python 3 funktioniert:
Dabei
today
handelt es sich um eine bekannte datetime-Instanz, die den Beginn des Tages (Mitternacht) in UTC darstellt, undutc
um ein tzinfo-Objekt ( Beispiel aus der Dokumentation ):Verwandte Themen: Leistungsvergleich verschiedener Möglichkeiten, um Mitternacht (Beginn eines Tages) für eine bestimmte UTC-Zeit zu erhalten . Hinweis: Es ist komplexer, Mitternacht für eine Zeitzone mit einem nicht festen UTC-Versatz zu erhalten .
quelle
Eine andere Methode zum Erstellen eines zeitzonensensitiven datetime-Objekts, das die aktuelle Zeit darstellt:
quelle
pytz.utc
undpytz.UTC
beide definiert sind (und gleich sind)replace()
Zeitzone ist in den meisten anderen Anwendungen im Allgemeinen fehleranfällig, währendlocalize()
ing die bevorzugte Methode ist, naiven Zeitstempeln Zeitzone zuzuweisen..localize()
Methode schlägt für mehrdeutige Ortszeiten fehl (Nicht-Utc-Eingabe). Die Antwort von @ philfreo, die verwendet.now(pytz_timezone)
, funktioniert in solchen Fällen weiterhin..now(pytz_timezone)
funktioniert genau das Gleiche wielocalize(utcnow)
: Zuerst wird die aktuelle Zeit in UTC generiert, dann wird ihr eine Zeitzone zugewiesen: "<...> In diesem Fall entspricht das Ergebnistz.fromutc(datetime.utcnow().replace(tzinfo=tz))
". Beide Antworten sind richtig und funktionieren immer.pytz
über OLSON db soll es wissen, wie es in eine beliebige Zeitzone auf der Welt konvertiert werden kann. Es ist schwierig, andere naive (nicht-utc) Zeitzonen bewusst zu machen, da die Sommerzeit nicht eindeutig ist. Das ist kein Problem.localize
(wenn Sie ihm einenis_dst
Wert geben, funktioniert er für jedes Datum). Das ist ein inhärentes Problem der Sommerzeit.Ein Einzeiler, der nur die Standardbibliothek verwendet, funktioniert ab Python 3.3. Sie können ein lokales zeitzonenbewusstes
datetime
Objekt mitastimezone
(wie von johnchen902 vorgeschlagen ) abrufen :quelle
datetime.now()
Argument 3.6 ohne Argumente aufgerufen werden kann und das richtige lokale Ergebnis zurückgibt (datetime
es wird angenommen, dass sich naive s in der lokalen Zeitzone befinden).Wenn Sie Django verwenden , können Sie Daten festlegen, die nicht tz-fähig sind (nur UTC ).
Kommentieren Sie die folgende Zeile in settings.py:
quelle
pytz ist eine Python-Bibliothek, die genaue und plattformübergreifende Zeitzonenberechnungen mit Python 2.3 oder höher ermöglicht.
Mit der stdlib ist dies nicht möglich.
Siehe eine ähnliche Frage zu SO .
quelle
Hier ist eine Möglichkeit, es mit der stdlib zu generieren:
Datum speichert das lokale Datum und den Versatz von UTC , nicht das Datum in der UTC-Zeitzone. Sie können diese Lösung also verwenden, wenn Sie ermitteln müssen, in welcher Zeitzone das Datum generiert wird . In diesem Beispiel und in meiner lokalen Zeitzone:
Der Schlüssel fügt der
%z
Anweisung FORMAT die Direktive hinzu, um den UTC-Offset der generierten Zeitstruktur anzugeben. Andere Darstellungsformate können in dem Datetime - Modul zu Rate gezogen werden docsWenn Sie das Datum in der UTC-Zeitzone benötigen, können Sie time.localtime () durch time.gmtime () ersetzen.
Bearbeiten
Dies funktioniert nur unter Python3 . Die z-Direktive ist für Python 2 _strptime.py-Code nicht verfügbar
quelle
Verwenden Sie dateutil wie in Python datetime.datetime.now () beschrieben, das zeitzonenabhängig ist :
quelle
tzlocal()
Funktion ist immer noch eine der einfachsten Lösungen und sollte hier unbedingt erwähnt werden.Das Abrufen eines zeitzonensensitiven Datums in der
utc
Zeitzone reicht aus, damit die Datumssubtraktion funktioniert.Wenn Sie jedoch ein zeitzonenbewusstes Datum in Ihrer aktuellen Zeitzone wünschen, sollten Sie Folgendes tun
tzlocal
:PS
dateutil
hat eine ähnliche Funktion (dateutil.tz.tzlocal
). Aber trotz der Namen des Teilens hat es eine ganz andere Codebasis, die als festgestellt , von JF Sebastian kann falsche Ergebnisse liefern.quelle
Hier ist eine Lösung mit einer lesbaren Zeitzone, die mit today () funktioniert:
Sie können alle Zeitzonen wie folgt auflisten:
quelle
Speziell für Nicht-UTC-Zeitzonen:
Die einzige Zeitzone, die über eine eigene Methode verfügt, ist
timezone.utc
, aber Sie können eine Zeitzone bei Bedarf mit einem beliebigen UTC-Offset fummeln, indem Sietimedelta
& verwendentimezone
und sie mit erzwingen.replace
.Die Verwendung
timezone(timedelta(hours=n))
als Zeitzone ist hier die wahre Silberkugel, und es gibt viele andere nützliche Anwendungen.quelle
Wenn Sie die aktuelle Uhrzeit und das aktuelle Datum in Python erhalten, importieren Sie Datum und Uhrzeit. Das Pytz-Paket in Python wird angezeigt, nachdem Sie das aktuelle Datum und die aktuelle Uhrzeit wie folgt erhalten haben.
quelle
Eine andere Alternative, meiner Meinung nach eine bessere, ist die Verwendung von
Pendulum
anstelle vonpytz
. Betrachten Sie den folgenden einfachen Code:Um Pendel zu installieren und deren Dokumentation zu sehen, klicken Sie hier . Es bietet unzählige Optionen (wie einfache ISO8601-, RFC3339- und viele andere Formatunterstützung), eine bessere Leistung und tendenziell einfacheren Code.
quelle
Verwenden Sie die unten gezeigte Zeitzone für eine zeitzonenbezogene Datums- und Uhrzeitangabe. Der Standardwert ist UTC:
quelle
Tyler von 'howchoo' hat einen wirklich großartigen Artikel geschrieben, der mir geholfen hat, eine bessere Vorstellung von den Datetime-Objekten zu bekommen, Link unten
Arbeiten mit Datetime
Im Wesentlichen habe ich am Ende meiner beiden datetime-Objekte Folgendes hinzugefügt
Beispiel:
quelle
Versuchen Sie es mit pnp_datetime . Die gesamte Zeit, die verwendet und zurückgegeben wurde, ist mit der Zeitzone verbunden und verursacht keine Offset-naiven und Offset-fähigen Probleme.
quelle
Es sollte betont werden, dass Sie seit Python 3.6 nur die Standardbibliothek benötigen, um ein zeitzonenbewusstes datetime-Objekt zu erhalten, das die Ortszeit darstellt (die Einstellung Ihres Betriebssystems). Verwenden von Astimezone ()
(siehe Kommentar von @ johnchen902).
quelle