Das ISO-Format des Python-UTC-Datetime-Objekts enthält kein Z (Zulu oder Zero offset)
Lesezeit: 8 Minuten
Murali Mopuru
Warum enthält Python 2.7 im Gegensatz zu JavaScript kein Z-Zeichen (Zulu oder Null-Offset) am Ende der Isoformat-Zeichenfolge des UTC-Datetime-Objekts?
Python-datetime-Werte haben KEINE Zeitzoneninformationen. Probieren Sie pytz oder Babel aus, wenn Sie Zeitzoneninformationen in Ihrem Zeitstempel speichern möchten.
– tnknepp
12. Dezember 2013 um 16:06 Uhr
datetime.datetime.utcnow().isoformat() + 'Z'
– jfs
17. Mai 2014 um 3:23 Uhr
Verwandte: Wie erhalte ich eine Datetime-Zeichenfolge im Isoformat einschließlich der Standardzeitzone?
– jfs
5. Oktober 2016 um 19:40 Uhr
..und das fehlende Z führt überraschenderweise dazu, dass einige Dinge nicht funktionieren, zB API-Aufruf
– Kardamom
20. März 2017 um 15:32 Uhr
Es wird noch schlimmer, wenn der letzte Teil von datetime 0 ist, wird es abgeschnitten …
– ntg
25. Mai 2020 um 8:25 Uhr
Manav Kataria
Möglichkeit: isoformat()
Pythons datetime unterstützt die nicht militärische Zeitzone Suffixe wie das Suffix „Z“ für UTC. Der folgende einfache String-Ersatz macht den Trick:
In [1]: import datetime
In [2]: d = datetime.datetime(2014, 12, 10, 12, 0, 0)
In [3]: str(d).replace('+00:00', 'Z')
Out[3]: '2014-12-10 12:00:00Z'
str(d) ist im Wesentlichen dasselbe wie d.isoformat(sep=' ')
Wenn Sie weiter gehen, könnten Sie daran interessiert sein, menschenlesbare Zeitzoneninformationen anzuzeigen, pytz mit strftime%Z Zeitzonenflagge:
In [5]: import pytz
In [6]: d = datetime.datetime(2014, 12, 10, 12, 0, 0, tzinfo=pytz.utc)
In [7]: d
Out[7]: datetime.datetime(2014, 12, 10, 12, 0, tzinfo=<UTC>)
In [8]: d.strftime('%Y-%m-%d %H:%M:%S %Z')
Out[8]: '2014-12-10 12:00:00 UTC'
Sollte das Trennzeichen nicht sein T statt Leerzeichen?
– Marcello Romani
30. März 2019 um 10:19 Uhr
es sollte sein d = datetime.datetime(2014, 12, 10, 12, 0, 0, tzinfo=datetime.timezone.utc) in Zeile 2. Btw., in RFC3339 es sagt, dass ein Leerzeichen ‘ok’ ist (anstelle des ‘T’).
– FObersteiner
9. Juni 2020 um 7:29 Uhr
stiv
Python datetime Objekte haben standardmäßig keine Zeitzoneninformationen, und ohne sie verstößt Python tatsächlich gegen die ISO 8601-Spezifikation (Wenn keine Zeitzoneninformationen angegeben sind, wird die Ortszeit angenommen). Du kannst den … benutzen pytz-Paket um einige Standardzeitzonen zu erhalten, oder direkt eine Unterklasse tzinfo dich selbst:
from datetime import datetime, tzinfo, timedelta
class simple_utc(tzinfo):
def tzname(self,**kwargs):
return "UTC"
def utcoffset(self, dt):
return timedelta(0)
Dann können Sie die Zeitzoneninformationen manuell hinzufügen utcnow():
Beachten Sie, dass dies dem ISO 8601-Format entspricht, das beides zulässt Z oder +00:00 als Suffix für UTC. Beachten Sie, dass letzteres tatsächlich besser dem Standard entspricht, wie Zeitzonen im Allgemeinen dargestellt werden (UTC ist ein Sonderfall).
@ivan_pozdeev Danke für den Link, sehr interessant. Beachten Sie, dass die Änderungen zulassen dateutil funktionieren, wurden sozusagen erst mit Python 3.6 mit PEP 495 implementiert pytz nicht die Standardschnittstelle verwendet haben, ist unfair, weil sich die Schnittstelle geändert hat. Vor der Änderung war der einzige Weg, es zum Laufen zu bringen, der Weg pytz geschafft.
– Markieren Sie Lösegeld
30. Oktober 2019 um 1:31 Uhr
Clay Risser
Die folgenden Javascript- und Python-Skripte liefern identische Ausgaben. Ich denke, es ist das, wonach Sie suchen.
JavaScript
new Date().toISOString()
Python
from datetime import datetime
datetime.utcnow().isoformat()[:-3]+'Z'
Die Ausgabe, die sie geben, ist die UTC-Zeit (zulu), formatiert als ISO-String mit einer signifikanten Ziffer von 3 Millisekunden und angehängt mit einem Z.
2019-01-19T23:20:25.459Z
Doch wenn now() ist 0 Millisekunden, Minuten und : wird auch gestrippt.
– Michail Murugow
23. November 2020 um 14:00 Uhr
@МихаилМуругов beim Laufen .isoformat()erstellt es eine Zeichenfolge mit einer festen Anzahl von Zeichen einschließlich nachgestellter Nullen, sodass dies zuverlässig funktioniert
– Peter VanderMeer
19. Februar 2021 um 16:09 Uhr
@PeterVanderMeer datetime(2021, 2, 19, 23, 21, 15).isoformat() -> '2021-02-19T23:21:15', datetime(2021, 2, 19, 23, 21, 15, 256).isoformat() -> '2021-02-19T23:21:15.000256'. Unterschiedliche Darstellungen. Mein Fehler ist, dass ich über Minuten geschrieben habe, nicht über Sekunden.
– Michail Murugow
19. Februar 2021 um 16:27 Uhr
Mit Zeitzonenversatz müssen Sie verwenden [:-6]+'Z'.
– Gringo Suave
4. März 2021 um 2:53 Uhr
Hochposten
Ihr Ziel sollte nicht das Hinzufügen eines Z-Zeichens sein, sondern das Generieren einer UTC-bewussten Datetime-Zeichenfolge im ISO 8601-Format. Die Lösung besteht darin, ein UTC-Zeitzonenobjekt an zu übergeben datetime.now() statt zu verwenden datetime.utcnow():
Dass sieht aus Gut, also mal sehen, was Django und dateutil denken:
from django.utils.timezone import is_aware
is_aware(datetime.now(timezone.utc))
>>> True
from dateutil.parser import isoparse
is_aware(isoparse(datetime.now(timezone.utc).isoformat()))
>>> True
Beachten Sie, dass Sie verwenden müssen isoparse() aus dateutil.parser weil die Python-Dokumentation für datetime.fromisoformat() sagt, dass es “das Parsen beliebiger ISO 8601-Zeichenfolgen nicht unterstützt”.
Okay, die Python datetime -Objekt und die ISO 8601-Zeichenfolge sind beide UTC “bewusst”. Sehen wir uns nun an, was JavaScript von der datetime-Zeichenfolge hält. In Anlehnung an diese Antwort erhalten wir:
let date="2020-01-08T06:07:04.492045+00:00";
const dateParsed = new Date(Date.parse(date))
document.write(dateParsed);
document.write("\n");
// Tue Jan 07 2020 22:07:04 GMT-0800 (Pacific Standard Time)
document.write(dateParsed.toISOString());
document.write("\n");
// 2020-01-08T06:07:04.492Z
document.write(dateParsed.toUTCString());
document.write("\n");
// Wed, 08 Jan 2020 06:07:04 GMT
Anmerkungen:
Ich bin dieses Problem mit ein paar Zielen angegangen:
Generieren Sie eine UTC “bewusste” Datetime-Zeichenfolge im ISO 8601-Format
verwenden nur Funktionen der Python-Standardbibliothek für die Erstellung von datetime-Objekten und Zeichenfolgen
validieren Sie das datetime-Objekt und die Zeichenfolge mit dem Django timezone Nutzenfunktion, die dateutil Parser- und JavaScript-Funktionen
Beachten Sie, dass dieser Ansatz nicht ein Z-Suffix und enthalten nicht verwenden utcnow(). Aber es basiert auf der Empfehlung in der Python-Dokumentation und es besteht die Musterung sowohl mit Django als auch mit JavaScript.
Der Grund, warum das “Z” nicht enthalten ist, ist, weil datetime.now() und sogar datetime.utcnow() gibt zeitzonennaive Datetimes zurück, d. h. Datetimes ohne zugeordnete Zeitzoneninformationen. Um eine zeitzonenbewusste datetime zu erhalten, müssen Sie eine Zeitzone als Argument an übergeben datetime.now. Zum Beispiel:
from datetime import datetime, timezone
datetime.utcnow()
#> datetime.datetime(2020, 9, 3, 20, 58, 49, 22253)
# This is timezone naive
datetime.now(timezone.utc)
#> datetime.datetime(2020, 9, 3, 20, 58, 49, 22253, tzinfo=datetime.timezone.utc)
# This is timezone aware
Sobald Sie einen zeitzonenfähigen Zeitstempel haben, enthält das Isoformat eine Zeitzonenbezeichnung. So können Sie dann einen ISO 8601-Zeitstempel erhalten über:
Ich mag diese Antwort, weil die meisten anderen entweder das Hinzufügen von a nicht demonstrieren Z, oder verwenden Sie naive datetime-Objekte. Ich habe das Gefühl, bewusste Objekte zu verwenden, ist der richtige Weg. Einmal sah ich den Unterschied zwischen datetime.utcnow().timestamp() und datetime.now(timezone.utc).timestamp() Ich beschloss zu versuchen, mich an bewusste Objekte zu halten.
– Jason Capriotti
17. April 2021 um 2:00 Uhr
Wenn Sie wirklich den in Javascript zurückgegebenen Wert abgleichen möchten, können Sie Folgendes tun: datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00', 'Z'). Es ist ein bisschen langatmig, aber vielleicht auch leicht zu lesen?
– Jason Capriotti
17. April 2021 um 2:07 Uhr
Ich denke, dies ist angesichts der API-Einschränkungen die beste Antwort, aber diese Bibliothek sollte wirklich eine Methode haben, um dies zu erreichen. Das manuelle Ersetzen von Saitenkomponenten für eine sehr häufige Operation fühlt sich spröde an und sollte unnötig sein.
– Schweinetasche
10. Oktober 2021 um 20:13 Uhr
Michel Samia
In Python >= 3.2 können Sie einfach Folgendes verwenden:
>>> from datetime import datetime, timezone
>>> datetime.now(timezone.utc).isoformat()
'2019-03-14T07:55:36.979511+00:00'
Ich mag diese Antwort, weil die meisten anderen entweder das Hinzufügen von a nicht demonstrieren Z, oder verwenden Sie naive datetime-Objekte. Ich habe das Gefühl, bewusste Objekte zu verwenden, ist der richtige Weg. Einmal sah ich den Unterschied zwischen datetime.utcnow().timestamp() und datetime.now(timezone.utc).timestamp() Ich beschloss zu versuchen, mich an bewusste Objekte zu halten.
– Jason Capriotti
17. April 2021 um 2:00 Uhr
Wenn Sie wirklich den in Javascript zurückgegebenen Wert abgleichen möchten, können Sie Folgendes tun: datetime.now(timezone.utc).isoformat(timespec='milliseconds').replace('+00:00', 'Z'). Es ist ein bisschen langatmig, aber vielleicht auch leicht zu lesen?
– Jason Capriotti
17. April 2021 um 2:07 Uhr
Ich denke, dies ist angesichts der API-Einschränkungen die beste Antwort, aber diese Bibliothek sollte wirklich eine Methode haben, um dies zu erreichen. Das manuelle Ersetzen von Saitenkomponenten für eine sehr häufige Operation fühlt sich spröde an und sollte unnötig sein.
– Schweinetasche
10. Oktober 2021 um 20:13 Uhr
Dima Tisnek
Python-Datetimes sind ein wenig klobig. Verwenden arrow.
Arrow hat im Wesentlichen die gleiche API wie datetime, aber mit Zeitzonen und einigen zusätzlichen Feinheiten, die in der Hauptbibliothek enthalten sein sollten.
Ein mit Javascript kompatibles Format kann erreicht werden durch:
Python-datetime-Werte haben KEINE Zeitzoneninformationen. Probieren Sie pytz oder Babel aus, wenn Sie Zeitzoneninformationen in Ihrem Zeitstempel speichern möchten.
– tnknepp
12. Dezember 2013 um 16:06 Uhr
datetime.datetime.utcnow().isoformat() + 'Z'
– jfs
17. Mai 2014 um 3:23 Uhr
Verwandte: Wie erhalte ich eine Datetime-Zeichenfolge im Isoformat einschließlich der Standardzeitzone?
– jfs
5. Oktober 2016 um 19:40 Uhr
..und das fehlende Z führt überraschenderweise dazu, dass einige Dinge nicht funktionieren, zB API-Aufruf
– Kardamom
20. März 2017 um 15:32 Uhr
Es wird noch schlimmer, wenn der letzte Teil von datetime 0 ist, wird es abgeschnitten …
– ntg
25. Mai 2020 um 8:25 Uhr