Home » Data Marketing » Comment parser efficacement les dates et heures en Python ?

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 des données imprévisibles. Voici cinq fonctions DIY qui simplifient ce travail, basées sur des techniques éprouvées et adaptables à vos projets.

3 principaux points à retenir.

  • Maîtrise des formats variés grâce à une approche flexible et regex.
  • Conversion intelligente des durées et dates relatives en objets datetime.
  • Adaptabilité aux données réelles sans dépendances lourdes.

Comment convertir des dates relatives en objets datetime ?

Les dates relatives comme « 5 minutes ago » sont omniprésentes dans les flux sociaux, et pour les exploiter efficacement, il est crucial de les convertir en dates absolues. Cela permet non seulement de mieux gérer les données, mais aussi d’effectuer des analyses temporelles pertinentes. Dans ce contexte, une fonction Python bien conçue peut s’avérer être un atout précieux.

Voici une fonction qui transforme ces chaînes de temps relatives en objets datetime. Elle utilise des expressions régulières pour extraire le nombre et l’unité de temps, puis applique un timedelta pour obtenir la date exacte.

from datetime import datetime, timedelta
import re

def parse_relative_time(time_string, reference_time=None):
    """
    Convertit les chaînes de temps relatives en objets datetime.
    
    Exemples : "2 hours ago", "3 days ago", "1 week ago"
    """
    if reference_time is None:
        reference_time = datetime.now()
    
    time_string = time_string.lower().strip()
    
    # Modèle : nombre + unité de temps + "ago"
    pattern = r'(\d+)\s*(second|minute|hour|day|week|month|year)s?\s*ago'
    match = re.match(pattern, time_string)
    
    if not match:
        raise ValueError(f"Impossible de parser : {time_string}")
    
    amount = int(match.group(1))
    unit = match.group(2)
    
    unit_mapping = {
        'second': 'seconds',
        'minute': 'minutes',
        'hour': 'hours',
        'day': 'days',
        'week': 'weeks',
    }
    
    if unit in unit_mapping:
        delta_kwargs = {unit_mapping[unit]: amount}
        return reference_time - timedelta(**delta_kwargs)
    elif unit == 'month':
        return reference_time - timedelta(days=amount * 30)
    elif unit == 'year':
        return reference_time - timedelta(days=amount * 365)

Pour tester cette fonction, voici quelques exemples :

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 tests vous donneront des dates précises, par exemple : « 2 hours ago » pourrait correspondre à une date de 2026-01-06, selon le moment où vous exécutez le code. Notez que pour les mois et les années, nous avons fait des approximations, en considérant respectivement 30 et 365 jours.

Le paramètre reference_time vous permet d’adapter la fonction à différents contextes, comme le traitement de données historiques. Cela vous offre une flexibilité appréciable lors de l’analyse de données chronologiques.

Voici un tableau synthétique des unités converties :

  • 1 minute = 60 secondes
  • 1 heure = 60 minutes
  • 1 jour = 24 heures
  • 1 semaine = 7 jours
  • 1 mois (approximatif) = 30 jours
  • 1 an (approximatif) = 365 jours

Pour plus d’informations sur la conversion de chaînes en datetime en Python, vous pouvez consulter cet article ici.

Comment extraire une date précise d’un texte naturel ?

Souvent, vous devez extraire une date précise d’une phrase, comme « La réunion est le 15 janvier 2026 ». Cela peut sembler simple, mais les dates dans le texte naturel sont souvent entourées de bruit. Pour y remédier, nous allons utiliser une fonction Python astucieuse qui exploite un dictionnaire de mois et une expression régulière (regex) pour capturer le mois, le jour et éventuellement l’année.

Voici comment fonctionne cette fonction :

import re
from datetime import datetime

def extract_date_from_text(text, current_year=None):
    """
    Extrait des dates d'un texte en langage naturel.
    
    Gère des formats comme :
    - "15 janvier 2026"
    - "3 mars"
    - "25 déc."
    """
    if current_year is None:
        current_year = datetime.now().year
    
    # Dictionnaire des mois
    months = {
        'janvier': 1, 'jan': 1,
        'février': 2, 'fév': 2,
        'mars': 3, 'mar': 3,
        'avril': 4, 'avr': 4,
        'mai': 5,
        'juin': 6, 'jun': 6,
        'juillet': 7, 'juil': 7,
        'août': 8, 'août': 8,
        'septembre': 9, 'sep': 9,
        'octobre': 10, 'oct': 10,
        'novembre': 11, 'nov': 11,
        'décembre': 12, 'déc': 12
    }
    
    # Expression régulière pour capturer la date
    pattern = r'(janvier|jan|février|fév|mars|mar|avril|avr|mai|juin|jun|juillet|juil|août|septembre|sep|octobre|oct|novembre|nov|décembre|déc)\s+(\d{1,2})(?:st|nd|rd|th)?(?:,?\s+(\d{4}))?'
    
    matches = re.findall(pattern, text.lower())
    
    if not matches:
        return None
    
    # On prend le premier match
    month_str, day_str, year_str = matches[0]
    
    month = months[month_str]
    day = int(day_str)
    year = int(year_str) if year_str else current_year
    
    return datetime(year, month, day)

Cette fonction commence par établir un dictionnaire associant les mois à leurs valeurs numériques. Elle utilise ensuite une regex pour identifier les formats de date, y compris les suffixes anglais comme st, nd, rd, et th. Si l’année n’est pas fournie, elle remplace cette donnée par l’année actuelle.

Voyons quelques exemples :

text1 = "La réunion est le 15 janvier 2026."
text2 = "Répondez avant le 3 mars."
text3 = "Deadline : 25 déc."

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

print(f"De '{text1}': {date1}")
print(f"De '{text2}': {date2}")
print(f"De '{text3}': {date3}")

Les sorties seraient :

De 'La réunion est le 15 janvier 2026.': 2026-01-15 00:00:00
De 'Répondez avant le 3 mars.': 2026-03-03 00:00:00
De 'Deadline : 25 déc.': 2026-12-25 00:00:00

Cette méthode est simple et efficace pour extraire rapidement des dates utiles dans des textes non structurés. Pour approfondir vos connaissances sur la gestion des dates en Python, consultez cet article ici.

Comment gérer plusieurs formats de date avec un seul parser ?

Dans le monde réel, les dates ne se présentent pas toujours sous un format uniforme. Entre les formats ISO, les styles européens et américains, ainsi que l’utilisation de différents séparateurs, il est crucial d’avoir une approche flexible pour parser efficacement ces dates. Plutôt que de créer un parseur pour chaque format, une méthode plus judicieuse consiste à essayer plusieurs formats courants en série jusqu’à ce qu’un format valide soit trouvé.

Voici une fonction qui illustre cette approche. Elle tente de parser une date en utilisant une liste de formats prédéfinis, allant des plus standards aux plus exotiques, en passant par les variations avec ou sans séparateurs. Cela permet de s’assurer que même si les données sont un peu désordonnées, vous serez en mesure de récupérer une date valide.

from datetime import datetime

def parse_flexible_date(date_string):
    """
    Parse dates in multiple common formats.
    
    Tries various formats and returns the first match.
    """
    date_string = date_string.strip()
    
    # Liste des formats de date courants
    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',           
    ]
    
    # Essayer chaque format
    for fmt in formats:
        try:
            return datetime.strptime(date_string, fmt)
        except ValueError:
            continue
    
    raise ValueError(f"Unable to parse date: {date_string}")

Cette fonction teste successivement chaque format jusqu’à ce qu’elle trouve celui qui correspond à la chaîne de date donnée. Par exemple, si vous passez les chaînes suivantes :

  • « 2026-01-15 »
  • « 15/01/2026 »
  • « 01/15/2026 »
  • « 15.01.2026 »
  • « January 15, 2026 »

La fonction renverra la première date valide, ce qui peut s’avérer extrêmement utile dans des situations où les données proviennent de sources variées. Voici un tableau comparatif des formats testés :

Format Description
%Y-%m-%d ISO standard (2026-01-15)
%d/%m/%Y Format européen (15/01/2026)
%m/%d/%Y Format américain (01/15/2026)
%B %d, %Y Format avec nom du mois (January 15, 2026)

Bien que cette méthode soit simple et robuste, elle peut être légèrement moins performante en raison des multiples essais. Cependant, dans la plupart des cas, la flexibilité qu’elle offre vaut bien ce petit compromis. Pour plus d’informations sur la manipulation des dates et heures en Python, consultez la documentation officielle ici.

Comment transformer des durées textuelles en objets timedelta ?


Les durées sont souvent exprimées dans des formats variés qui peuvent rendre leur traitement délicat. On rencontre fréquemment des chaînes comme « 1h 30m », « 2:45:30 » ou même « 90 minutes ». Pour les développeurs en Python, il est crucial de transformer ces durées textuelles en objets timedelta pour effectuer des calculs. Voyons comment procéder.

La première étape consiste à détecter si la chaîne de durée utilise le format « H:M:S » grâce à la présence du caractère « : ». Si tel est le cas, on peut séparer les heures, les minutes et les secondes. Voici un exemple de fonction qui gère cela :

from datetime import timedelta
import re

def parse_duration(duration_string):
    duration_string = duration_string.strip().lower()
    
    # Essayer le format avec deux points d'abord (H:M:S ou M:S)
    if ':' in duration_string:
        parts = duration_string.split(':')
        if len(parts) == 2:
            minutes, seconds = map(int, parts)
            return timedelta(minutes=minutes, seconds=seconds)
        elif len(parts) == 3:
            hours, minutes, seconds = map(int, parts)
            return timedelta(hours=hours, minutes=minutes, seconds=seconds)
    
    # Essayer le format basé sur les unités (1h 30m 45s)
    total_seconds = 0
    
    # Trouver les heures
    hours_match = re.search(r'(\d+(?:\.\d+)?)\s*h(?:ours?)?', duration_string)
    if hours_match:
        total_seconds += float(hours_match.group(1)) * 3600
    
    # Trouver les 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
    
    # Trouver les secondes
    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}")

Cette fonction commence par vérifier si la chaîne contient un caractère « : ». Si oui, elle l'interprète comme un format horaire. Ensuite, elle utilise des expressions régulières (regex) pour détecter les heures, les minutes et les secondes dans les formats textuels. Les valeurs extraites sont converties en secondes et ajoutées pour obtenir un total, qui est ensuite retourné sous forme de timedelta.

Voici quelques exemples pratiques et leurs résultats :

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}")

Les résultats démontrent comment les durées sont efficacement converties en objets timedelta, facilitant ainsi leur manipulation dans les calculs ou les applications. Pour plus d'informations sur la gestion des dates en Python, vous pouvez consulter cet article ici.

Comment interpréter les dates au format ISO semaine ?

Le format ISO semaine est un standard souvent utilisé dans le monde des affaires pour la planification et la gestion des projets. Par exemple, une date au format « 2026-W03-2 » signifie que nous sommes dans la semaine 3 de l’année 2026 et que le jour concerné est le mardi (jour 2 de la semaine). Une caractéristique essentielle de ce format est que la semaine 1 est définie comme la semaine contenant le premier jeudi de l’année. Cela peut sembler déroutant au début, mais cela garantit que chaque année commence avec une semaine complète selon le calendrier ISO.

Pour parser efficacement ces dates, il est crucial de comprendre comment calculer la date à partir du lundi de la semaine 1. Voici une fonction qui effectue cette tâche :

from datetime import datetime, timedelta

def parse_iso_week_date(iso_week_string):
    """
    Parse ISO week date format: YYYY-Www-D
    
    Example: "2024-W03-2" = Week 3 of 2024, Tuesday
    """
    # Parse the 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

Cette fonction commence par décomposer la chaîne de caractères représentant la date ISO semaine. Elle s'assure que le format est correct et que les valeurs de la semaine et du jour sont valides. Ensuite, elle trouve le lundi de la première semaine de l'année en se basant sur la date du 4 janvier, qui est toujours dans cette semaine. À partir de là, elle ajoute le nombre de semaines et de jours spécifié pour obtenir la date finale.

Voici quelques exemples d'utilisation :

# 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)')}")

En exécutant ce code, vous obtiendrez des résultats comme :

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

Avoir un parseur pour ce format est particulièrement utile dans des contextes de planification hebdomadaire, où la précision des dates est essentielle. En maîtrisant cette technique, vous serez en mesure de gérer efficacement les projets qui s'appuient sur le calendrier ISO.

Prêt à dompter toutes vos dates et heures en Python ?

Ces cinq fonctions DIY vous offrent une boîte à outils solide pour parser dates, heures, durées et formats complexes en Python sans galérer. Vous gagnez en flexibilité, compréhension et autonomie face aux données désordonnées du réel. Plus besoin de dépendre de bibliothèques lourdes ou de recoder à chaque fois. C’est un vrai gain de temps et d’efficacité, idéal pour vos scripts, prototypes et projets data. Alors, convaincu que vos dates ne seront plus jamais un casse-tête ?

FAQ

Comment gérer les formats de dates imprévus en Python ?

Utilisez une fonction qui tente plusieurs formats courants successivement, comme montré avec la fonction parse_flexible_date, pour capturer la date correcte sans erreur.

Peut-on parser des durées en format texte facilement ?

Oui, en combinant la détection des formats H:M:S avec des expressions régulières pour extraire heures, minutes et secondes, on convertit aisément en objets timedelta exploitables.

Pourquoi approximons-nous les mois et années dans la conversion des dates relatives ?

Parce que timedelta ne supporte pas directement les mois et années, on utilise des approximations (30 jours/mois, 365 jours/an) suffisantes pour la plupart des cas pratiques.

Comment extraire une date d’un texte contenant plusieurs informations ?

Une regex ciblée couplée à un dictionnaire de mois permet d’isoler le premier motif date, même avec suffixes et année optionnelle, facilitant ainsi l’extraction rapide.

Quand utiliser le format ISO semaine pour les dates ?

Le format ISO semaine est privilégié dans les contextes business et planification hebdomadaire, où la gestion par semaine est plus pertinente que par jour calendaire classique.

 

 

A propos de l'auteur

Franck Scandolera, expert et consultant en Analytics, Data, Automatisation et IA, accompagne depuis plusieurs années les entreprises dans la maîtrise et l’intégration des données complexes. Formateur reconnu, il partage son savoir-faire autour des outils Python, des workflows IA et des meilleures pratiques pour transformer vos données en leviers concrets de performance.

Retour en haut
DataMarket AI