Ich fand es schwierig zu verstehen, wie man mit Zeitzonen in Python umgeht, daher ist dies ein organisiertes Memo.
Versionsinformation
Es gibt die folgenden zwei Arten von Instanzen in derselben Klasse.
Aware and Naive Objects - datetime — Basic date and time types — Python 3.8.1rc1 documentation
from datetime import datetime
from datetime import timezone
now = datetime.now()
print(now) # =>Jetzt in Japan Zeit
print(now.tzinfo) # => None
# Naive
now = datetime.utcnow()
print(now) # =>Zeit minus 9 Stunden ab Japan
print(now.tzinfo) # => None
# Naive
now = datetime.now(timezone.utc)
print(now) #Zu der Zeit minus 9 Stunden"+00:00"Mit der Notation
print(now.tzinfo) # => UTC
# Aware
from datetime import datetime
from datetime import timezone
unixtime = 1572764400
now = datetime.fromtimestamp(unixtime)
print(now) # =>Notation in der japanischen Zeit des Augenblicks, dargestellt durch die Unix-Zeit
print(now.tzinfo) # => None
# Naive
now = datetime.utcfromtimestamp(unixtime)
print(now) #Zeit minus 9 Stunden=Notation in UTC im Moment dargestellt durch Unix-Zeit
print(now.tzinfo) # => None
# Naive
now = datetime.fromtimestamp(unixtime, timezone.utc)
print(now) #Zu der Zeit minus 9 Stunden"+00:00"Mit der Notation
print(now.tzinfo)
# => UTC
# Aware
from datetime import datetime
from datetime import timedelta
now = datetime.now() # Naive
print(now) # =>Jetzt in Japan Zeit(Keine Zeitzoneninformationen)
print(now - timedelta(hours = +9)) # =>Zeit minus 9 Stunden(Keine Zeitzoneninformationen)
now = datetime.utcnow() # Naive
print(now) # =>Ich habe jetzt 9 Stunden gezogen(Keine Zeitzoneninformationen)
print(now + timedelta(hours = +9)) # =>9 Stunden Japanzeit hinzugefügt(Keine Zeitzoneninformationen)
tzinfo
ist eine abstrakte Klasse mit den folgenden Informationen.
tzinfo - datetime — Basic date and time types — Python 3.8.1rc1 documentation
Verwenden Sie "Zeitzone" oder "Pytz" als konkrete Klasse. pytz
befindet sich nicht in der Standardbibliothek und muss installiert werden.
timezone
ist eine konkrete Klasse von tzinfo
mit einem festen Versatzwert. Es ist fest und kann als Zeitzone wie +09: 00 verwendet werden. Es kann jedoch nicht berücksichtigt werden, dass sich der Versatzwert je nach Datum und Uhrzeit wie Sommerzeit ändert.
Mit dem "pytz" -Paket können Sie eine konkrete Klasse von "tzinfo" aus einer Zeichenfolge wie "Asia / Tokyo" generieren. Es kann davon ausgegangen werden, dass sich der Versatzwert mit UTC je nach Datum und Uhrzeit ändert.
Beispiel, bei dem sich der Versatzwert je nach Datum und Uhrzeit ändert
pytz
ist keine Standardbibliothek und muss installiert werden.
$ pip install pytz
Zeitzonenklasse
from datetime import datetime
from datetime import timedelta
from datetime import timezone
import pytz
dt = datetime.utcfromtimestamp(1572764400)
print(dt)
# => 2019-11-03 07:00:00
#1572764400 ist am 3. in Japan um 16:00 Uhr
# timezone.utc hat einen Offsetwert von 0, keine Sommerzeit
utc = timezone.utc
print(utc.utcoffset(dt))
# => 0:00:00
print(utc.dst(dt))
# => None
#Instanz der Zeitzonenklasse
tz8 = timezone(timedelta(hours=-8)) #Zeitzone, die 8 Stunden hinter UTC liegt
print(tz8.utcoffset(dt))
# => -1 day, 16:00:00
print(tz8.dst(dt))
# => None
#Die japanische Zeit hat einen Versatzwert+9 Stunden ohne Sommerzeit
tokyo = pytz.timezone('Asia/Tokyo') #Japan Zeit
print(tokyo.utcoffset(dt))
# => 9:00:00
print(tokyo.dst(dt))
# => 0:00:00
#Am 3. November um 7:00 Uhr in UTC ist der Offset-Wert in der Zeit im US-Pazifik.-8 Stunden ist keine Sommerzeit
lasvegas = pytz.timezone('America/Los_Angeles') #Amerikanische Pazifikzeit
print(lasvegas.utcoffset(dt))
# => -1 day, 16:00:00
print(lasvegas.dst(dt))
# => 0:00:00
#Am Tag zuvor war der Offset-Wert in der Zeit im US-Pazifik-7 Stunden ist Sommerzeit
print(lasvegas.utcoffset(dt - timedelta(days = 1)))
# => -1 day, 17:00:00
print(lasvegas.dst(dt - timedelta(days = 1)))
# => 1:00:00
Wenn Sie astimezone für eine naive datetime-Instanz verwenden, die keine Zeitzoneninformationen enthält, wird diese von der Zeitzone der lokalen Umgebung in die angegebene Zeitzone konvertiert. Nach der Konvertierung wird es eine Aware-Instanz.
from datetime import datetime
from datetime import timedelta
from datetime import timezone
import pytz
dt = datetime.utcfromtimestamp(1572764400)
print(dt)
# => 2019-11-03 07:00:00
#1572764400 ist am 3. in Japan um 16:00 Uhr
#dt ist eine Instanz, die von UTC am 3. um 7 Uhr erstellt wurde.
#Weil es sich um eine naive Instanz ohne Zeitzoneninformationen handelt
#Es wird am 3. Japans um 7 Uhr in die angegebene Zeitzone konvertiert.
tokyo = pytz.timezone('Asia/Tokyo') #Japan Zeit
print(dt.astimezone(tokyo))
# => 2019-11-03 07:00:00+09:00
#Da die lokale PC-Umgebung japanische Zeit ist, ändert sich die Zeit nicht
lasvegas = pytz.timezone('America/Los_Angeles') #Amerikanische Pazifikzeit
print(dt.astimezone(lasvegas))
# => 2019-11-02 15:00:00-07:00
#Am 3. November um 7 Uhr liegt die japanische Zeit im Sommer 16 Stunden hinter Japan in der Zeit des US-Pazifiks
tz8 = timezone(timedelta(hours=-8)) #Zeitzone, die 8 Stunden hinter UTC liegt
print(dt.astimezone(tz8))
# => 2019-11-02 14:00:00-08:00
Wenn Sie astimezone für eine Aware datetime-Instanz mit Zeitzoneninformationen verwenden, wird die ursprüngliche Zeitzone in die angegebene Zeitzone konvertiert. Nach der Konvertierung bleibt es weiterhin eine Aware-Instanz.
# dt.replace(tzinfo=utc)Es werden nur die Zeitzoneninformationen hinzugefügt, ohne die Werte für Jahr, Monat, Tag, Stunde, Minute und Sekunde zu ändern.
print(dt.replace(tzinfo=utc).astimezone(tokyo))
# => 2019-11-03 16:00:00+09:00
print(dt.replace(tzinfo=utc).astimezone(lasvegas))
# => 2019-11-03 00:00:00-07:00
print(dt.replace(tzinfo=utc).astimezone(tz8))
# => 2019-11-02 23:00:00-08:00
Werfen wir einen Blick auf die Umstellung von UTC auf die Zeit im amerikanischen Pazifik am Ende der Sommerzeit.
from datetime import datetime
import pytz
lasvegas = pytz.timezone('America/Los_Angeles') #Amerikanische Pazifikzeit
for i in range(7):
dt = datetime.utcfromtimestamp(1572764400 + i * 1800)
#1572764400 ist am 3. um 7 Uhr UTC
print(dt.replace(tzinfo=utc).astimezone(lasvegas))
# =>
# 2019-11-03 00:00:00-07:00
# 2019-11-03 00:30:00-07:00
# 2019-11-03 01:00:00-07:00
# 2019-11-03 01:30:00-07:00
# 2019-11-03 01:00:00-08:00 <-Die Zeit geht am Ende der Sommerzeit zurück
# 2019-11-03 01:30:00-08:00
# 2019-11-03 02:00:00-08:00
Wenn Sie "dt.replace (tzinfo = tokyo)" oder "datetime (2019, 11, 3, 1, 0, 0, tzinfo = tokyo)" in dem aus "pytz" generierten Zeitzonenobjekt verwenden, 19 Es gibt ein Problem, das verstanden werden kann. In Japan sind es 19 Minuten, in der Zeit im amerikanischen Pazifik 7 Minuten.
from datetime import datetime
from datetime import timedelta
from datetime import timezone
import pytz
dt = datetime.utcfromtimestamp(1572742800)
print(dt)
# => 2019-11-03 01:00:00
#1572764400 ist 1:00 Uhr am 3. in Japan
utc = timezone.utc
print(dt.replace(tzinfo=utc))
# => 2019-11-03 01:00:00+00:00
Wenn Sie "replace (tzinfo = utc)" auf eine naive datetime-Instanz setzen, wird diese in eine Aware-Instanz mit "+00: 00" -Informationen geändert. Wenn Sie anstelle von "utc" die japanische Zeit angeben,
tokyo = pytz.timezone('Asia/Tokyo') #Japan Zeit
print(dt.replace(tzinfo=tokyo))
# => 2019-11-03 01:00:00+09:19
Aus irgendeinem Grund ist der Zeitunterschied um 19 Minuten geringer.
Es gibt kein Problem, wenn Sie die Methode localize
verwenden. Ich bin mir nicht sicher, was anders ist.
print(tokyo.localize(dt))
# => 2019-11-03 01:00:00+09:00
Selbst wenn Sie es in der Zeit im US-Pazifik versuchen, ist die Abweichungsbreite unterschiedlich, ändert sich jedoch nicht.
lasvegas = pytz.timezone('America/Los_Angeles') #Amerikanische Pazifikzeit
print(dt.replace(tzinfo=lasvegas))
# => 2019-11-03 01:00:00-07:53
print(lasvegas.localize(dt))
# => 2019-11-03 01:00:00-08:00
Der 3. Tag der Zeit im amerikanischen Pazifik ist der Tag, an dem die Sommerzeit endet. Wie im obigen Beispiel gezeigt, fließt die Zeit wie folgt, wenn die Zeit alle 30 Minuten aufgeführt wird.
2019-11-03 00:00:00-07:00 2019-11-03 00:30:00-07:00 2019-11-03 01:00:00-07:00 2019-11-03 01:30:00-07:00 2019-11-03 01: 00: 00-08: 00 <-Time kehrt am Ende der Sommerzeit zurück 2019-11-03 01:30:00-08:00 2019-11-03 02:00:00-08:00
Es geht zweimal von 1:00 bis 1:59. Mit anderen Worten, es besteht Unklarheit, dass es nicht möglich ist, anhand der Informationen von 1 Uhr zu erkennen, ob es das erste oder das zweite Mal ist.
Versuchen Sie aufgrund dieser Tatsache "lokalisieren".
from datetime import datetime
from datetime import timedelta
from datetime import timezone
import pytz
dt = datetime.utcfromtimestamp(1572742800)
print(dt)
# => 2019-11-03 01:00:00
#dt ist eine naive Instanz um 1 Uhr am 3 ..
lasvegas = pytz.timezone('America/Los_Angeles') #Amerikanische Pazifikzeit
print(lasvegas.localize(dt))
# => 2019-11-03 01:00:00-08:00
#Die zweite 1 Uhr wurde zurückgegeben
Übrigens, wenn Sie zum zweiten Mal 1 Stunde vor 1 Uhr rechnen, ist es 0 Uhr. Es sollte Sommer um Mitternacht sein, aber es bleibt Winterzeit.
print(lasvegas.localize(dt) - timedelta(hours=1))
# => 2019-11-03 00:00:00-08:00
Wenn Sie 1 Stunde vor der naiven Instanz vor "Lokalisieren" und dann "Lokalisieren" berechnen, ist es im Sommer 0 Uhr. Dies ist 2 Stunden vor der zweiten 1 Uhr.
print(lasvegas.localize(dt - timedelta(hours=1)))
# => 2019-11-03 00:00:00-07:00
das ist alles.
Recommended Posts