问题
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.
回答1:
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).
回答2:
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.
来源:https://stackoverflow.com/questions/28429512/python-parsing-date-and-find-the-correct-locale-setting