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

Comment parser efficacement les dates et heures en Python ?

Parser dates et heures en Python peut vite virer au cauchemar avec des formats variés et du texte sale. Voici cinq fonctions DIY pour maîtriser ces formats, du temps relatif aux durées complexes, sans dépendances lourdes.

3 principaux points à retenir.

  • Gérez les temps relatifs comme « 5 minutes ago » en les convertissant en objets datetime précis.
  • Extraire des dates dans du texte naturel grâce à des expressions régulières ciblées.
  • Parsez flexiblement plusieurs formats de dates et durées pour couvrir vos besoins réels.

Comment convertir des temps relatifs en dates précises

Transformer des expressions de temps relatives, comme « 2 hours ago », en objets datetime concrets peut sembler un défi, mais avec Python, c’est un jeu d’enfant, surtout grâce à la puissance des regex et des objets timedelta. Voici comment procéder.

La fonction parse_relative_time que nous allons créer s’appuie sur la bibliothèque datetime de Python, ainsi que sur le module re pour les expressions régulières. Son rôle est d’extraire le nombre et l’unité de temps d’une chaîne de caractères, puis de calculer la date correspondante en soustrayant un timedelta approprié à un temps de référence.

Voici un aperçu de la fonction :

from datetime import datetime, timedelta
import re

def parse_relative_time(time_string, reference_time=None):
    if reference_time is None:
        reference_time = datetime.now()
    
    time_string = time_string.lower().strip()
    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"Cannot parse: {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)  # Approximation
    elif unit == 'year':
        return reference_time - timedelta(days=amount * 365)  # Approximation

Cette fonction se veut simple mais efficace. Elle commence par vérifier si un temps de référence est fourni ; sinon, elle utilise la date et l’heure actuelles. Ensuite, elle utilise une expression régulière pour extraire le nombre et l’unité. Si l’unité est reconnue, elle crée un timedelta et le soustrait à la date de référence. Pour les mois et les années, elle fait une approximation, car tous les mois n’ont pas le même nombre de jours.

Pour tester la fonction, vous pouvez l’utiliser de cette manière :

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 afficheront des dates précises basées sur le temps de référence. Grâce à cette approche, vous pouvez facilement gérer des formats de temps relatifs dans vos projets Python, rendant votre code à la fois robuste et flexible. Pour approfondir la gestion des dates en Python, consultez cet article.

Comment extraire une date depuis un texte naturel

Extraire des dates depuis du texte naturel peut sembler être une tâche banale, mais c’est en réalité un défi fréquent, surtout lorsque vous traitez des données non structurées. Imaginez que vous travaillez sur un projet de scraping de données et que vous devez récupérer des dates de phrases comme « La réunion est fixée au 15 janvier 2026 » ou « Veuillez répondre avant le 3 mars ». Comment faire ? C’est là que l’utilisation de Python et des expressions régulières entre en jeu.

Pour commencer, nous devons construire un dictionnaire qui associe les noms des mois à leurs valeurs numériques. Cela nous permettra de convertir les mois en chiffres, ce qui est essentiel pour créer des objets de date. Voici un exemple de ce dictionnaire :


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, 'jui': 7,
    'août': 8, 'aou': 8,
    'septembre': 9, 'sep': 9,
    'octobre': 10, 'oct': 10,
    'novembre': 11, 'nov': 11,
    'décembre': 12, 'déc': 12
}

Ensuite, nous allons utiliser une expression régulière pour capter les dates présentes dans le texte. Le motif que nous allons utiliser doit être capable de reconnaître les mois suivis d’un jour, avec des suffixes comme « er », « nd », « rd » ou « th », et éventuellement une année. Voici un exemple de motif regex :


pattern = r'(janvier|jan|février|fév|mars|mar|avril|avr|mai|juin|jun|juillet|jui|août|aou|septembre|sep|octobre|oct|novembre|nov|décembre|déc)\s+(\d{1,2})(?:er|nd|rd|th)?(?:,?\s+(\d{4}))?'

Dans cette regex, le premier groupe capte le nom du mois, le deuxième groupe le jour, et le troisième groupe l’année qui est optionnelle. Si l’année n’est pas présente, nous allons utiliser l’année courante. Cela fait sens, car si quelqu’un mentionne « 3 mars » en janvier, il est probable qu’il parle du mars à venir.

Voici une fonction complète qui extrait une date depuis un texte naturel :


from datetime import datetime
import re

def extract_date_from_text(text, current_year=None):
    if current_year is None:
        current_year = datetime.now().year
    
    matches = re.findall(pattern, text.lower())
    
    if not matches:
        return None
    
    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)

Pour tester notre fonction, essayons plusieurs phrases :


text1 = "La réunion est fixée au 15 janvier 2026"
text2 = "Veuillez répondre avant le 3 mars"
text3 = "Date limite : 25 déc. 2026"

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

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

Cette approche est extrêmement utile pour analyser des données textuelles non structurées. En récupérant les dates de manière automatisée, vous pouvez ensuite les utiliser pour des analyses statistiques, des plannings ou tout autre traitement de données. Pour plus d’astuces sur la gestion des dates en Python, vous pouvez consulter cet article.

Comment parser plusieurs formats de dates automatiquement


Dans le monde réel, les formats de dates sont aussi variés que les utilisateurs qui les saisissent. Pour gérer cette diversité, il est crucial de créer une fonction Python capable de détecter automatiquement plusieurs formats de dates. Voici comment procéder.

La fonction suivante teste séquentiellement une liste de formats standards pour déterminer lequel correspond à la chaîne de date fournie. Cela permet de convertir des dates sous différents formats (ISO, européen, américain, texte, etc.) en objets datetime.

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()
    
    # List of common date formats
    formats = [
        '%Y-%m-%d',           # ISO format
        '%Y/%m/%d',           # ISO alternative
        '%d-%m-%Y',           # European format
        '%d/%m/%Y',           # European alternative
        '%m/%d/%Y',           # American format
        '%d.%m.%Y',          # European with dots
        '%Y%m%d',            # Compact format
        '%B %d, %Y',        # Full month name
        '%b %d, %Y',         # Abbreviated month name
        '%d %B %Y',          # Day and full month
        '%d %b %Y',           # Day and abbreviated month
    ]
    
    # Try each format
    for fmt in formats:
        try:
            return datetime.strptime(date_string, fmt)
        except ValueError:
            continue
    
    # If nothing worked, raise an error
    raise ValueError(f"Unable to parse date: {date_string}")

Il est essentiel d’ordonner les formats de manière stratégique. En plaçant le format ISO en premier, qui est le plus courant dans les contextes techniques, vous minimisez les erreurs. Les formats ambigus, comme le %d/%m/%Y et le %m/%d/%Y, doivent être testés plus tard pour éviter toute confusion, notamment dans les cas où le jour et le mois pourraient être inversés.

Voici un exemple pour tester cette fonction avec différentes chaînes de date :

# Test different formats
dates = [
    "2026-01-15",
    "15/01/2026",
    "01/15/2026",
    "15.01.2026",
    "20260115",
    "January 15, 2026",
    "15 Jan 2026"
]

for date_str in dates:
    parsed = parse_flexible_date(date_str)
    print(f"{date_str:20} -> {parsed}")

Cette méthode est à la fois simple et efficace pour traiter des données hétérogènes. En utilisant cette fonction, vous vous assurez que peu importe le format de date que vous recevez, vous pourrez le convertir facilement en un objet datetime, prêt à être utilisé dans vos applications. Pour plus d’informations sur la gestion des dates et heures en Python, vous pouvez consulter la documentation officielle.

Comment convertir des durées textuelles en objets timedelta


Les durées exprimées sous forme textuelle peuvent être particulièrement délicates à gérer dans un projet Python. Que vous soyez en train d'analyser des données de performance, de suivre le temps d'exécution d'un processus ou de gérer des horaires, il est crucial de convertir ces durées en objets timedelta exploitables. Cela permet d'effectuer des calculs précis et d'éviter les erreurs de manipulation.

Nous allons voir comment parser des durées dans des formats variés comme "1h 30m 45s", "2:45:30" ou "90 minutes". La méthode que nous allons utiliser se divise en deux étapes. D'abord, nous allons détecter si la chaîne de caractères suit un format heure:minute:seconde. Si ce n'est pas le cas, nous passerons à une recherche via regex pour extraire les heures, minutes et secondes, tout en gérant les décimales.

Voici une fonction Python qui illustre ce processus :

from datetime import timedelta
import re

def parse_duration(duration_string):
    """
    Parse des chaînes de durée en objets timedelta.
    
    Gère des formats comme :
    - "1h 30m 45s"
    - "2:45:30" (H:M:S)
    - "90 minutes"
    - "1.5 heures"
    """
    duration_string = duration_string.strip().lower()
    
    # Vérification du format avec des deux-points
    if ':' in duration_string:
        parts = duration_string.split(':')
        if len(parts) == 2:
            # Format M:S
            minutes, seconds = map(int, parts)
            return timedelta(minutes=minutes, seconds=seconds)
        elif len(parts) == 3:
            # Format H:M:S
            hours, minutes, seconds = map(int, parts)
            return timedelta(hours=hours, minutes=minutes, seconds=seconds)
    
    # Format basé sur les unités
    total_seconds = 0
    
    # Recherche des heures
    hours_match = re.search(r'(\d+(?:\.\d+)?)\s*h(?:ours?)?', duration_string)
    if hours_match:
        total_seconds += float(hours_match.group(1)) * 3600
    
    # Recherche des 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
    
    # Recherche des 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"Impossible de parser la durée : {duration_string}")

# Exemples de test
durations = [
    "1h 30m 45s",
    "2:45:30",
    "90 minutes",
    "1.5 heures",
    "45s",
    "2h 15m"
]

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

Ce code montre comment gérer divers formats de durée et les convertir en objets timedelta. L'importance de cette conversion ne doit pas être sous-estimée : elle permet de manipuler des données temporelles complexes avec efficacité. Pour une compréhension plus approfondie de la conversion de chaînes en objets datetime, vous pouvez consulter cet article sur DataCamp.

Comment interpréter les dates au format ISO semaine

Le format de date ISO semaine, tel que « 2026-W03-2 », est une notation qui représente une semaine particulière dans une année donnée. Cette notation se décompose en trois éléments : l’année (2026), le numéro de la semaine (W03), et le jour de la semaine (2, où 1 correspond à lundi et 7 à dimanche). Ce système est principalement utilisé dans des contextes professionnels, notamment pour la planification de projets, la gestion des ressources humaines et le suivi des performances. Il permet de standardiser la manière dont les semaines sont référencées, ce qui est crucial pour les entreprises qui opèrent sur des cycles hebdomadaires.

La logique derrière la conversion de cette notation en une date classique repose sur la détermination du lundi de la première semaine de l’année. Pour ce faire, on commence par trouver le 4 janvier de l’année en question. Ce jour-là est toujours dans la première semaine selon la norme ISO. Ensuite, il suffit de calculer le lundi de cette semaine et d’ajouter les semaines et les jours nécessaires pour obtenir la date finale.

Voici une fonction Python complète qui illustre cette conversion :

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 

Cette fonction est particulièrement utile pour les projets qui manipulent des données hebdomadaires ou qui nécessitent une planification précise. En traitant les dates au format ISO semaine, vous pouvez facilement intégrer des cycles de travail, des rapports hebdomadaires ou des plannings dans vos applications. Cela permet de gagner un temps considérable par rapport à un traitement manuel des dates.

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

Ces cinq fonctions DIY vous offrent une boîte à outils concrète pour parser dates et heures en Python, sans vous perdre dans les bibliothèques lourdes ou les formats obscurs. Que ce soit pour convertir du temps relatif, extraire des dates dans du texte libre, gérer plusieurs formats, ou manipuler durées et semaines ISO, vous avez désormais des solutions claires et testées. Intégrer ces fonctions dans vos projets vous fera gagner un temps fou et évitera les bugs liés aux formats temporels mal gérés. En maîtrisant ces techniques, vous transformez une source classique de galère en un atout solide pour vos développements.

FAQ

Pourquoi Python a-t-il du mal avec les dates non standard ?

Python gère très bien les formats standards via datetime, mais les données réelles sont souvent imprécises, hétérogènes ou en langage naturel, ce qui nécessite des parsers personnalisés utilisant regex et logique métier pour extraire correctement les informations.

Comment gérer les durées exprimées en texte libre ?

En combinant la détection de formats colon (H:M:S) avec l'extraction via expressions régulières des unités heures, minutes et secondes, on peut convertir ces durées en objets timedelta utilisables pour calculs et comparaisons.

Quelle est la meilleure méthode pour parser plusieurs formats de dates ?

Tester plusieurs formats connus dans un ordre logique avec datetime.strptime, en capturant les erreurs pour passer au format suivant, est simple et efficace pour couvrir la majorité des cas rencontrés.

Quand utiliser le format ISO semaine ?

Le format ISO semaine est privilégié en business pour planifier ou analyser des données à l'échelle hebdomadaire, notamment dans la gestion de projets, la production ou le reporting.

Peut-on remplacer ces fonctions DIY par des bibliothèques externes ?

Oui, des bibliothèques comme dateutil ou arrow existent, mais ces fonctions DIY sont légères, transparentes, et parfaites pour des scripts simples ou quand on veut comprendre la mécanique du parsing sans dépendances lourdes.

 

 

A propos de l'auteur

Franck Scandolera cumule des années d'expérience en analytics, data et automatisation IA, notamment dans le développement d'applications Python intégrant des traitements temporels complexes. Consultant et formateur reconnu, il accompagne les entreprises à exploiter leurs données efficacement, en alliant rigueur technique et pragmatisme. Basé à Brive‑la‑Gaillarde, il intervient partout en France, Suisse et Belgique, avec un focus sur les workflows métier intégrant l'intelligence artificielle.

Retour en haut
Click Power Up