Python:匹配正确的datetime.datetime格式

时间:2014-08-02 16:03:08

标签: python python-2.7 datetime

在我的Python脚本中,我传递了一个带有--before参数的命令行选项date,即

myscript.py --before 2014-Aug-02

然后我需要将它读入我的变量中。我想支持几种可能的日期格式,即2014-Aug-022014-08-022014-08,...

在我的脚本中,我有以下构造来尝试匹配提供的日期格式,但它看起来非常难看。有更好,更优雅的方式吗?

if args.before:
    try:
        BEFORE = datetime.datetime.strptime(args.before[0], "%Y-%b-%d")
    except ValueError:
        try:
            BEFORE = datetime.datetime.strptime(args.before[0], "%Y-%b")
        except ValueError:
            try:
                 BEFORE = datetime.datetime.strptime(args.before[0], "%Y-%m-%d")
            except ValueError:
                try:
                    BEFORE = datetime.datetime.strptime(args.before[0], "%Y-%m")
                except ValueError:
                    try:
                        BEFORE = datetime.datetime.strptime(args.before[0], "%Y")
                    except ValueError:
                        print 'time data %s does not match format' % args.before[0]
                        exit(1)

3 个答案:

答案 0 :(得分:4)

我个人使用dateutil package来解析任意日期:

from dateutil.parser import parse as date_parse
try:
    BEFORE = date_parse(args.before[0])
except (TypeError, ValueError):
    print 'time data %s does not match format' % args.before[0]
    exit(1)

dateutil解析器可以处理您想要支持的所有格式以及更多。

但是,如果您不想安装外部依赖项,请创建支持格式的列表,并使用循环:

formats = ('%Y-%b-%d', '%Y-%b', '%Y-%m-%d', '%Y-%m', '%Y')
for format in formats:
    try:
        BEFORE = datetime.datetime.strptime(args.before[0], format)
        break
    except ValueError:
        pass
else:
    print 'time data %s does not match format' % args.before[0]
    exit(1)

一旦找到工作格式,循环就会以break结束,否则会到达else:循环的for套件,并打印错误消息。请注意,当您提前爆发时,> 执行循环的else:套件。

答案 1 :(得分:2)

acceptedFormats = ("%Y-%b-%d", "%Y-%b", "%Y-%m-%d", "%Y-%m", "%Y")
if args.before:
    for format in acceptedFormats:
        try:
            before = datetime.datetime.strptime(args.before[0], format)
            break
        except ValueError:
            pass
    else:
        print 'time data %s does not match format' % args.before[0]
        exit(1)

答案 2 :(得分:1)

我会做类似的事情:

def validate_date(datestr):
    for format in ("%Y-%b-%d", "%Y-%b", ...):
        try:
            return datetime.datetime.strptime(datestr, format)
        except ValueError:
            pass
    else:
        print 'time data %s does not match format' % datestr
        exit(1)

然后:

BEFORE = validate_date(args.before[0])

如果循环到达没有elsefor的结尾,break循环上的return块会运行,在这种情况下,只有在没有format时才会发生曾经成功解析过datestr


如果像@poke一样,你希望函数不是exit整个脚本(可能并不总是合适的话),你可以完全从函数中删除exit(1)(因此会隐式如果没有return None匹配,则format并执行以下操作:

BEFORE = validate_date(args.before[0])
if BEFORE is None:
    exit(1)

您也可以将整个else块移到函数外部,因为您可能并不总是希望它print