使用Python strptime解析月份名称时的UnicodeEncodeError

时间:2012-06-27 21:48:14

标签: python datetime unicode locale

我必须以MONTH YEAR格式解析德语日期,其中MONTH是月份的全名。我在Python中设置了适当的语言环境,然后尝试用strptime解析日期。例如:

locale.setlocale(locale.LC_ALL, "deu_deu") # Locale name on Windows
datetime.strptime(dt, "%B %Y")

在遇到名称中带有非ASCII字符的月份时,我得到UnicodeEncodeError。日期是从通过Web服务提供的XML文件中提取的。有没有办法可以将我的日期字符串转换为适用于strptime

的日期字符串

修改

datetime.strptime(dt.encode("iso-8859-16"), "%B %Y") 

的工作。

2 个答案:

答案 0 :(得分:3)

没有答案,只是一个测试(虽然在Unix上):

>>> import locale, datetime
>>> locale.setlocale(locale.LC_ALL, "de_de")
>>> datetime.datetime.strptime("März 2012", "%B %Y")
datetime.datetime(2012, 3, 1, 0, 0)

以上工作符合预期。现在模拟unicode作为输入 - März包含LATIN SMALL LETTER A WITH DIAERESIS

>>> datetime.datetime.strptime("M\u00E4rz 2012", "%B %Y"))
...
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' ...

使用内置的unicode函数可以实现

>>> datetime.datetime.strptime(unicode("März 2012", "utf-8"), "%B %Y")
...
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' ....

现在尝试使用适当的编码:

>>> datetime.datetime.strptime(u"M\u00E4rz 2012".encode('utf-8'), "%B %Y")
datetime.datetime(2012, 3, 1, 0, 0)

同样,这不是在Windows上 - 所以不是一个真正的答案,但它可能包含一个提示。


只是为了进一步研究 - 一个场景,其中一个处理数据外部源(在本例中使用JSON,用于XML的YMMV):

我认为一个合适的JSON编码器会给你unicode,RFC4627似乎暗示了这一点:

  

任何角色都可能被转义。如果角色在基本      多语言平面(U + 0000到U + FFFF),然后它可能是      表示为六个字符的序列:反向固相,然后      用小写字母u,后跟四个十六进制数字      编码角色的代码点。十六进制字母A虽然      F可以是大写或小写。

所以用python模拟它(没有人会用这种方式解析JSON,这只是一个模拟):

>>> import json
>>> s = json.dumps({"date" : "März 2012"}).split(":")[1].replace(
        '"', "").replace("}", "").strip().decode("unicode_escape")
>>> # and sure enough ...
>>> datetime.datetime.strptime(s, "%B %Y")
...
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4 ...

>>> # and again, with the right encoding ...
>>> datetime.datetime.strptime(s.encode("utf-8"), "%B %Y")
datetime.datetime(2012, 3, 1, 0, 0)

答案 1 :(得分:1)

以下代码解决了这个问题。

locale.setlocale(locale.LC_ALL, "deu_deu") # Locale name on Windows
datetime.strptime(dt.encode("iso-8859-16"), "%B %Y")