Introduction
Gérer les fuseaux horaires en Python peut être délicat, mais c'est essentiel pour les applications travaillant avec des utilisateurs du monde entier. Ce tutoriel vous guidera à travers les meilleures pratiques pour travailler avec les fuseaux horaires en Python.
Ce que Vous Apprendrez
- ✅ Différence entre datetime naive et aware
- ✅ Utiliser pytz pour les fuseaux horaires
- ✅ Utiliser zoneinfo (Python 3.9+)
- ✅ Convertir entre fuseaux horaires
- ✅ Gérer l'heure d'été (DST)
- ✅ Meilleures pratiques et erreurs courantes
Prérequis
- Python 3.6 ou supérieur
- Connaissance basique de datetime
Étape 1 : Comprendre Naive vs Aware
Datetime Naive (Sans Fuseau Horaire)
PYTHON1from datetime import datetime 2 3# Naive - sans information de fuseau horaire 4dt_naive = datetime(2024, 1, 15, 12, 30, 0) 5print(dt_naive.tzinfo) # None
Datetime Aware (Avec Fuseau Horaire)
PYTHON1from datetime import datetime, timezone 2 3# Aware - inclut le fuseau horaire 4dt_aware = datetime(2024, 1, 15, 12, 30, 0, tzinfo=timezone.utc) 5print(dt_aware.tzinfo) # UTC
Règle d'or : Travaillez toujours avec des datetimes aware.
Étape 2 : Travailler avec UTC
PYTHON1from datetime import datetime, timezone 2 3# Heure actuelle en UTC 4maintenant_utc = datetime.now(timezone.utc) 5print(maintenant_utc) 6# Sortie : 2024-01-15 12:30:00+00:00 7 8# Depuis un timestamp Unix 9timestamp = 1705321800 10dt = datetime.fromtimestamp(timestamp, tz=timezone.utc) 11print(dt) 12# Sortie : 2024-01-15 12:30:00+00:00
Étape 3 : Utiliser pytz
PYTHON1import pytz 2from datetime import datetime 3 4# Créer un fuseau horaire 5paris = pytz.timezone('Europe/Paris') 6new_york = pytz.timezone('America/New_York') 7 8# Heure actuelle à Paris 9maintenant_paris = datetime.now(paris) 10print(f"Paris : {maintenant_paris}") 11 12# Convertir UTC en Paris 13utc = pytz.UTC 14maintenant_utc = datetime.now(utc) 15maintenant_paris = maintenant_utc.astimezone(paris) 16print(f"Paris depuis UTC : {maintenant_paris}")
Avertissement avec pytz
PYTHON1# ❌ INCORRECT - ne pas utiliser replace avec pytz 2dt = datetime(2024, 1, 15, 12, 0) 3dt_mal = dt.replace(tzinfo=paris) # Ne fonctionne pas correctement ! 4 5# ✅ CORRECT - utiliser localize 6dt = datetime(2024, 1, 15, 12, 0) 7dt_bien = paris.localize(dt)
Étape 4 : Utiliser zoneinfo (Python 3.9+)
PYTHON1from datetime import datetime 2from zoneinfo import ZoneInfo 3 4# Créer un fuseau horaire 5paris = ZoneInfo('Europe/Paris') 6tokyo = ZoneInfo('Asia/Tokyo') 7 8# Heure actuelle à Paris 9maintenant_paris = datetime.now(paris) 10print(maintenant_paris) 11 12# Convertir entre fuseaux 13maintenant_tokyo = maintenant_paris.astimezone(tokyo) 14print(maintenant_tokyo)
Étape 5 : Convertir Entre Fuseaux Horaires
PYTHON1from datetime import datetime 2from zoneinfo import ZoneInfo 3 4# Créer datetime dans un fuseau 5paris = ZoneInfo('Europe/Paris') 6new_york = ZoneInfo('America/New_York') 7tokyo = ZoneInfo('Asia/Tokyo') 8 9dt_paris = datetime(2024, 1, 15, 14, 30, tzinfo=paris) 10 11# Convertir vers d'autres fuseaux 12dt_ny = dt_paris.astimezone(new_york) 13dt_tokyo = dt_paris.astimezone(tokyo) 14 15print(f"Paris : {dt_paris}") 16print(f"New York : {dt_ny}") 17print(f"Tokyo : {dt_tokyo}")
Étape 6 : Gérer le DST (Heure d'Été)
PYTHON1from datetime import datetime 2from zoneinfo import ZoneInfo 3 4paris = ZoneInfo('Europe/Paris') 5 6# Hiver (CET, UTC+1) 7hiver = datetime(2024, 1, 15, 12, 0, tzinfo=paris) 8print(f"Hiver : {hiver} (décalage : {hiver.strftime('%z')})") 9# Sortie : 2024-01-15 12:00:00+01:00 10 11# Été (CEST, UTC+2) 12ete = datetime(2024, 7, 15, 12, 0, tzinfo=paris) 13print(f"Été : {ete} (décalage : {ete.strftime('%z')})") 14# Sortie : 2024-07-15 12:00:00+02:00
Étape 7 : Stocker et Récupérer des Horodatages
PYTHON1from datetime import datetime, timezone 2from zoneinfo import ZoneInfo 3 4# Toujours stocker en UTC 5def sauvegarder_evenement(dt_local, zone_utilisateur): 6 """Convertit l'heure locale en UTC pour stockage""" 7 if dt_local.tzinfo is None: 8 zone = ZoneInfo(zone_utilisateur) 9 dt_local = dt_local.replace(tzinfo=zone) 10 return dt_local.astimezone(timezone.utc) 11 12# Afficher dans la zone locale de l'utilisateur 13def afficher_evenement(dt_utc, zone_utilisateur): 14 """Convertit UTC en heure locale pour affichage""" 15 zone = ZoneInfo(zone_utilisateur) 16 return dt_utc.astimezone(zone) 17 18# Exemple 19heure_locale = datetime(2024, 1, 15, 14, 30) 20heure_utc = sauvegarder_evenement(heure_locale, 'Europe/Paris') 21print(f"Stocké : {heure_utc}") 22 23heure_afficher = afficher_evenement(heure_utc, 'America/New_York') 24print(f"Affiché à NY : {heure_afficher}")
Erreurs Courantes à Éviter
1. Utiliser datetime.now() sans fuseau
PYTHON1# ❌ Incorrect 2maintenant = datetime.now() 3 4# ✅ Correct 5maintenant = datetime.now(timezone.utc)
2. Comparer naive avec aware
PYTHON1# ❌ Cela cause TypeError 2naive = datetime(2024, 1, 15, 12, 0) 3aware = datetime(2024, 1, 15, 12, 0, tzinfo=timezone.utc) 4# naive < aware # TypeError ! 5 6# ✅ Convertir d'abord 7naive_utc = naive.replace(tzinfo=timezone.utc) 8# naive_utc < aware # Fonctionne
3. Ignorer le DST dans les calculs
PYTHON1from datetime import timedelta 2from zoneinfo import ZoneInfo 3 4# Pendant le changement DST, utiliser timedelta peut échouer 5paris = ZoneInfo('Europe/Paris') 6 7# ✅ Mieux : travailler en UTC puis convertir
Résumé
Vous avez appris comment :
- Différencier datetime naive et aware
- Utiliser pytz et zoneinfo pour les fuseaux horaires
- Convertir entre différents fuseaux horaires
- Gérer le DST correctement
- Stocker toujours en UTC et afficher en heure locale
Essayez notre Convertisseur de Fuseau Horaire pour pratiquer les conversions !