J'ai eu du mal à comprendre comment gérer les fuseaux horaires en Python, il s'agit donc d'un mémo organisé.
information sur la version
Il existe les deux types d'instances suivants dans la même classe.
Aware and Naive Objects - datetime — Basic date and time types — Python 3.8.1rc1 documentation
TZ = JST-9
from datetime import datetime
from datetime import timezone
now = datetime.now()
print(now) # =>Maintenant au Japon temps
print(now.tzinfo) # => None
# Naive
now = datetime.utcnow()
print(now) # =>Heure moins 9 heures à partir de l'heure du Japon
print(now.tzinfo) # => None
# Naive
now = datetime.now(timezone.utc)
print(now) #À l'époque moins 9 heures"+00:00"Avec la notation
print(now.tzinfo) # => UTC
# Aware
from datetime import datetime
from datetime import timezone
unixtime = 1572764400
now = datetime.fromtimestamp(unixtime)
print(now) # =>Notation en japonais de l'heure du moment représentée par l'heure unix
print(now.tzinfo) # => None
# Naive
now = datetime.utcfromtimestamp(unixtime)
print(now) #Temps moins 9 heures=Notation en UTC au moment représenté par l'heure unix
print(now.tzinfo) # => None
# Naive
now = datetime.fromtimestamp(unixtime, timezone.utc)
print(now) #À l'époque moins 9 heures"+00:00"Avec la notation
print(now.tzinfo)
# => UTC
# Aware
from datetime import datetime
from datetime import timedelta
now = datetime.now() # Naive
print(now) # =>Maintenant au Japon temps(Aucune information sur le fuseau horaire)
print(now - timedelta(hours = +9)) # =>Temps moins 9 heures(Aucune information sur le fuseau horaire)
now = datetime.utcnow() # Naive
print(now) # =>J'ai tiré 9 heures maintenant(Aucune information sur le fuseau horaire)
print(now + timedelta(hours = +9)) # =>9 heures supplémentaires de l'heure du Japon(Aucune information sur le fuseau horaire)
tzinfo
est une classe abstraite avec les informations suivantes.
--Nom de la zone horaire --Valeur de décalage horaire à partir de UTC --Valeur de décalage horaire à partir de UTC en heure d'été
tzinfo - datetime — Basic date and time types — Python 3.8.1rc1 documentation
Utilisez timezone
ou pytz
comme classe concrète. pytz
n'est pas dans la bibliothèque standard et doit être installé.
timezone
est une classe concrète de tzinfo
avec une valeur de décalage fixe. Il est fixe et peut être utilisé comme fuseau horaire tel que +09: 00, mais on ne peut pas considérer que la valeur de décalage change en fonction de la date et de l'heure, comme l'heure d'été.
Le paquet pytz
vous permet de générer une classe concrète de tzinfo
à partir d'une chaîne comme" "Asia / Tokyo" ". On peut considérer que la valeur de décalage avec UTC change en fonction de la date et de l'heure.
Exemple où la valeur de décalage change en fonction de la date et de l'heure
pytz
n'est pas une bibliothèque standard et doit être installé.
$ pip install pytz
classe de fuseau horaire
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 est 16:00 le 3ème heure du Japon
# timezone.utc a 0 valeur de décalage, pas d'heure d'été
utc = timezone.utc
print(utc.utcoffset(dt))
# => 0:00:00
print(utc.dst(dt))
# => None
#Instance de la classe de fuseau horaire
tz8 = timezone(timedelta(hours=-8)) #Fuseau horaire représentant 8 heures de retard sur UTC
print(tz8.utcoffset(dt))
# => -1 day, 16:00:00
print(tz8.dst(dt))
# => None
#L'heure du Japon a une valeur de décalage+9 heures sans heure d'été
tokyo = pytz.timezone('Asia/Tokyo') #Heure du Japon
print(tokyo.utcoffset(dt))
# => 9:00:00
print(tokyo.dst(dt))
# => 0:00:00
#À 7 h 00 le 3 novembre à UTC, la valeur de décalage correspond à l'heure du Pacifique américain.-8 heures n'est pas l'heure d'été
lasvegas = pytz.timezone('America/Los_Angeles') #Heure du Pacifique américain
print(lasvegas.utcoffset(dt))
# => -1 day, 16:00:00
print(lasvegas.dst(dt))
# => 0:00:00
#La veille, la valeur de décalage était en heure du Pacifique américain-7 heures est l'heure d'été
print(lasvegas.utcoffset(dt - timedelta(days = 1)))
# => -1 day, 17:00:00
print(lasvegas.dst(dt - timedelta(days = 1)))
# => 1:00:00
Si vous utilisez le fuseau horaire pour une instance datetime Naive sans informations de fuseau horaire, il sera converti du fuseau horaire de l'environnement local au fuseau horaire spécifié. Après la conversion, il devient une instance Aware.
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 est 16:00 le 3ème heure du Japon
#dt est une instance créée par UTC à 7 heures le 3,
#Parce qu'il s'agit d'une instance Naive sans informations de fuseau horaire
#Il sera converti au fuseau horaire spécifié à 7 heures le 3ème heure du Japon.
tokyo = pytz.timezone('Asia/Tokyo') #Heure du Japon
print(dt.astimezone(tokyo))
# => 2019-11-03 07:00:00+09:00
#Étant donné que l'environnement PC local est l'heure du Japon, l'heure ne change pas
lasvegas = pytz.timezone('America/Los_Angeles') #Heure du Pacifique américain
print(dt.astimezone(lasvegas))
# => 2019-11-02 15:00:00-07:00
#7h00 le 3 novembre, l'heure du Japon a 16 heures de retard sur le Japon en heure d'été par rapport à l'heure du Pacifique des États-Unis
tz8 = timezone(timedelta(hours=-8)) #Fuseau horaire représentant 8 heures de retard sur UTC
print(dt.astimezone(tz8))
# => 2019-11-02 14:00:00-08:00
Si vous utilisez le fuseau horaire pour une instance datetime Aware avec des informations de fuseau horaire, le fuseau horaire d'origine sera converti dans le fuseau horaire spécifié. Il restera une instance Aware après la conversion.
# dt.replace(tzinfo=utc)Seules les informations de fuseau horaire sont ajoutées sans modifier les valeurs de l'année, du mois, du jour, de l'heure, des minutes et des secondes.
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
Jetons un coup d'œil à la conversion de l'heure UTC à l'heure du Pacifique américain à la fin de l'heure d'été.
from datetime import datetime
import pytz
lasvegas = pytz.timezone('America/Los_Angeles') #Heure du Pacifique américain
for i in range(7):
dt = datetime.utcfromtimestamp(1572764400 + i * 1800)
#1572764400 est UTC à 7 heures le 3
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 <-Le temps remonte à la fin de l'heure d'été
# 2019-11-03 01:30:00-08:00
# 2019-11-03 02:00:00-08:00
Si vous utilisez dt.replace (tzinfo = tokyo)
ou datetime (2019, 11, 3, 1, 0, 0, tzinfo = tokyo)
dans l'objet de fuseau horaire généré à partir de pytz
, 19 Il y a un problème qui peut être compris. Il est de 19 minutes au Japon, mais 7 minutes en Amérique Pacifique.
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 est 1:00 le 3ème heure du Japon
utc = timezone.utc
print(dt.replace(tzinfo=utc))
# => 2019-11-03 01:00:00+00:00
Si vous définissez replace (tzinfo = utc)
sur une instance de datetime Naive, elle deviendra une instance Aware avec les informations +00: 00
. Si vous spécifiez l'heure japonaise au lieu de ʻutc`,
tokyo = pytz.timezone('Asia/Tokyo') #Heure du Japon
print(dt.replace(tzinfo=tokyo))
# => 2019-11-03 01:00:00+09:19
Pour une raison quelconque, le décalage horaire est décalé de 19 minutes.
Il n'y a pas de problème si vous utilisez la méthode localize
. Je ne sais pas ce qui est différent.
print(tokyo.localize(dt))
# => 2019-11-03 01:00:00+09:00
Même si vous l'essayez à l'heure du Pacifique américain, la largeur de l'écart est différente, mais elle ne change pas.
lasvegas = pytz.timezone('America/Los_Angeles') #Heure du Pacifique américain
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
Le troisième jour de l'heure du Pacifique américain est le jour de la fin de l'heure d'été et, comme illustré dans l'exemple ci-dessus, lorsque l'heure est indiquée toutes les 30 minutes, l'heure s'écoule comme suit.
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 <-L'heure revient à la fin de l'heure d'été 2019-11-03 01:30:00-08:00 2019-11-03 02:00:00-08:00
Il tourne deux fois de 1 h à 1 h 59. En d'autres termes, il existe une ambiguïté selon laquelle il n'est pas possible de dire si c'est la première ou la deuxième fois à partir de l'information de 1 heure.
Sur la base de ce fait, essayez localiser
.
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 est une instance naïve à 1 heure le 3
lasvegas = pytz.timezone('America/Los_Angeles') #Heure du Pacifique américain
print(lasvegas.localize(dt))
# => 2019-11-03 01:00:00-08:00
#La seconde 1 heure est revenue
À propos, si vous calculez 1 heure avant 1 heure pour la deuxième fois, ce sera 0 heure. Ce devrait être l'heure d'été à minuit, mais cela reste l'heure d'hiver.
print(lasvegas.localize(dt) - timedelta(hours=1))
# => 2019-11-03 00:00:00-08:00
Si vous calculez il y a 1 heure pour l'instance Naive avant localize
puis localize
, il sera 0 heures en heure d'été. C'est 2 heures avant la seconde 1 heure.
print(lasvegas.localize(dt - timedelta(hours=1)))
# => 2019-11-03 00:00:00-07:00
c'est tout.
Recommended Posts