# 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. ![Un atelier de travail magique pour un horloger](/media/editor_temp/6/5843a4cb-f3a6-4d8d-9a13-89c1cbb0ef6c.png) 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` ? {#sec-5f3cbdfb3d40} Le module `datetime` regroupe plusieurs types qui semblent similaires mais ont des rôles distincts. * `date` : uniquement année‑mois‑jour * `time` : uniquement heure‑minute‑seconde * `datetime` : 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 {#sec-80466bd4f739} ### 2.1 Naïf / conscient {#sec-893b0793d467} 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 {#sec-f876fdec8f2b} Uniformiser la base de calcul sur UTC rend souvent les choses plus propres. ```python 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. ```python 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` {#sec-5497d843fd3e} ### 3.1 Addition / soustraction {#sec-0288780aa297} ```python 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 {#sec-c781f333910b} ```python 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 » {#sec-c81173d2a4f5} `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` {#sec-a17a8e259a48} ### 4.1 `datetime` → chaîne (`strftime`) {#sec-8d6f34025b2e} ```python 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`) {#sec-f2bbc1672485} ```python 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`. ```python 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, utilisez `astimezone()` (voir section suivante). --- ## 5. Fuseaux horaires : distinguer `timezone` et `zoneinfo` {#sec-05b1d0f7ef82} ### 5.1 Décalage fixe : `timezone` {#sec-67fec65074ab} Exemple : UTC ou UTC+9. ```python 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` {#sec-834b663bce83} Les fuseaux qui changent (heure d’été) sont mieux gérés par `zoneinfo`. ```python 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(...)` {#sec-35bf0fbaa9df} * `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 {#sec-552ca3933648} ### 6.1 Mélange naïf/conscient {#sec-21a4c96b9022} * 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 {#sec-e2bd08b413c3} `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 {#sec-e52b753858ac} `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 {#sec-b244af674a6a} ### 7.1 Enregistrer en ISO 8601 {#sec-4b1979b29466} ```python 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 {#sec-ae13a5dac423} ```python 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 {#sec-b509d1188ff7} ```python 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 {#sec-9fa53305f95a} `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](/ko/whitedec/2025/11/10/django-datetime-timezone/) - [Gestion du temps dans Django – guide complet de `django.utils.timezone`](/ko/whitedec/2025/11/14/django-utils-timezone-guide/) --- **Voir la série précédente** - [[Python Standard Library – 0] Qu’est-ce que la bibliothèque standard Python ? Guide pour débutants](/ko/whitedec/2026/1/29/python-standard-library/) - [[Python Standard Library –1] Système de fichiers & environnement OS : pathlib vs os](/ko/whitedec/2026/1/29/file-system-os-environment-master-pathlib-vs-os/) - [[Python Standard Library – 2] Stockage & sérialisation : json, pickle, csv](/ko/whitedec/2026/1/30/python-json-pickle-csv/)