517 Stimmen

Wie erhalte ich einen Wert von datetime.today() in Python, die "timezone aware" ist?

Ich versuche, einen Datumswert von dem Wert von zu subtrahieren datetime.datetime.today() um zu berechnen, wie lange etwas her ist. Aber es beschwert sich:

TypeError: can't subtract offset-naive and offset-aware datetimes

Der Rückgabewert von datetime.datetime.today() scheint nicht "zeitzonenbewusst" zu sein, während mein anderer Datumswert es ist. Wie erhalte ich einen Rückgabewert von datetime.datetime.today() die die Zeitzone berücksichtigt?

Ideal wäre es, wenn das System automatisch die Zeitzone kennen würde.

Im Moment wird mir die Zeit in Ortszeit angezeigt, die zufällig PST ist, d. h. UTC - 8 Stunden. Gibt es im schlimmsten Fall eine Möglichkeit, eine Zeitzone manuell in das Feld datetime Objekt zurückgegeben von datetime.datetime.today() und sie auf UTC-8 einstellen?

511voto

AndiDog Punkte 65445

In der Standardbibliothek gibt es keine plattformübergreifende Möglichkeit, bewusste Zeitzonen zu erstellen, ohne eine eigene Zeitzonenklasse zu erstellen. ( Edita: Python 3.9 führt ein zoneinfo in der Standardbibliothek, die diese Funktionalität bietet).

Unter Windows gibt es win32timezone.utcnow() aber das ist ein Teil von pywin32. Ich würde eher vorschlagen, die pytz-Bibliothek die eine ständig aktualisierte Datenbank mit den meisten Zeitzonen enthält.

Die Arbeit mit lokalen Zeitzonen kann sehr knifflig sein (siehe "Weiterführende Links" weiter unten), so dass Sie in Ihrer gesamten Anwendung lieber UTC verwenden sollten, insbesondere für arithmetische Operationen wie die Berechnung der Differenz zwischen zwei Zeitpunkten.

Sie können das aktuelle Datum/die aktuelle Uhrzeit wie folgt ermitteln:

import pytz
from datetime import datetime
datetime.utcnow().replace(tzinfo=pytz.utc)

Beachten Sie das datetime.today() y datetime.now() Rückgabe der . Zeit, nicht die UTC-Zeit, so dass die Anwendung .replace(tzinfo=pytz.utc) für sie nicht korrekt wäre.

Eine andere schöne Möglichkeit ist:

datetime.now(pytz.utc)

die etwas kürzer ist und das Gleiche bewirkt.


Weitere Lektüre/Beobachtung, warum UTC in vielen Fällen zu bevorzugen ist:

200voto

Flimm Punkte 112964

In Python 3.2+: datetime.timezone.utc :

Die Standardbibliothek macht es viel einfacher, UTC als Zeitzone anzugeben:

>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2020, 11, 27, 14, 34, 34, 74823, tzinfo=datetime.timezone.utc)

Sie können auch eine Datumszeit abrufen, die die lokale Zeitverschiebung enthält, indem Sie astimezone :

>>> datetime.datetime.now(datetime.timezone.utc).astimezone()
datetime.datetime(2020, 11, 27, 15, 34, 34, 74823, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'CET'))

(In Python 3.6+ können Sie die letzte Zeile zu verkürzen: datetime.datetime.now().astimezone() )

Wenn Sie eine Lösung suchen, die nur die Standardbibliothek verwendet und sowohl in Python 2 als auch in Python 3 funktioniert, lesen Sie jfs' Antwort .

In Python 3.9+: zoneinfo um die IANA-Zeitzonendatenbank zu verwenden:

In Python 3.9 können Sie bestimmte Zeitzonen mit Hilfe der Standardbibliothek angeben, indem Sie zoneinfo etwa so:

>>> from zoneinfo import ZoneInfo
>>> datetime.datetime.now(ZoneInfo("America/Los_Angeles"))
datetime.datetime(2020, 11, 27, 6, 34, 34, 74823, tzinfo=zoneinfo.ZoneInfo(key='America/Los_Angeles'))

zoneinfo bezieht seine Zeitzonendatenbank aus dem Betriebssystem oder aus dem PyPI-Paket der ersten Partei tzdata falls vorhanden.

198voto

philfreo Punkte 38965

Abfrage der aktuellen Uhrzeit in einer bestimmten Zeitzone:

import datetime
import pytz
my_date = datetime.datetime.now(pytz.timezone('US/Pacific'))

Denken Sie daran, Folgendes zu installieren pytz Erstens.

50voto

Mihai Capotă Punkte 1791

Ein Einzeiler, der nur die Standardbibliothek verwendet, funktioniert ab Python 3.3. Sie können eine lokale Zeitzone bewusst erhalten datetime Objekt mit astimezone (als vorgeschlagen von johnchen902 ):

from datetime import datetime, timezone

aware_local_now = datetime.now(timezone.utc).astimezone()

print(aware_local_now)
# 2020-03-03 09:51:38.570162+01:00

print(repr(aware_local_now))
# datetime.datetime(2020, 3, 3, 9, 51, 38, 570162, tzinfo=datetime.timezone(datetime.timedelta(0, 3600), 'CET'))

21voto

jfs Punkte 370717

Hier ist eine stdlib-Lösung, die sowohl mit Python 2 als auch 3 funktioniert:

from datetime import datetime

now = datetime.now(utc) # Timezone-aware datetime.utcnow()
today = datetime(now.year, now.month, now.day, tzinfo=utc) # Midnight

donde today ist eine bewusste datetime-Instanz, die den Tagesbeginn (Mitternacht) in UTC darstellt, und utc ist ein tzinfo-Objekt ( Beispiel aus der Dokumentation ):

from datetime import tzinfo, timedelta

ZERO = timedelta(0)

class UTC(tzinfo):
    def utcoffset(self, dt):
        return ZERO

    def tzname(self, dt):
        return "UTC"

    def dst(self, dt):
        return ZERO

utc = UTC()

Verwandt: Leistungsvergleich von mehrere Möglichkeiten, um Mitternacht (Tagesbeginn) für eine bestimmte UTC-Zeit zu erhalten . Hinweis: Es ist komplexer, zu Mitternacht für eine Zeitzone mit nicht festem UTC-Offset ermitteln .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X