Maîtriser le temps avec la bibliothèque standard Python : le module datetime en détail
Série 03 – Opérations sur les dates/horaires, fuseaux horaires, conversion de format en un seul passage
Le temps n’est pas qu’une simple chaîne de caractères. Les jours passent, les mois changent, l’heure d’été intervient, et chaque région a ses propres règles. Il est donc crucial de distinguer la représentation textuelle d’une valeur temporelle calculable et d’inclure les fuseaux horaires dans vos traitements.

Dans cet article, nous allons explorer le module datetime et aborder les points suivants.
- Créer la date et l’heure actuelles
- Calculer des durées (
timedelta) - Formater et analyser des chaînes (
strftime,strptime) - Gérer les fuseaux horaires (
timezone,zoneinfo) - Points d’attention fréquents et modèles fiables
1. Que propose datetime ?
Le module datetime regroupe plusieurs types qui semblent similaires mais ont des rôles distincts.
date: uniquement année‑mois‑jourtime: uniquement heure‑minute‑secondedatetime: date + heure (le plus utilisé)timedelta: différence de temps (durée)timezone: fuseau horaire à décalage fixe (ex : UTC+9)
Depuis Python 3.9, la bibliothèque standard inclut zoneinfo, qui simplifie la manipulation des fuseaux horaires régionaux (ex : Asia/Tokyo).
2. Obtenir « maintenant » : naive vs aware
2.1 Naïf / conscient
Les objets datetime se divisent en deux catégories.
- Naïf : sans information de fuseau
- Conscient : avec
tzinfo
Mélanger les deux lors d’opérations ou de comparaisons peut provoquer des erreurs ou des résultats inattendus.
2.2 Valeur par défaut recommandée : commencer en UTC conscient
Uniformiser la base de calcul sur UTC rend souvent les choses plus propres.
from datetime import datetime, timezone
utc_now = datetime.now(timezone.utc) # conscient (UTC)
print(utc_now)
Si vous avez besoin de l’heure locale, effectuez la conversion lors de l’affichage.
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
utc_now = datetime.now(timezone.utc)
tokyo_now = utc_now.astimezone(ZoneInfo("Asia/Tokyo"))
print(utc_now)
print(tokyo_now)
3. Calculs temporels : le rôle central de timedelta
3.1 Addition / soustraction
from datetime import datetime, timedelta, timezone
now = datetime.now(timezone.utc)
print(now + timedelta(days=3))
print(now - timedelta(hours=2))
3.2 Différence entre deux instants
from datetime import datetime, timezone
a = datetime(2026, 1, 1, tzinfo=timezone.utc)
b = datetime(2026, 1, 10, tzinfo=timezone.utc)
delta = b - a
print(delta.days) # 9
print(delta.total_seconds()) # 777600.0
3.3 Sens de timedelta pour exprimer une « durée »
timedelta fonctionne en jours, secondes et microsecondes. Une expression comme « un mois plus tard » ne peut pas être modélisée directement ; on peut approximativement utiliser timedelta(days=30), mais pour des calculs précis on recourt souvent à des bibliothèques tierces comme dateutil.
4. Formatage et analyse : strftime / strptime
4.1 datetime → chaîne (strftime)
from datetime import datetime, timezone
dt = datetime(2026, 1, 30, 14, 5, 0, tzinfo=timezone.utc)
print(dt.strftime("%Y-%m-%d %H:%M:%S %z"))
Modèles courants :
%Y-%m-%d: 2026-01-30%H:%M:%S: 14:05:00%z: +0000 (décalage UTC)
4.2 Chaîne → datetime (strptime)
from datetime import datetime
s = "2026-01-30 14:05:00"
dt = datetime.strptime(s, "%Y-%m-%d %H:%M:%S")
print(dt)
Le dt obtenu est naïf. Pour préciser le fuseau, ajoutez tzinfo.
from datetime import datetime, timezone
s = "2026-01-30 14:05:00"
dt = datetime.strptime(s, "%Y-%m-%d %H:%M:%S").replace(tzinfo=timezone.utc)
print(dt)
replace(tzinfo=…)ne convertit pas l’heure, il ajoute simplement une étiquette de fuseau. Pour convertir, utilisezastimezone()(voir section suivante).
5. Fuseaux horaires : distinguer timezone et zoneinfo
5.1 Décalage fixe : timezone
Exemple : UTC ou UTC+9.
from datetime import datetime, timezone, timedelta
kst_fixed = timezone(timedelta(hours=9))
dt = datetime(2026, 1, 30, 12, 0, tzinfo=kst_fixed)
print(dt)
5.2 Fuseau régional : zoneinfo
Les fuseaux qui changent (heure d’été) sont mieux gérés par zoneinfo.
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
utc_now = datetime.now(timezone.utc)
ny_now = utc_now.astimezone(ZoneInfo("America/New_York"))
print(ny_now)
5.3 Différence entre replace(tzinfo=…) et astimezone(...)
replace(tzinfo=…): conserve la valeur temporelle, change seulement l’étiquette de fuseau.astimezone(...): convertit la même instant dans un autre fuseau.
Connaître cette distinction réduit les bugs liés aux fuseaux.
6. Points d’attention fréquents
6.1 Mélange naïf/conscient
- Utilisez des instants conscients (UTC) pour les calculs internes.
- Normalisez les entrées externes dès leur arrivée.
6.2 « Heure locale » dépend du contexte
datetime.now() suit la configuration locale de l’environnement d’exécution. Dans des conteneurs ou serveurs, la locale peut être UTC ou autre. Privilégiez datetime.now(timezone.utc) pour éviter les surprises.
6.3 Incohérence de format lors de l’analyse
strptime échoue si le format ne correspond pas exactement. Si vous avez plusieurs formats possibles, pré-traitez ou essayez les formats séquentiellement. Limiter le format d’entrée est souvent la meilleure solution.
7. Trois modèles courants
7.1 Enregistrer en ISO 8601
from datetime import datetime, timezone
dt = datetime.now(timezone.utc)
print(dt.isoformat()) # ex : 2026-01-30T05:12:34.567890+00:00
7.2 Nom de fichier avec la date d’aujourd’hui
from datetime import datetime
stamp = datetime.now().strftime("%Y%m%d")
filename = f"report_{stamp}.json"
print(filename)
7.3 Temps restant jusqu’à une date cible
from datetime import datetime, timezone
target = datetime(2026, 2, 1, 0, 0, tzinfo=timezone.utc)
now = datetime.now(timezone.utc)
remaining = target - now
print(remaining)
print(remaining.total_seconds())
8. Conclusion
datetime dépasse la simple création de chaînes : il permet de manipuler le temps comme une valeur calculable. En y ajoutant les fuseaux horaires (timezone, zoneinfo), vous obtenez un code robuste, indépendant de l’environnement d’exécution.
Dans la prochaine partie, nous aborderons le module random séparément, couvrant génération de nombres aléatoires, échantillonnage, mélange, graines et la génération sécurisée (secrets).
Articles connexes :
- Utiliser correctement datetime et timezone dans Django
- Gestion du temps dans Django – guide complet de
django.utils.timezone
Voir la série précédente