Le parsing des dates et heures en Python est souvent un casse-tête à cause des formats variés et imprévisibles. Voici 5 fonctions DIY robustes pour transformer ces données chaotiques en objets exploitables, sans dépendre d’outils lourds ni perdre de temps.
3 principaux points à retenir.
- Parsez les dates relatives comme « 2 hours ago » en datetime précis.
- Extraire les dates cachées dans un texte naturel grâce aux regex.
- Gérez les formats flexibles et durées variées pour éviter les erreurs courantes.
Comment convertir des dates relatives en objets datetime ?
Convertir des chaînes comme « 3 days ago » en objets datetime est essentiel pour rendre les données temporelles exploitables. Imaginez que vous scrapez des données d’une application de réseaux sociaux, où les utilisateurs interagissent avec des messages dans un format relatif. Sans une méthode pour convertir ces chaînes en objets datetime, vous seriez coincé dans un labyrinthe de données inutilisables.
La fonction parse_relative_time est votre alliée dans cette tâche. Elle utilise une expression régulière (regex) pour détecter à la fois le nombre et l’unité de temps, puis crée un timedelta approprié pour soustraire du temps à une date de référence, qui est par défaut la date et l’heure actuelles.
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()
# Normalisation de la chaîne
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"Cannot parse: {time_string}")
amount = int(match.group(1))
unit = match.group(2)
# Mapping des unités vers les kwargs de timedelta
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
Pour tester cette fonction, vous pouvez l’utiliser comme ceci :
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 retourneront des objets datetime précis, vous permettant ainsi de manipuler ces données efficacement. Cette fonction est particulièrement utile dans les applications sociales ou lors de l’extraction de données, où les formats de date peuvent varier considérablement. En intégrant cette méthode dans votre boîte à outils, vous vous assurez de pouvoir gérer les timestamps relatifs avec aisance.
Comment extraire une date d’un texte en langage naturel ?
Dans le monde du traitement de texte, les dates sont souvent noyées au milieu de phrases, rendant leur extraction cruciale. Imaginez un email où il est mentionné que « la réunion est prévue pour le 15 janvier 2026 ». Vous ne voulez pas vous farcir toute la phrase pour extraire simplement la date. C’est là qu’intervient la fonction extract_date_from_text, qui utilise un dictionnaire de mois et une expression régulière (regex) sophistiquée pour capturer mois, jour, suffixes ordinals et année optionnelle.
Le principe est simple mais efficace. La fonction commence par définir un dictionnaire qui associe les noms des mois, qu’ils soient complets ou abrégés, à leurs valeurs numériques. Par exemple, « janvier » devient 1, « février » devient 2, etc. Ensuite, un motif regex est utilisé pour rechercher des formats de dates typiques dans le texte. Le motif est conçu pour capturer le mois, le jour (avec éventuellement un suffixe ordinal comme « st », « nd », « rd », « th ») et l’année, qui est optionnelle.
Quand l’année n’est pas fournie, la fonction attribue automatiquement l’année en cours. Cela a du sens : si quelqu’un mentionne « le 3 mars » en janvier, il est raisonnable de penser qu’il fait référence au mars à venir, pas à celui de l’année précédente.
text1 = "La réunion est prévue pour le 15 janvier 2026 à 15h00"
text2 = "Merci de 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(f"De '{text1}': {date1}")
print(f"De '{text2}': {date2}")
print(f"De '{text3}': {date3}")
Dans cet exemple, la fonction extrait correctement les dates des différentes phrases, et vous pouvez voir les résultats dans la console. Cela a un intérêt particulier pour les applications de traitement de texte, les emails ou l’automatisation des tâches. En intégrant cette fonctionnalité dans vos projets, vous pouvez facilement extraire des informations temporelles utiles sans vous perdre dans le reste du texte.
Comment gérer plusieurs formats de date avec un seul parseur ?
Face à la diversité des formats de date, que ce soit ISO, européen, américain, ou même en texte libre, un parseur flexible est indispensable. La fonction parse_flexible_date se présente comme une solution efficace. Elle teste séquentiellement plusieurs formats standards en utilisant strptime, capturant la première correspondance trouvée.
Voici les formats courants supportés par cette fonction :
%Y-%m-%d(ex: 2026-01-15)%Y/%m/%d(ex: 2026/01/15)%d-%m-%Y(ex: 15-01-2026)%d/%m/%Y(ex: 15/01/2026)%m/%d/%Y(ex: 01/15/2026)%d.%m.%Y(ex: 15.01.2026)%Y%m%d(ex: 20260115)%B %d, %Y(ex: January 15, 2026)%b %d, %Y(ex: Jan 15, 2026)%d %B %Y(ex: 15 January 2026)%d %b %Y(ex: 15 Jan 2026)
L’ordre de ces formats est stratégique. On place d’abord le format ISO (%Y-%m-%d), car c’est le plus utilisé dans les contextes techniques. Les formats ambigus comme %d/%m/%Y et %m/%d/%Y sont relégués plus loin dans la liste, ce qui permet d’éviter les confusions lors de l’analyse des données.
Voici un exemple de test avec diverses chaînes de dates :
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 approche brute-force est simple, mais elle s’avère extrêmement efficace pour traiter les formats variés que l’on rencontre dans des projets divers. En utilisant cette méthode, vous vous assurez que votre code reste propre et fonctionnel, même face aux imprévus que peut réserver la gestion des dates. Pour plus de détails sur la manipulation des dates en Python, consultez la documentation officielle.
Comment convertir des durées textuelles en objets timedelta ?
Dans le monde du développement, il est fréquent de rencontrer des durées exprimées sous des formats variés. Que ce soit « 1h 30m », « 2:45:30 » ou encore « 90 minutes », ces représentations doivent être converties en objets timedelta pour effectuer des calculs. La fonction parse_duration est spécifiquement conçue pour gérer ces cas.
La première étape de cette fonction consiste à traiter les formats utilisant des deux-points, comme H:M:S ou M:S. En cas de présence de deux-points dans la chaîne de caractères, la fonction divise la chaîne et interprète les parties comme heures, minutes et secondes. Si la chaîne a la forme M:S, elle ne traite que les minutes et secondes.
Pour les formats unitaires, la fonction utilise des expressions régulières (regex) pour cibler les heures, minutes et secondes, même en incluant les décimales. Par exemple, pour détecter les heures, la regex (\d+(?:\.\d+)?)\s*h(?:ours?)? permet de capturer des valeurs comme « 1.5h ». Voici comment cela se présente :
import re
from datetime import timedelta
def parse_duration(duration_string):
duration_string = duration_string.strip().lower()
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)
total_seconds = 0
hours_match = re.search(r'(\d+(?:\.\d+)?)\s*h(?:ours?)?', duration_string)
if hours_match:
total_seconds += float(hours_match.group(1)) * 3600
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
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}")
Testons maintenant notre fonction avec différents formats :
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 vous donneront des objets timedelta parfaitement adaptés pour vos calculs :
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
Cette souplesse du parser permet de s’adapter aux données utilisateur ou scrappées, rendant votre code plus robuste et réactif. Pour approfondir vos connaissances sur la conversion de chaînes en objets datetime, n’hésitez pas à consulter ce tutoriel.
Comment décoder les dates au format ISO semaine ?
Le format ISO semaine est un système utilisé principalement dans les environnements professionnels pour planifier les activités sur une base hebdomadaire. Ce format, tel que « 2024-W03-2 », indique la troisième semaine de l’année 2024, avec le jour 2 correspondant à un mardi. Bien que ce système soit pratique pour la planification, il est souvent nécessaire de convertir ces données en dates classiques pour les intégrer dans des systèmes qui n’utilisent pas ce format. C’est là qu’intervient notre fonction parse_iso_week_date.
Cette fonction prend une chaîne de caractères au format ISO semaine et la découpe pour extraire l’année, le numéro de la semaine et le jour. Voici comment elle fonctionne :
from datetime import datetime, timedelta
def parse_iso_week_date(iso_week_string):
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
La logique derrière cette fonction repose sur le fait que la première semaine de l'année est définie comme celle contenant le premier jeudi de l'année. Cela signifie que la semaine 1 peut commencer en décembre de l'année précédente. Pour calculer la date cible, la fonction trouve d'abord le lundi de la semaine 1, puis ajoute le nombre de semaines et de jours nécessaires pour obtenir la date souhaitée.
Pour illustrer cela, prenons quelques exemples :
# 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 résultats pour ces exemples seraient :
2024-W01-1 -> 2024-01-01 (Monday)
2024-W03-2 -> 2024-01-16 (Tuesday)
2024-W10-5 -> 2024-03-08 (Friday)
Ces conversions sont particulièrement pertinentes dans les contextes de planification professionnelle, où les projets sont souvent organisés par semaine. Une bonne maîtrise de la conversion entre les formats de date vous permettra de travailler plus efficacement et d'éviter les erreurs de calendrier. Pour approfondir vos connaissances sur la gestion des dates en Python, vous pouvez consulter ce tutoriel.
Prêt à maîtriser le parsing des dates et temps en Python ?
Vous voilà armé pour transformer n’importe quelle date ou durée en Python, même les formats les plus tordus. Ces fonctions DIY allient simplicité, robustesse et adaptabilité, idéales pour vos scripts, prototypes ou projets sans dépendances lourdes. En comprenant ces méthodes, vous évitez les pièges classiques des formats imprévus et gagnez en autonomie. Résultat : votre code ne casse plus à cause des dates, et vos données temporelles deviennent enfin exploitables et fiables.
FAQ
Comment gérer les formats de date inconnus en Python ?
Pourquoi approximons-nous les mois et années en jours ?
Comment extraire une date d’un texte complexe ?
Peut-on gérer les durées avec des formats mixtes ?
Quand utiliser le format ISO semaine ?
A propos de l'auteur
Franck Scandolera, consultant et formateur expert en Analytics, Data et Automatisation IA, accompagne depuis des années les professionnels dans la maîtrise des données complexes. Passionné par le développement Python et l’intégration d’IA dans les workflows métier, il partage ses connaissances pour rendre accessibles les sujets techniques pointus et pragmatiques.
⭐ Analytics engineer, Data Analyst et Automatisation IA indépendant ⭐
- Ref clients : Logis Hôtel, Yelloh Village, BazarChic, Fédération Football Français, Texdecor…
Mon terrain de jeu :
- Data Analyst & Analytics engineering : tracking avancé (GTM server, e-commerce, CAPI, RGPD), entrepôt de données (BigQuery, Snowflake, PostgreSQL, ClickHouse), modèles (Airflow, dbt, Dataform), dashboards décisionnels (Looker, Power BI, Metabase, SQL, Python).
- Automatisation IA des taches Data, Marketing, RH, compta etc : conception de workflows intelligents robustes (n8n, App Script, scraping) connectés aux API de vos outils et LLM (OpenAI, Mistral, Claude…).
- Engineering IA pour créer des applications et agent IA sur mesure : intégration de LLM (OpenAI, Mistral…), RAG, assistants métier, génération de documents complexes, APIs, backends Node.js/Python.





