Es funktioniert für jede Zeitzone, einschließlich derer, die die Sommerzeit (DST) einhalten, dh es funktioniert für Zeitzonen, die zu unterschiedlichen Zeiten unterschiedliche UTC-Offsets aufweisen können (nicht fester UTC-Offset). Nicht verwenden tz.localize(datetime.now())- es kann während des Übergangs am Ende der Sommerzeit fehlschlagen, wenn die Ortszeit nicht eindeutig ist.
Aber es gibt keinen guten Grund dafür, dass es zeitzonennaiv ist - es ist UTC. Warum müssen Sie eine Bibliothek eines Drittanbieters durchsuchen, damit sie ordnungsgemäß funktioniert?
Mark Ransom
4
Genau; Für mich sind "naive" Zeiten völlig nutzlos. Derzeit wird auf der Python-Liste diskutiert, ob der stdlib Pytz hinzugefügt werden soll. Das Problem ist nicht die Lizenzierung, sondern die Tatsache, dass die Zeitzonendaten so oft aktualisiert werden (was Python selbst nicht sein kann). Außerdem implementiert pytz die tzinfo-Schnittstelle nicht in der erwarteten Weise, sodass Fehler auftreten können, wenn Sie versuchen, einige der Zeitzonen der Stadt zu verwenden astimezone. Datetime hat also nicht nur keine nativen Zeitzonen, sondern die einzige weit verbreitete Implementierung von tzinfo entspricht nicht dem vermeintlichen Standard.
Bobince
5
@bobince Warum funktionieren Pytz und die Standard-Datetime-Bibliotheken nicht für Sie? Der Python-Kern und der Pytz, die sich als unabhängige Projekte entwickeln, reduzieren die logistische Komplexität für das Kernteam. Ja, die Reduzierung der Komplexität für das Python-Kernteam erhöht die Komplexität für alle Python-Benutzer, die sich mit Zeitzonen befassen müssen. Ich vertraue jedoch darauf, dass sie diese Entscheidung aus gutem Grund getroffen haben. Die Regel "Die Standardbibliothek hat keine tzinfo-Instanzen ..." ist großartig, weil es einfach ist. Warum hier eine Ausnahme machen?
Derek Litz
15
Wie wäre es nuru=datetime.now(pytz.utc)
Craig McQueen
4
@bain: nicht benutzen tz.localize(datetime.now()); Verwenden Sie datetime.now(tz)stattdessen.
Welches ist bevorzugt? datetime.now(timezone.utc)oder datetime.utcnow(timezone.utc)?
Jesse Webb
8
datetime.utcnow()nimmt keine Argumente. So müsste es sein datetime.now(timezone.utc).
Craig McQueen
1
datetime.now()gibt die Maschinenzeit zurück, datetime.utcnow()gibt aber die tatsächliche UTC-Zeit zurück.
Babu
13
@Babu: Zeigt datetime.utcnow()nicht tzinfoan, dass es sich um UTC handelt. Gibt datetime.now(datetime.timezone.utc)aber die UTC-Zeit mittzinfo set zurück.
Craig McQueen
@CraigMcQueen Wenn wir also ein tzObjekt im now-Konstruktor übergeben, wird die Zeit dieser Zeitzone zurückgegeben? OK! Vielen Dank für den Hinweis.
Babu
71
Die Standard-Python-Bibliotheken enthalten keine tzinfo-Klassen ( siehe jedoch S. 431 ). Ich kann nur die Gründe erraten. Persönlich denke ich, dass es ein Fehler war, keine tzinfo-Klasse für UTC aufzunehmen, da diese unumstritten genug ist, um eine Standardimplementierung zu haben.
Bearbeiten: Obwohl es keine Implementierung in der Bibliothek gibt, wird in der tzinfoDokumentation eine als Beispiel angegeben .
from datetime import timedelta, tzinfo
ZERO = timedelta(0)# A UTC class.class UTC(tzinfo):"""UTC"""def utcoffset(self, dt):return ZERO
def tzname(self, dt):return"UTC"def dst(self, dt):return ZERO
utc = UTC()
So verwenden Sie es, um die aktuelle Uhrzeit als bewusstes Datum / Uhrzeit-Objekt abzurufen:
from datetime import datetime
now = datetime.now(utc)
Es gibt datetime.timezone.utcin Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
Finden Sie heraus, warum diese Klasse überhaupt nicht bereitgestellt wurde (und, was noch wichtiger ist, für datetimeObjekte verwendet wurde, die von erstellt wurden utcnow()) ...
André Caron
17
Das Zeitzonenobjekt timezone.utcwurde schließlich zu Python 3.2 hinzugefügt. Gibt aus Gründen der Abwärtskompatibilität utcnow()immer noch ein zeitzonenloses Zeitobjekt zurück, aber Sie können das, was Sie möchten, durch Aufrufen erhalten now(timezone.utc).
Mhsmith
4
@rgove, das ist die Art der Korrektur von Fehlern, die für Python 3 ein faires Spiel sein sollte. Sie hätten sich keine Sorgen um die Abwärtskompatibilität machen sollen. Es gibt ein weiteres Beispiel, das ich in den letzten Tagen gelesen habe: Das structModul hat automatische Konvertierungen von Unicode zu Bytestring durchgeführt, und die endgültige Entscheidung war, die Kompatibilität mit früheren Python 3-Versionen zu unterbrechen, um zu verhindern, dass eine schlechte Entscheidung getroffen wird.
@ LS ja, pytzist eine großartige Ressource. Als ich meine Antwort bearbeitet hatte, um sie in den Beispielcode einzufügen, hatte es bereits jemand anderes vorgeschlagen, und ich wollte ihren Donner nicht stehlen.
Mark Ransom
20
Das pytzModul ist eine Option, und es gibt eine andere python-dateutil, die zwar ebenfalls ein Paket eines Drittanbieters ist, jedoch abhängig von Ihren anderen Abhängigkeiten und Ihrem Betriebssystem möglicherweise bereits verfügbar ist.
Ich wollte diese Methode nur als Referenz aufnehmen. Wenn Sie sie bereits python-dateutilfür andere Zwecke installiert haben , können Sie sie verwenden, tzinfoanstatt sie zu duplizierenpytz
import datetime
import dateutil.tz
# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())
Ich stimme eher zu, dass Anrufe an utcnowdie UTC-Zeitzoneninformationen enthalten sollten. Ich vermute, dass dies nicht enthalten ist, da die native datetime-Bibliothek aus Gründen der Kreuzkompatibilität standardmäßig naive datetimes verwendet.
Ich habe den Aufruf datetime.datetime.utcfromtimestamp () verwendet und musste tzinfo hinzufügen. Die zweite Lösung hat für mich funktioniert: utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
Da mein Programm bereits den Import dateutilfür dateutil.parsermochte ich diese Lösung am besten. Es war so einfach wie : utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc()). Viola!!
In der Tat gibt die Python-Datetime-API immer unbekannte Datetime-Objekte zurück, was sehr unglücklich ist. Sobald Sie eines dieser Objekte erhalten, können Sie die Zeitzone nicht mehr kennen. Daher sind diese Objekte für sich genommen ziemlich "nutzlos".
Leider utcnow()werden die Zeitzoneninformationen, wie Sie festgestellt haben , auch dann nicht angezeigt, wenn Sie sie verwenden .
Empfehlungen:
Verwenden Sie immer bewusste datetimeObjekte, dh mit Zeitzoneninformationen. Dadurch wird sichergestellt, dass Sie sie direkt vergleichen können (bewusste und unbewusste datetime
Objekte sind nicht vergleichbar) und sie korrekt an Benutzer zurückgeben. Leverage pytz zu Zeitzone Objekte.
Verwenden Sie ISO 8601 als Eingabe- und Ausgabezeichenfolgenformat. Verwenden Sie datetime.datetime.isoformat()diese Option, um Zeitstempel als Zeichenfolge zurückzugeben, die mit diesem Format formatiert ist, das die Zeitzoneninformationen enthält.
Wenn Sie Zeichenfolgen mit ISO 8601-formatierten Zeitstempeln analysieren müssen, können Sie sich darauf verlassen iso8601, dass Zeitstempel mit korrekten Zeitzoneninformationen zurückgegeben werden. Dies macht Zeitstempel direkt vergleichbar.
Dies ist eine leicht irreführende Empfehlung. Als Faustregel gilt: Niemals mit Zeitzonen umgehen. Speichern und übertragen Sie immer tz unware utc-Objekte (Epochenobjekte). Die Zeitzone sollte nur zum Zeitpunkt der Darstellung in der Benutzeroberfläche berechnet werden
nehem
1
Das hört sich so an, als würde es schon ganz gut zu Juliens Gedanken passen. Welche seiner spezifischen Empfehlungen (wie oben erwähnt) sind irreführend?
Joe D'Andrea
10
So fügen Sie timezoneInformationen in Python 3.2+ hinzu
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)>>>print(d.tzinfo)'UTC+00:00'
Soweit ich aus docs.python.org/library/datetime.html ersehen kann , ist eine Datumszeit ohne tzinfo eine Zeit, in der die Zeitzone nicht angegeben ist. Hier ist die Zeitzone hat angegeben, so logisch sollte vorhanden sein. Es gibt einen großen Unterschied zwischen einem Datum / einer Uhrzeit ohne zugehörige Zeitzone und einem Datum, das definitiv in UTC angegeben ist. (Idealerweise sollten sie verschiedene IMO-Typen sein, aber das ist eine andere Sache ...)
Jon Skeet
@ JonSkeet Ich denke, Sie vermissen Ignacios Argument, dass UTC keine Zeitzone ist. Erstaunlich, dass diese Antwort -9 Punkte hat, während ich dies
CS
3
@CS: Nun, Ignacio hat das nie gesagt ... und obwohl UTC streng genommen keine Zeitzone ist, wird es normalerweise als eine Zeitzone behandelt , um das Leben erheblich zu vereinfachen (auch in Python, z pytz.utc. B. mit ). Beachten Sie, dass es einen großen Unterschied zwischen einem Wert gibt, dessen Versatz von UTC unbekannt ist, und einem Wert, bei dem bekannt ist, dass er 0 ist. Letzteres utcnow()sollte IMO zurückgeben. Dies würde gemäß der Dokumentation zu "Ein bewusstes Objekt wird verwendet, um einen bestimmten Zeitpunkt darzustellen, der nicht interpretiert werden kann" passen.
Antworten:
Das heißt, es ist zeitzonennaiv, sodass Sie es nicht mit verwenden können
datetime.astimezone
Sie können ihm eine Zeitzone wie diese geben
Jetzt können Sie die Zeitzonen ändern
Um die aktuelle Zeit in einer bestimmten Zeitzone abzurufen, können Sie tzinfo
datetime.now()
direkt an Folgendes übergeben :Es funktioniert für jede Zeitzone, einschließlich derer, die die Sommerzeit (DST) einhalten, dh es funktioniert für Zeitzonen, die zu unterschiedlichen Zeiten unterschiedliche UTC-Offsets aufweisen können (nicht fester UTC-Offset). Nicht verwenden
tz.localize(datetime.now())
- es kann während des Übergangs am Ende der Sommerzeit fehlschlagen, wenn die Ortszeit nicht eindeutig ist.quelle
astimezone
. Datetime hat also nicht nur keine nativen Zeitzonen, sondern die einzige weit verbreitete Implementierung von tzinfo entspricht nicht dem vermeintlichen Standard.u=datetime.now(pytz.utc)
tz.localize(datetime.now())
; Verwenden Siedatetime.now(tz)
stattdessen.Beachten Sie, dass das
datetime
Modul ab Python 3.2 enthältdatetime.timezone
. Die Dokumentation fürdatetime.utcnow()
sagt:So können Sie tun:
quelle
datetime.now(timezone.utc)
oderdatetime.utcnow(timezone.utc)
?datetime.utcnow()
nimmt keine Argumente. So müsste es seindatetime.now(timezone.utc)
.datetime.now()
gibt die Maschinenzeit zurück,datetime.utcnow()
gibt aber die tatsächliche UTC-Zeit zurück.datetime.utcnow()
nichttzinfo
an, dass es sich um UTC handelt. Gibtdatetime.now(datetime.timezone.utc)
aber die UTC-Zeit mittzinfo
set zurück.tz
Objekt im now-Konstruktor übergeben, wird die Zeit dieser Zeitzone zurückgegeben? OK! Vielen Dank für den Hinweis.Die Standard-Python-Bibliotheken enthalten keine tzinfo-Klassen ( siehe jedoch S. 431 ). Ich kann nur die Gründe erraten. Persönlich denke ich, dass es ein Fehler war, keine tzinfo-Klasse für UTC aufzunehmen, da diese unumstritten genug ist, um eine Standardimplementierung zu haben.
Bearbeiten: Obwohl es keine Implementierung in der Bibliothek gibt, wird in der
tzinfo
Dokumentation eine als Beispiel angegeben .So verwenden Sie es, um die aktuelle Uhrzeit als bewusstes Datum / Uhrzeit-Objekt abzurufen:
Es gibt
datetime.timezone.utc
in Python 3.2+:quelle
datetime
Objekte verwendet wurde, die von erstellt wurdenutcnow()
) ...timezone.utc
wurde schließlich zu Python 3.2 hinzugefügt. Gibt aus Gründen der Abwärtskompatibilitätutcnow()
immer noch ein zeitzonenloses Zeitobjekt zurück, aber Sie können das, was Sie möchten, durch Aufrufen erhaltennow(timezone.utc)
.struct
Modul hat automatische Konvertierungen von Unicode zu Bytestring durchgeführt, und die endgültige Entscheidung war, die Kompatibilität mit früheren Python 3-Versionen zu unterbrechen, um zu verhindern, dass eine schlechte Entscheidung getroffen wird.tzinfo
Dokumentation Beispiele für Code zur Implementierung enthält, aber diese Funktionalität ist in datetime selbst nicht enthalten! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutcpytz
ist eine großartige Ressource. Als ich meine Antwort bearbeitet hatte, um sie in den Beispielcode einzufügen, hatte es bereits jemand anderes vorgeschlagen, und ich wollte ihren Donner nicht stehlen.Das
pytz
Modul ist eine Option, und es gibt eine anderepython-dateutil
, die zwar ebenfalls ein Paket eines Drittanbieters ist, jedoch abhängig von Ihren anderen Abhängigkeiten und Ihrem Betriebssystem möglicherweise bereits verfügbar ist.Ich wollte diese Methode nur als Referenz aufnehmen. Wenn Sie sie bereits
python-dateutil
für andere Zwecke installiert haben , können Sie sie verwenden,tzinfo
anstatt sie zu duplizierenpytz
Ich stimme eher zu, dass Anrufe an
utcnow
die UTC-Zeitzoneninformationen enthalten sollten. Ich vermute, dass dies nicht enthalten ist, da die native datetime-Bibliothek aus Gründen der Kreuzkompatibilität standardmäßig naive datetimes verwendet.quelle
utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
datetime.now(pytz_tz)
funktioniert immer;datetime.now(dateutil.tz.tzlocal())
kann während der Sommerzeitübergänge fehlschlagen . PEP 495 - Lokale Zeitdisambiguierung könnte diedateutil
Situation in Zukunft verbessern .utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())
(Hinweis:dateutil
Wenn ein nicht fester utc-Offset (z. B.dateutil.tz.tzlocal()
) hier fehlschlägt , verwenden Sie stattdessen einepytz
Lösung auf Basis ).dateutil
fürdateutil.parser
mochte ich diese Lösung am besten. Es war so einfach wie :utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())
. Viola!!Julien Danjou hat einen guten Artikel geschrieben, in dem erklärt wird, warum Sie sich niemals mit Zeitzonen befassen sollten . Ein Ausschnitt:
Leider
utcnow()
werden die Zeitzoneninformationen, wie Sie festgestellt haben , auch dann nicht angezeigt, wenn Sie sie verwenden .Empfehlungen:
quelle
So fügen Sie
timezone
Informationen in Python 3.2+ hinzuquelle
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (Standard, 19. Januar 2017, 14:48:08)quelle
UTC-Daten benötigen keine Zeitzoneninformationen, da sie UTC sind, was per Definition bedeutet, dass sie keinen Versatz haben.
quelle
pytz.utc
. B. mit ). Beachten Sie, dass es einen großen Unterschied zwischen einem Wert gibt, dessen Versatz von UTC unbekannt ist, und einem Wert, bei dem bekannt ist, dass er 0 ist. Letzteresutcnow()
sollte IMO zurückgeben. Dies würde gemäß der Dokumentation zu "Ein bewusstes Objekt wird verwendet, um einen bestimmten Zeitpunkt darzustellen, der nicht interpretiert werden kann" passen.