Parser les dates et heures en Python peut vite tourner au cauchemar avec des formats hétérogènes. Cet article vous guide avec 5 fonctions Python DIY pour transformer ces données en objets exploitables, claires et robustes, sans dépendre de bibliothèques lourdes.
3 principaux points à retenir.
- Maîtrisez les formats relatifs et naturels grâce à des regex ciblées et datetime.
- Adoptez la flexibilité avec un parseur multi-format pour ne jamais bloquer votre code.
- Gérez aussi les durées et ISO weeks pour couvrir tous les cas d’usage réels.
Comment convertir des dates relatives en objets datetime ?
Les dates relatives, comme « 5 minutes ago » ou « 2 jours auparavant », sont monnaie courante dans les données que vous récupérez sur les réseaux sociaux ou dans les applications de messagerie. Pourquoi est-il si crucial de les convertir en objets datetime précis ? Simple : pour effectuer des analyses fiables et pour que votre code ne se transforme pas en un véritable casse-tête. Si vous ne gérez pas correctement ces formats, vous risquez de vous retrouver avec des erreurs qui feront plantés votre application.
Voici une fonction Python qui fait le job de manière efficace. Elle utilise des expressions régulières (regex) pour extraire le nombre et l’unité de temps, puis calcule le datetime en soustrayant un timedelta approprié.
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"Impossible de parser : {time_string}")
amount = int(match.group(1))
unit = match.group(2)
# Mappage des unités aux 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':
# Approximatif : 30 jours par mois
return reference_time - timedelta(days=amount * 30)
elif unit == 'year':
# Approximatif : 365 jours par an
return reference_time - timedelta(days=amount * 365)
Cette fonction est assez robuste. Elle utilise un motif regex pour capturer le nombre et l’unité. Ainsi, que vous ayez « 2 heures » ou « 3 jours », elle saura les interpréter. Pour les mois et les années, l’approche est approximative, mais elle suffit pour la plupart des cas. Le paramètre reference_time est particulièrement utile pour tester ou traiter des données historiques. Vous pouvez ainsi simuler des dates passées sans avoir à changer votre logique de code.
Voyons quelques exemples concrets :
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}")
La sortie pourrait ressembler à ceci :
2 hours ago: 2026-01-06 12:09:34.584107
3 days ago: 2026-01-03 14:09:34.584504
1 week ago: 2025-12-30 14:09:34.584558
Avec cette fonction, vous êtes armé pour transformer des données brutes en informations exploitables. Plus besoin de vous casser la tête avec des formats de temps fantaisistes. Pour aller plus loin dans vos explorations de Python, n’hésitez pas à consulter des ressources comme KDnuggets.
Comment extraire des dates dans du texte naturel ?
Souvent, les dates se perdent dans le flot de texte. Que ce soit dans un e-mail, un rapport ou un message, il n’est pas rare de devoir extraire une date d’une phrase complexe. La bonne nouvelle, c’est qu’il existe des méthodes efficaces pour réaliser cette extraction sans se perdre dans les détails. Voici une fonction Python qui utilise une regex fine pour détecter les mois, qu’ils soient abrégés ou complets, ainsi que les jours, souvent accompagnés de suffixes ordinals tels que « st », « nd », « rd » ou « th ». L’année, quant à elle, est optionnelle, et si elle n’est pas précisée, la fonction par défaut choisit de prendre l’année courante. C’est un choix pragmatique, surtout lorsqu’on traite des données textuelles où le contexte temporel est souvent implicite.
import re
from datetime import datetime
def extract_date_from_text(text, current_year=None):
"""
Extract dates from natural language text.
Handles formats like:
- "January 15th, 2024"
- "March 3rd"
- "Dec 25th, 2023"
"""
if current_year is None:
current_year = datetime.now().year
# Month names (full and abbreviated)
months = {
'january': 1, 'jan': 1,
'february': 2, 'feb': 2,
'march': 3, 'mar': 3,
'april': 4, 'apr': 4,
'may': 5,
'june': 6, 'jun': 6,
'july': 7, 'jul': 7,
'august': 8, 'aug': 8,
'september': 9, 'sep': 9, 'sept': 9,
'october': 10, 'oct': 10,
'november': 11, 'nov': 11,
'december': 12, 'dec': 12
}
# Pattern: Month Day(st/nd/rd/th), Year (year optional)
pattern = r'(january|jan|february|feb|march|mar|april|apr|may|june|jun|july|jul|august|aug|september|sep|sept|october|oct|november|nov|december|dec)\s+(\d{1,2})(?:st|nd|rd|th)?(?:,?\s+(\d{4}))?'
matches = re.findall(pattern, text.lower())
if not matches:
return None
# Take the first 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)
Testons cette fonction sur plusieurs phrases variées pour voir son efficacité :
text1 = "The meeting is scheduled for January 15th, 2026 at 3pm"
text2 = "Please respond by 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(f"From '{text1}': {date1}")
print(f"From '{text2}': {date2}")
print(f"From '{text3}': {date3}")
Les résultats montrent que la fonction extrait correctement les dates de phrases riches en informations :
From 'The meeting is scheduled for January 15th, 2026 at 3pm': 2026-01-15 00:00:00
From 'Please respond by March 3rd': 2026-03-03 00:00:00
From 'Deadline: Dec 25th, 2026': 2026-12-25 00:00:00
Cette méthode démontre la puissance de l’utilisation des regex pour nettoyer rapidement des données textuelles. Vous pouvez explorer davantage sur la conversion de chaînes en objets datetime ici. Elle vous aidera à gérer des cas similaires où l’extraction de données précises est essentielle.
Comment gérer les formats de dates multiples en Python ?
Le monde des dates et heures en Python est une jungle, peuplée de formats disparates : ISO, US, EU, avec ou sans séparateurs. Vous vous êtes déjà retrouvé à jongler avec des chaînes comme « 2026-01-15 », « 15/01/2026 » ou « 01/15/2026 » ? Ne vous inquiétez pas, vous n’êtes pas seul. Cette diversité rend le parsing rigide et peu efficace si l’on ne s’arme pas d’une méthode robuste.
Pour résoudre ce casse-tête, une approche efficace consiste à créer une fonction qui tente de parser une date en utilisant plusieurs formats standards, en s’arrêtant dès qu’un format correspond. Cette méthode de brute force est simple et fonctionne dans la majorité des cas pratiques.
Voici un exemple de code qui fait exactement cela :
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',
'%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',
]
# 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}")
Cette fonction commence par normaliser la chaîne de date, puis elle parcourt une liste de formats. Si l’un d’eux correspond, elle renvoie la date sous forme d’objet datetime. Sinon, elle lève une erreur. Voici quelques exemples d’entrées variées et leur parsing réussi :
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 brute force est non seulement simple, mais aussi robuste pour la plupart des cas pratiques. Vous pouvez vous appuyer dessus pour gérer la variété des formats que vous rencontrerez dans vos projets. Pour plus de détails sur la manipulation des dates et heures en Python, n’hésitez pas à consulter la documentation officielle ici.
Comment parser des durées exprimées en formats variés ?
Les durées, souvent exprimées sous des formats variés comme « 1h 30m », « 2:45:30 » ou « 90 minutes », exigent une conversion précise en objets timedelta pour des calculs fiables. Ces formats peuvent provenir de nombreuses sources, que ce soit pour le suivi d’activités sportives, la gestion de vidéos ou des applications de suivi du temps. Ignorer la flexibilité de ces formats pourrait vous coûter cher en termes de précision.
Pour gérer cela, voici une fonction qui commence par le format colon (H:M:S ou M:S), puis analyse les chaînes unitaires à l’aide de regex pour extraire les heures, minutes et secondes. Cela permet également de supporter les nombres décimaux, ce qui est crucial dans des contextes où des précisions sont nécessaires.
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}")
Pour tester cette fonction, envisagez des durées telles que « 1h 30m 45s », « 2:45:30 », « 90 minutes », « 1.5 hours », « 45s », et « 2h 15m ». Voici comment cela fonctionne :
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}")
Cette approche permet une flexibilité essentielle. En effet, lorsque vous traitez des données variées, cette fonction s’avère être un outil précieux pour garantir que vous pouvez interpréter correctement les durées, quel que soit le format d’entrée. Non seulement elle vous aide à gagner du temps, mais elle assure également que vos calculs sont précis et fiables dans n’importe quel contexte.
Pour aller plus loin, vous pouvez consulter des ressources supplémentaires sur la conversion et le parsing des dates en Python. Une bonne référence est disponible ici.
Comment interpréter les dates au format ISO semaine ?
Le format ISO semaine, représenté par des chaînes comme ‘2026-W03-2’, est un standard couramment utilisé dans le monde professionnel pour la planification hebdomadaire. Ce format se décompose en trois éléments : l’année, la semaine (précédée d’un ‘W’) et le jour de la semaine (où 1 représente lundi et 7 dimanche). Une particularité importante de ce système est que la première semaine de l’année est définie comme celle contenant le premier jeudi de l’année, ce qui peut parfois décaler le début de l’année calendaire.
Pour déterminer la date exacte à partir d’un format ISO semaine, il faut d’abord identifier le lundi de la première semaine. Pour ce faire, on commence par localiser le 4 janvier de l’année concernée, car ce jour sera toujours dans la première semaine. Ensuite, on recule jusqu’au lundi de cette semaine. À partir de là, on ajoute le nombre de semaines et de jours spécifiés dans la chaîne ISO pour obtenir la date finale.
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
"""
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
Pour tester la fonction, 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)')}")
Voici les résultats attendus :
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 le format ISO semaine est crucial dans les applications professionnelles, car il facilite la gestion des plannings, des rendez-vous et des rapports hebdomadaires. Pour approfondir vos connaissances sur la gestion des dates en Python, n'hésitez pas à consulter cet article : Gestion des dates avec Python.
Prêt à dompter toutes vos dates et heures en Python sans galérer ?
Ces cinq fonctions DIY couvrent l’essentiel des formats et défis rencontrés avec les dates et temps en Python. Du relatif au naturel, du multi-format au temps ISO, en passant par les durées, vous avez désormais des outils clairs et légers pour transformer vos données en or exploitable. Fini les plantages et les conversions approximatives. Vous gagnez en maîtrise, en robustesse, et en autonomie, sans rajouter de dépendances inutiles. Votre code devient enfin à la hauteur de vos ambitions data et business.
FAQ
Pourquoi les dates relatives posent-elles problème en programmation ?
Comment gérer les formats de dates inconnus ou multiples ?
Les regex sont-elles fiables pour extraire des dates dans du texte naturel ?
Comment convertir des durées en format texte en objets exploitables ?
Qu'est-ce que le format ISO semaine et pourquoi l'utiliser ?
A propos de l'auteur
Consultant et formateur expert en Analytics, Data et Automatisation IA, je mets à profit plusieurs années d’expérience pour simplifier les problématiques techniques complexes. Passionné par le développement Python orienté data, j'accompagne les entreprises à intégrer l’intelligence artificielle et à automatiser leurs workflows métier. Basé à Brive-la-Gaillarde, je partage régulièrement mes retours d’expérience et conseils pratiques pour rendre la data accessible et opérationnelle.
⭐ Expert et formateur en Tracking avancé, Analytics Engineering et Automatisation IA (n8n, Make) ⭐
Ref clients : Logis Hôtel, Yelloh Village, BazarChic, Fédération Football Français, Texdecor…
Mon terrain de jeu :
Data & Analytics engineering : tracking propre RGPD, entrepôt de données (GTM server, BigQuery…), modèles (dbt/Dataform), dashboards décisionnels (Looker, SQL, Python).
Automatisation IA des taches Data, Marketing, RH, compta etc : conception de workflows intelligents robustes (n8n, Make, 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.






