10

Dateutil 是解析字符串格式日期的好工具。例如

from dateutil.parser import parse
parse("Tue, 01 Oct 2013 14:26:00 -0300")

返回

datetime.datetime(2013, 10, 1, 14, 26, tzinfo=tzoffset(None, -10800))

然而,

parse("Ter, 01 Out 2013 14:26:00 -0300") # In portuguese

产生此错误:

ValueError: unknown string format

有人知道如何让 dateutil 了解语言环境吗?

4

4 回答 4

4

据我所知, dateutil 不知道语言环境(还没有!)。

我可以想到三个替代建议:

  • 日期和月份名称是硬编码的dateutil.parser(作为parserinfo类的一部分)。您可以将 parserinfo 子类化,并将这些名称替换为葡萄牙语的适当名称。

  • 修改 dateutil 以根据用户的区域设置获取日期和月份名称。所以你可以做类似的事情

    import locale
    locale.setlocale(locale.LC_ALL, "pt_PT")
    
    from dateutil.parser import parse
    parse("Ter, 01 Out 2013 14:26:00 -0300")
    

    我已经启动了一个 fork,它从calendar模块中获取名称(这是区域设置感知的)来处理这个问题:https ://github.com/alexwlchan/dateutil

    现在它适用于葡萄牙语(或似乎适用),但在我向主分支提交补丁之前,我想多考虑一下。特别是,如果它面对西欧语言中未使用的字符,可能会发生奇怪的情况。我还没有测试过这个。(见https://stackoverflow.com/a/8917539/1558022

  • 如果你没有绑定到 dateutil 模块,你可以使用 datetime 代替,它已经是语言环境感知的:

    from datetime import datetime, date
    import locale
    
    locale.setlocale(locale.LC_ALL, "pt_PT")
    datetime.strptime("Ter, 01 Out 2013 14:26:00 -0300",
                      "%a, %d %b %Y %H:%M:%S %z")
    

    (请注意,在 datetime%z中并不始终支持该令牌。)

于 2015-04-08T09:28:51.193 回答
3

您可以使用给定格式PyICU解析本地化的日期/时间字符串:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from datetime import datetime
import icu  # PyICU

df = icu.SimpleDateFormat(
               'EEE, dd MMM yyyy HH:mm:ss zzz', icu.Locale('pt_BR'))
ts = df.parse(u'Ter, 01 Out 2013 14:26:00 -0300')
print(datetime.utcfromtimestamp(ts))
# -> 2013-10-01 17:26:00 (UTC)

它适用于 Python 2/3。它不会修改全局状态(语言环境)。

如果您的实际输入时间字符串不包含明确的 utc 偏移量,那么您应该明确指定 ICU 使用的时区,否则您可能会得到错误的结果(ICU 和 datetime 可能使用不同的时区定义)。

如果您只需要支持 Python 3 并且您不介意设置语言环境,那么您可以datetime.strptime()按照@alexwlchan 的建议使用:

#!/usr/bin/env python3
import locale
from datetime import datetime

locale.setlocale(locale.LC_TIME, "pt_PT.UTF-8")
print(datetime.strptime("Ter, 01 Out 2013 14:26:00 -0300",
                        "%a, %d %b %Y %H:%M:%S %z")) # works on Python 3.2+
# -> 2013-10-01 14:26:00-03:00
于 2015-04-09T20:50:41.243 回答
1

calendar模块已经有许多语言的常量。我认为最好的解决方案是使用这些常量从 dateutil 自定义解析器。这是一个简单的解决方案,适用于许多语言。我没有测试很多,所以谨慎使用。

创建一个模块localeparseinfo.py和子类parser.parseinfo

import calendar
from dateutil import parser
    
class LocaleParserInfo(parser.parserinfo):
    WEEKDAYS = zip(calendar.day_abbr, calendar.day_name)
    MONTHS = list(zip(calendar.month_abbr, calendar.month_name))[1:]

现在您可以使用新的 parseinfo 对象作为dateutil.parser.

In [1]: import locale;locale.setlocale(locale.LC_ALL, "pt_BR.utf8")
In [2]: from localeparserinfo import LocaleParserInfo                                   

In [3]: from dateutil.parser import parse                                                

In [4]: parse("Ter, 01 Out 2013 14:26:00 -0300", parserinfo=PtParserInfo())              
Out[4]: datetime.datetime(2013, 10, 1, 14, 26, tzinfo=tzoffset(None, -10800))

它解决了我的问题,但请注意,对于所有可能的日期和时间,这是一个不完整的解决方案。看看 dateutil parser.py,特别是parserinfo类变量。看看 HMS 变量和其他变量。您可能可以使用日历模块中的其他常量。

您甚至可以将语言环境字符串作为参数传递给 parserinfo 类。

于 2020-06-25T18:15:31.133 回答
0
from dateutil.parser import parse
parse("Ter, 01 Out 2013 14:26:00 -0300",fuzzy=True)

结果:

datetime.datetime(2013, 1, 28, 14, 26, tzinfo=tzoffset(None, -10800))
于 2019-01-28T05:36:57.737 回答