有没有可能让dateutil.parser.parse只解析iso8601字符串并抛出其他格式的错误

时间:2017-09-01 16:19:56

标签: python-3.6 python-dateutil

我正在使用dateutil.parser。我只想解析一个包含日期,时间和时区信息的日期字符串。

e.g。我只想接受有效日期为“2014-11-11T18:28:50.588Z”。如果用户已通过“2013-12-11”(这也是dateutil的有效日期),那么我想抛出错误。

P.S - 我知道我可以使用正则表达式,但我希望看看我是否可以使用dateutil库

1 个答案:

答案 0 :(得分:0)

不,dateutil.parser无法做到这一点。 dateutil的解析器主要用于处理看起来像日期的任何,目前只有最少的自定义选项。

需要注意的一点是,2013-12-112014-11-11T18:28:50.588Z都是有效的ISO-8601日期,所以即使您有一条规则说“仅解析ISO-8601日期”,它仍然会捕获这两个。

我的推荐一般是如果您知道日期字符串的确切格式,则应使用strptime,例如:

from datetime import datetime
from dateutil import tz

def parse_datetime(dt_str):
    return datetime.strptime(dt_str, '%Y-%m-%dT%H:%M:%S.%fZ').replace(tzinfo=tz.tzutc())


if __name__ == "__main__":
    print(parse_datetime("2014-11-11T18:28:50.588Z"))

    try:
        parse_datetime("2013-12-11")
    except ValueError:
        print("Failed to parse!")

# Returns:
#
# 2014-11-11 18:28:50.588000+00:00
# Failed to parse!

如果您想要更灵活一点,并且允许没有Z扩展名的日期,或者没有浮点数,我发现最快的方法是if / elif用于检查字符串长度的块。我将如何做到这一点:

from datetime import datetime
from dateutil import tz

def parse_datetime(dt_str):
    tzinfo = None
    if dt_str.endswith('Z'):
        tzinfo = tz.tzutc()
        dt_str = dt_str[:-1]

    if len(dt_str) == 23:
        fmt =  '%Y-%m-%dT%H:%M:%S.%f'
    elif len(dt_str) == 19:
        fmt = '%Y-%m-%dT%H:%M:%S'
    else:
        raise ValueError("Unknown format for date: {}".format(dt_str))

    return datetime.strptime(dt_str, fmt).replace(tzinfo=tzinfo)


if __name__ == "__main__":
    print(parse_datetime("2014-11-11T18:28:50.588"))
    print(parse_datetime("2014-11-11T18:28:50.588Z"))
    print(parse_datetime("2014-11-11T18:28:50"))
    print(parse_datetime("2014-11-11T18:28:50Z"))    

    try:
        parse_datetime("2013-12-11")
    except ValueError as e:
        print(e)

# Returns:
#
# 2014-11-11 18:28:50.588000
# 2014-11-11 18:28:50.588000+00:00
# 2014-11-11 18:28:50
# 2014-11-11 18:28:50+00:00
# Unknown format for date: 2013-12-11