2 votes

Analyse des chaînes de dates en Python

R dispose d'un flux de travail très agréable qui permet à l'utilisateur de définir l'ordre date/mois/année, mais qui gère autrement le désordre des chaînes de dates saisies par l'utilisateur :

date_str = c('05/03/2022', '14/03/2022', '14.03.2022', '14/03.2022')
lubridate::parse_date_time(date_str, orders = 'dmy')
#> [1] "2022-03-05 UTC" "2022-03-14 UTC" "2022-03-14 UTC" "2022-03-14 UTC"

Le plus proche que j'ai trouvé en Python est :

from dateparser import parse
date_str = ['05/03/2022', '14/03/2022', '14.03.2022', '14/03.2022']
list(map(lambda l: parse(l, date_formats = ['dmy']), date_str))
[datetime.datetime(2022, 5, 3, 0, 0),
 datetime.datetime(2022, 3, 14, 0, 0),
 datetime.datetime(2022, 3, 14, 0, 0),
 datetime.datetime(2022, 3, 14, 0, 0)]

qui gère le désordre mais transpose le jour/mois dans la première observation, je pense parce que date_formats donne la priorité aux formats explicitement définis et revient sinon au format (stupide) par défaut US mois-jour-année ?

Existe-t-il une bonne implémentation en Python qui permette de gérer le désordre et d'assumer un ordre date/mois ?

2voto

AKX Points 14236

Eh bien, si dateparser autrement fait ce que vous aimez, vous pouvez l'emballer doucement pour donner la priorité au format que vous aimez :

import dateparser
import datetime
import re

dmy_re = re.compile(r"^(?P<day>\d+)/(?P<month>\d+)/(?P<year>\d+)$")

def parse_with_dmy_priority(ds):
    dmy_match = dmy_re.match(ds)
    if dmy_match:
        return datetime.datetime(**{k: int(v) for (k, v) in dmy_match.groupdict().items()})
    return dateparser.parse(ds)

in_data = ['05/03/2022', '14/03/2022', '14.03.2022', '14/03.2022']
print([parse_with_dmy_priority(d) for d in in_data])

[
  datetime.datetime(2022, 3, 5, 0, 0), 
  datetime.datetime(2022, 3, 14, 0, 0),
  datetime.datetime(2022, 3, 14, 0, 0), 
  datetime.datetime(2022, 3, 14, 0, 0),
]

Cela se généralise bien aussi :

def parse_date(ds, regexps=()):
    for regexp in regexps:
        match = regexp.match(ds)
        if match:
            return datetime.datetime(**{k: int(v) for (k, v) in match.groupdict().items()})
    return dateparser.parse(ds)

print([parse_date(d, regexps=[dmy_re]) for d in in_data])

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X