Reputation: 386
I have the following date string: '3 févr. 2015 14:26:00 CET'
datetime.datetime.strptime('03 févr. 2015 14:26:00', '%d %b %Y %H:%M:%S')
Parsing this failed with the error:
ValueError: time data '03 f\xc3\xa9vr. 2015 14:26:00' does not match format '%d %b %Y %H:%M:%S'
I tried to loop over all locales with locale.locale_alias
:
for l in locale.locale_alias:
try:
locale.setlocale(locale.LC_TIME, l)
print l,datetime.datetime.strptime('03 févr. 2015 14:26:00', '%d %b %Y %H:%M:%S')
break
except Exception as e:
print e
but I was not able to find the correct one.
Upvotes: 3
Views: 4922
Reputation: 414475
To parse localized date/time string using ICU date/time format:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from datetime import datetime
import icu # PyICU
import pytz # $ pip install pytz
tz = icu.ICUtzinfo.getDefault() # any ICU timezone will do here
df = icu.DateFormat.createDateTimeInstance(icu.DateFormat.MEDIUM,
icu.DateFormat.MEDIUM,
icu.Locale.getFrench())
df.setTimeZone(tz.timezone)
ts = df.parse(u'3 févr. 2015 14:26:00 CET') #NOTE: CET is ignored
naive_dt = datetime.fromtimestamp(ts, tz).replace(tzinfo=None)
dt = pytz.timezone('Europe/Paris').localize(naive_dt, is_dst=None)
print(dt) # -> 2015-02-03 14:26:00+01:00
df.applyPattern()
could be used to set a different date/time pattern (df.toPattern()
) or you could use icu.SimpleDateFormat
to get df
from the format and the locale directly.
It is necessary to use an explicit ICU timezone (so that df.parse()
and .fromtimestamp()
could use the same utc offset) because icu
and datetime
may use different timezone definitions.
pytz
is used here, to get a proper UTC offset for past/future dates (some timezones may have different utc offsets in the past/future including reasons unrelated to DST transitions).
Upvotes: 4
Reputation: 1123052
Your format includes a dot for the abbreviation and uses 4 characters:
'03 févr. 2015 14:26:00'
# ^^
but if I set the locale to fr_FR
and format the same date:
>>> import locale, datetime
>>> locale.setlocale(locale.LC_TIME, ('fr', 'UTF-8'))
'fr_FR.UTF-8'
>>> datetime.datetime(2015, 2, 3, 14, 26).strftime('%d %b %Y %H:%M:%S')
'03 f\xc3\xa9v 2015 14:26:00'
>>> print datetime.datetime(2015, 2, 3, 14, 26).strftime('%d %b %Y %H:%M:%S')
03 fév 2015 14:26:00
You'll notice only 3 characters are used and no dot is included. Parsing the date only supports the same 3 character abbreviations:
>>> datetime.datetime.strptime('03 fév 2015 14:26:00', '%d %b %Y %H:%M:%S')
datetime.datetime(2015, 2, 3, 14, 26)
You could try the parsedatetime
library instead, others have had success parsing French dates with that tool.
Upvotes: 0