2

我必须以 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

4

2 回答 2

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 包含一个带有 DIAERESIS 的 LATIN SMALL LETTER A

>>> 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)
于 2012-06-27T22:03:08.467 回答
1

下面的代码解决了这个问题。

locale.setlocale(locale.LC_ALL, "deu_deu") # Locale name on Windows
datetime.strptime(dt.encode("iso-8859-16"), "%B %Y") 
于 2012-10-19T17:20:36.043 回答