Comment parser efficacement les dates et heures en Python ?

Parser les dates et heures en Python peut vite devenir un cauchemar avec des formats variés et imprévisibles. Voici cinq fonctions DIY précises et pratiques pour dompter ces données, sans dépendre de bibliothèques lourdes ni perdre de temps.

3 principaux points à retenir.

  • Flexibilité : gérer formats relatifs, naturels, flexibles et ISO.
  • Pragmatisme : solutions simples, robustes, sans lourdes dépendances.
  • Utilité : adaptées aux données réelles issues du web, utilisateurs, systèmes legacy.

Comment convertir les temps relatifs en dates concrètes ?

Les temps relatifs comme « 5 minutes ago » sont omniprésents, surtout dans les données sociales, les journaux d’activité et les systèmes de logs. Ces expressions peuvent rapidement devenir un casse-tête si vous devez les manipuler dans votre code. La solution ? Les convertir en objets datetime pour pouvoir les utiliser efficacement. C’est là qu’intervient la fonction parse_relative_time.

Cette fonction utilise une expression régulière (regex) pour extraire le nombre et l’unité de temps à partir d’une chaîne de caractères. Voici le fonctionnement : on commence par normaliser la chaîne en la mettant en minuscules et en supprimant les espaces superflus. Ensuite, on définit un motif regex qui correspond à un nombre suivi d’une unité de temps (comme « minute », « heure », etc.) et du mot « ago ». Par exemple, le motif r'(\d+)\s*(second|minute|hour|day|week)s?\s*ago' va capturer des entrées comme « 5 minutes ago » ou « 2 hours ago ».

Une fois que nous avons extrait le nombre et l’unité, la fonction utilise timedelta pour calculer la date correspondante. Pour les unités directement supportées (secondes, minutes, heures, jours et semaines), on crée un objet timedelta et on le soustrait de la référence temporelle, généralement la date actuelle. Pour les mois et les années, on fait une approximation : un mois équivaut à 30 jours et une année à 365 jours. Bien que cela ne soit pas parfait, cela fonctionne pour la plupart des cas pratiques.

Un autre aspect intéressant est le paramètre reference_time, qui vous permet de spécifier une autre date « maintenant », ce qui est utile pour tester ou traiter des données historiques. Voici quelques exemples d’utilisation :

result1 = parse_relative_time("2 hours ago")
result2 = parse_relative_time("3 days ago")
result3 = parse_relative_time("1 week ago")

print(f"2 hours ago: {result1}")
print(f"3 days ago: {result2}")
print(f"1 week ago: {result3}") 

Les résultats de ces appels vous donneront des objets datetime précis, prêts à être utilisés dans vos calculs ou analyses. En gros, cette fonction est une petite pépite pour gérer ces formats de temps relatifs qui peuvent autrement vous faire perdre un temps fou.

Pour approfondir le sujet des conversions entre chaînes et objets datetime, vous pouvez consulter cet article sur DataCamp.

Comment extraire des dates dans des textes en langage naturel ?

Souvent, dans le monde du développement, les dates sont noyées dans des textes plus ou moins complexes, et vous n’avez qu’une envie : extraire la date sans avoir à tout parser. C’est là qu’intervient la fonction extract_date_from_text, un outil pratique qui se charge de cette tâche avec élégance.

Cette fonction utilise un dictionnaire des mois pour convertir des formats variés comme « January 15th, 2026 » ou « March 3rd » en objets datetime. Mais comment ça marche exactement ?

À la base, la fonction s’appuie sur des expressions régulières (regex) pour détecter les dates dans le texte. Elle peut reconnaître des formats avec des suffixes ordinals tels que st, nd, rd, ou th, ce qui est essentiel pour des dates comme « 1st », « 2nd » ou « 3rd ». Ces suffixes, bien qu’optionnels, ajoutent une touche de précision à la détection des dates.

Un autre aspect intéressant est la gestion de l’année. Si l’année n’est pas spécifiée dans le texte, la fonction remplace celle-ci par l’année en cours. C’est logique : si quelqu’un mentionne « March 3rd » en janvier, il est probable qu’il parle de mars de cette année, pas de l’année précédente.

Voici quelques exemples pour illustrer son fonctionnement :

text1 = "La réunion est prévue pour January 15th, 2026"
text2 = "Merci de répondre d'ici March 3rd"
text3 = "Deadline : Dec 25th, 2026"

date1 = extract_date_from_text(text1)
date2 = extract_date_from_text(text2)
date3 = extract_date_from_text(text3)

print(date1)  # 2026-01-15 00:00:00
print(date2)  # 2026-03-03 00:00:00
print(date3)  # 2026-12-25 00:00:00

Les résultats sont limpides : la fonction extrait les dates avec une précision remarquable, tout en étant robuste face à différentes formulations. Pour en savoir plus sur la conversion de chaînes en objets datetime, vous pouvez consulter cet article sur DataCamp.

En somme, cette méthode est simple mais efficace, un vrai must-have pour quiconque doit manipuler des dates dans du texte naturel.

Comment gérer les formats de date multiples avec un seul parseur ?

Dans la vraie vie, les dates ne se présentent jamais sous un format unique et bien rangé. Entre les formats ISO, européens, américains, et même ceux en texte libre, il est inefficace d’écrire un parseur pour chaque variante. C’est là qu’intervient la fonction parse_flexible_date, une solution élégante pour gérer cette complexité.

Cette fonction teste une liste ordonnée de formats standards, lui permettant de s’adapter à presque toutes les situations. Elle commence par tenter de parser la date en utilisant strptime, qui est une méthode puissante pour convertir des chaînes de caractères en objets datetime. Si un format échoue, la fonction l’ignore simplement et passe au suivant, ce qui rend le processus à la fois simple et efficace.

from datetime import datetime

def parse_flexible_date(date_string):
    date_string = date_string.strip()
    formats = [
        '%Y-%m-%d',           
        '%Y/%m/%d',           
        '%d-%m-%Y',           
        '%d/%m/%Y',         
        '%m/%d/%Y',           
        '%d.%m.%Y',          
        '%Y%m%d',            
        '%B %d, %Y',      
        '%b %d, %Y',         
        '%d %B %Y',          
        '%d %b %Y',           
    ]
    
    for fmt in formats:
        try:
            return datetime.strptime(date_string, fmt)
        except ValueError:
            continue
    
    raise ValueError(f"Unable to parse date: {date_string}")

Voici un tableau synthétique des formats testés et des exemples de parsing réussis :

Format Exemple Date Parsée
%Y-%m-%d 2026-01-15 2026-01-15 00:00:00
%d/%m/%Y 15/01/2026 2026-01-15 00:00:00
%B %d, %Y January 15, 2026 2026-01-15 00:00:00
%d %b %Y 15 Jan 2026 2026-01-15 00:00:00

Cette méthode n’est pas seulement simple, elle est aussi adaptable. Si vous découvrez de nouveaux formats à traiter, il vous suffit d’ajouter les nouveaux modèles à la liste. Vous pouvez ainsi gérer la complexité des dates multiples sans vous perdre dans des parseurs spécifiques. Pour ceux qui cherchent des solutions similaires, vous pouvez consulter cet article sur Stack Overflow qui aborde des défis similaires.

Comment convertir des durées variées en objets timedelta ?


Dans de nombreux contextes, qu'il s'agisse de vidéos, de sports ou de suivi d'activités, vous serez souvent confronté à des durées sous des formats variés comme « 1h 30m 45s » ou « 2:45:30 ». Manipuler ces durées peut rapidement devenir un casse-tête, surtout si vous devez les convertir en objets timedelta pour des calculs ultérieurs. C'est là que la fonction parse_duration entre en jeu.

Cette fonction gère efficacement deux formats principaux : le format colon (H:M:S) et le format basé sur des unités, comme « 90 minutes » ou « 1.5 hours ». Grâce à l'utilisation de regex, elle permet d'extraire les heures, les minutes et les secondes, y compris les valeurs décimales.

Voici comment la fonction est structurée :

from datetime import timedelta
import re

def parse_duration(duration_string):
    """
    Parse duration strings into timedelta objects.
    
    Handles formats like:
    - "1h 30m 45s"
    - "2:45:30" (H:M:S)
    - "90 minutes"
    - "1.5 hours"
    """
    duration_string = duration_string.strip().lower()
    
    # Try colon format first (H:M:S or M:S)
    if ':' in duration_string:
        parts = duration_string.split(':')
        if len(parts) == 2:
            # M:S format
            minutes, seconds = map(int, parts)
            return timedelta(minutes=minutes, seconds=seconds)
        elif len(parts) == 3:
            # H:M:S format
            hours, minutes, seconds = map(int, parts)
            return timedelta(hours=hours, minutes=minutes, seconds=seconds)
    
    # Try unit-based format (1h 30m 45s)
    total_seconds = 0
    
    # Find hours
    hours_match = re.search(r'(\d+(?:\.\d+)?)\s*h(?:ours?)?', duration_string)
    if hours_match:
        total_seconds += float(hours_match.group(1)) * 3600
    
    # Find minutes
    minutes_match = re.search(r'(\d+(?:\.\d+)?)\s*m(?:in(?:ute)?s?)?', duration_string)
    if minutes_match:
        total_seconds += float(minutes_match.group(1)) * 60
    
    # Find seconds
    seconds_match = re.search(r'(\d+(?:\.\d+)?)\s*s(?:ec(?:ond)?s?)?', duration_string)
    if seconds_match:
        total_seconds += float(seconds_match.group(1))
    
    if total_seconds > 0:
        return timedelta(seconds=total_seconds)
    
    raise ValueError(f"Unable to parse duration: {duration_string}")

Voyons quelques exemples d'entrée et leurs sorties correspondantes :

durations = [
    "1h 30m 45s",
    "2:45:30",
    "90 minutes",
    "1.5 hours",
    "45s",
    "2h 15m"
]

for duration in durations:
    parsed = parse_duration(duration)
    print(f"{duration:15} -> {parsed}")

Le résultat de ces exemples sera :

1h 30m 45s      -> 1:30:45
2:45:30         -> 2:45:30
90 minutes      -> 1:30:00
1.5 hours       -> 1:30:00
45s             -> 0:00:45
2h 15m          -> 2:15:00

Avec cette fonction, vous avez une souplesse et une précision considérables pour gérer les durées dans vos projets Python. Pour approfondir vos connaissances sur la gestion des dates et heures, je vous recommande de consulter cet article ici.

Comment interpréter les dates au format semaine ISO en Python ?

Dans le monde des affaires, il est courant d’utiliser des dates au format ISO semaine, comme « 2026-W03-2 ». Ce format peut sembler déroutant au premier abord, mais il a ses propres avantages, notamment en matière de planification hebdomadaire. Chaque date ISO semaine représente une combinaison de l’année, du numéro de la semaine et du jour de la semaine. Par exemple, « 2026-W03-2 » indique le deuxième jour (mardi) de la troisième semaine de l’année 2026.

Pour manipuler ce format en Python, nous allons utiliser une fonction dédiée, parse_iso_week_date. Cette fonction décompose la chaîne de caractères, vérifie que les valeurs fournies sont dans les limites acceptables, puis calcule la date réelle. L’astuce consiste à se baser sur le lundi de la première semaine de l’année, qui est toujours la semaine contenant le premier jeudi de l’année. Pour cela, nous commençons par trouver le 4 janvier de l’année concernée. Ensuite, nous déterminons quel jour de la semaine cela correspond, puis nous calculons la date cible en ajoutant le nombre de semaines et de jours spécifiés.

from datetime import datetime, timedelta

def parse_iso_week_date(iso_week_string):
    """
    Parse ISO week date format: YYYY-Www-D
    """
    parts = iso_week_string.split('-')
    
    if len(parts) != 3 or not parts[1].startswith('W'):
        raise ValueError(f"Invalid ISO week format: {iso_week_string}")
    
    year = int(parts[0])
    week = int(parts[1][1:])  # Remove 'W' prefix
    day = int(parts[2])
    
    if not (1 <= week <= 53):
        raise ValueError(f"Week must be between 1 and 53: {week}")
    
    if not (1 <= day <= 7):
        raise ValueError(f"Day must be between 1 and 7: {day}")
    
    # Find January 4th (always in week 1)
    jan_4 = datetime(year, 1, 4)
    
    # Find Monday of week 1
    week_1_monday = jan_4 - timedelta(days=jan_4.weekday())
    
    # Calculate the target date
    target_date = week_1_monday + timedelta(weeks=week - 1, days=day - 1)
    
    return target_date

Voyons quelques exemples concrets pour mieux comprendre :

# Test ISO week dates
iso_dates = [
    "2024-W01-1",  # Week 1, Monday
    "2024-W03-2",  # Week 3, Tuesday
    "2024-W10-5",  # Week 10, Friday
]

for iso_date in iso_dates:
    parsed = parse_iso_week_date(iso_date)
    print(f"{iso_date} -> {parsed.strftime('%Y-%m-%d (%A)')}")

Les sorties de ce code seront :

  • 2024-W01-1 -> 2024-01-01 (Monday)
  • 2024-W03-2 -> 2024-01-16 (Tuesday)
  • 2024-W10-5 -> 2024-03-08 (Friday)

Ce format, bien que moins courant, est essentiel pour les projets qui doivent gérer des données hebdomadaires. Il permet une gestion plus précise des périodes de planification et garantit que les équipes respectent les délais. Pour plus de détails sur la manipulation des dates en Python, vous pouvez consulter la documentation officielle ici.

Prêt à maîtriser toutes vos dates et heures en Python sans prise de tête ?

Ces cinq fonctions Python DIY vous donnent les clés pour gérer les formats de dates et heures les plus courants et les plus tordus. En combinant regex, datetime et un soupçon d’astuce, vous évitez les pièges des formats ambigus et des données réelles sales. Fini les bugs chronophages et les dépendances inutiles : vous contrôlez votre parsing, gagnez en robustesse et en clarté. Pour vous, c’est un vrai gain de temps et une base solide pour vos projets data et automation.

FAQ

Comment gérer les formats de dates ambigus en Python ?

Utilisez un parseur flexible qui teste plusieurs formats courants avec datetime.strptime. Priorisez les formats selon votre contexte et traitez les erreurs pour passer au format suivant.

Pourquoi approximons-nous les mois et années dans le parsing relatif ?

Parce que timedelta ne supporte pas directement mois et années, on utilise des approximations (30 jours pour un mois, 365 pour une année) qui suffisent pour la plupart des usages non critiques.

Peut-on gérer les fuseaux horaires avec ces fonctions ?

Ces fonctions de base ne gèrent pas explicitement les fuseaux horaires. Pour cela, il faut utiliser des bibliothèques spécialisées comme pytz ou zoneinfo en complément.

Comment traiter les durées avec des formats non standards ?

Adaptez les expressions régulières pour capter vos formats spécifiques, en vous inspirant des exemples de parse_duration. Vous pouvez aussi combiner plusieurs méthodes pour plus de robustesse.

À quoi sert le parsing ISO semaine en entreprise ?

Le format ISO semaine est utilisé pour la planification hebdomadaire, les rapports et la gestion des projets. Le parsing facilite l’intégration de ces données dans les systèmes calendaires classiques.

 

 

A propos de l'auteur

Consultant et formateur expert en Analytics, Data, Automatisation et IA, je mets à profit mes années d’expérience pour simplifier les sujets complexes comme le parsing de dates en Python. Responsable de l’agence webAnalyste et de Formations Analytics, je développe et partage des solutions concrètes pour intégrer efficacement la data science et l’IA dans vos workflows métier. Basé à Brive‑la‑Gaillarde, j’accompagne les professionnels en France, Suisse et Belgique à maîtriser leurs données et automatisations.

Retour en haut
MetricsMag