Les dates et les timezone

La librairie standard ne définit pas de timezone. Elle fournit une classe timezone, spécialisation simple de tzinfo qui s'instancie en passant en paramètre un timedelta. Celui-ci doit avoir +/- 24 heures.


In [ ]:
import datetime as dt

print("Maintenant naif  :", dt.datetime.now())

instant = dt.datetime.now(dt.timezone(dt.timedelta(hours=2)))

print("Maintenant aware :", instant)
print("Info timezone    :", instant.tzinfo)

In [ ]:
instant = dt.datetime.now(dt.timezone(dt.timedelta(hours=2), name="plus_2"))
print("Maintenant aware :", instant)
print("Info timezone    :", instant.tzinfo)

In [ ]:
instant = dt.datetime.now(dt.timezone(dt.timedelta(hours=2), name="plus_2"))
autre_instant = dt.datetime.now(dt.timezone(dt.timedelta(hours=1), name="plus_1"))
print("Maintenant aware 2 :", instant)
print("Maintenant aware 1 :", autre_instant)

In [ ]:
autre_instant - instant

Avec la librairie pytz

Dans la cellule suivante, nous définissons un timezone pour la France


In [ ]:
import pytz
paris_tz = pytz.timezone('Europe/Paris')
print(paris_tz)
paris_tz

Quelles sont les valeurs possibles pour les timezone ? Une constante existe.


In [ ]:
pytz.all_timezones

Nous créons d'abord une date naive à laquelle nous renseignons le timezone.


In [ ]:
h_france_naive = dt.datetime.now()
print("France, naive :", h_france_naive)

h_paris_aware = paris_tz.localize(h_france_naive)
print("France, aware :", h_paris_aware)

Nous renouvelons les instructions pour une date proche en Angleterre.


In [ ]:
london_tz = pytz.timezone('Europe/London')

h_uk_naive = dt.datetime.now()
print("UK, naive :", h_uk_naive)

h_london_aware = london_tz.localize(h_uk_naive)
print("UK, aware :", h_london_aware)

Nous changeons le timezone de cette date aware d'Angleterre en France.


In [ ]:
h_paris_from_london = h_london_aware.astimezone(paris_tz)
print("France from UK :", h_paris_from_london)

Cette nouvelle date n'affiche pas les même heures, mais n'a pas non plus le même timezone. Nous pouvons vérifier qu'il s'agit de la même date.


In [ ]:
h_london_aware == h_paris_from_london

Les deux dates localisées contiennent la même information d'heure. Nous vérifions qu'il ne s'agit pas du même instant et qu'il y a un décalage d'une heure.


In [ ]:
print("Heure UK   :", h_london_aware.hour)
print("Heure Fr   :", h_paris_aware.hour)
print("Différence :", h_london_aware - h_paris_aware)

Prise en compte du changement d'heure

Les problèmes de timezone ne se limitent pas au fuseau horaire mais également à la différence en fonction du changement d'heure. Ci dessous, nous définissons deux instants à minuit pour un jour en heure d'hiver et un jour en heure d'été.


In [ ]:
winter_day = paris_tz.localize(dt.datetime(2019, 3, 30))
#pre_ete = dt.datetime(2019, 3, 30, tzinfo=paris_tz)
summer_day = paris_tz.localize(dt.datetime(2019, 4, 2))
print("Hiver :", winter_day)
print("Été.  :", summer_day)

In [ ]:
print("Différence :", summer_day - winter_day)

In [ ]:
after_3_days = winter_day + dt.timedelta(days=3)
print("3 jours plus tard :", after_3_days)

In [ ]:
print("3 jours plus tard relocalisé :", after_3_days.astimezone(paris_tz))

Voir donc les bonnes pratiques pour manipuler les dates.