简体   繁体   English

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

[英]Python: match correct datetime.datetime format

In my Python script, I pass a commandline option --before with a date argument, ie 在我的Python脚本中,我传递了一个命令行选项--before并带有一个date参数,即

myscript.py --before 2014-Aug-02

I then need to read it into my variable. 然后,我需要将其读入我的变量。 I want to support several possible date formats, ie 2014-Aug-02 , 2014-08-02 , 2014-08 , ... 我想支持几种可能的日期格式,即2014-Aug-022014-08-022014-08 ,...

In my script, I have following construct to try to match the provided date format, but it looks to me very ugly. 在我的脚本中,我具有以下结构来尝试匹配提供的日期格式,但是在我看来,它非常丑陋。 Is there a better, more elegant way to do it? 有没有更好,更优雅的方法呢?

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)

I'd personally use the dateutil package to parse arbitrary dates: 我个人将使用dateutil来解析任意日期:

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)

The dateutil parser can handle all formats you want to support plus more. dateutil解析器可以处理您要支持的所有格式以及其他格式。

But if you don't want to install an external dependency, then create a list of supported formats, and use a loop: 但是,如果您不想安装外部依赖项,请创建受支持格式的列表 ,然后使用循环:

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)

As soon as a working format is found, the loop is ended with a break , otherwise the else: suite of the for loop is reached, and an error message is printed. 一旦找到一种有效的格式,循环就以break结束,否则将到达else: for循环套件,并显示一条错误消息。 Note that an else: suite of a loop is not executed when you break out early. 请注意,在您早点休息时不会执行else:循环套件。

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)

I would do something like: 我会做类似的事情:

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)

Then: 然后:

BEFORE = validate_date(args.before[0])

The else block on a for loop runs if the loop reaches an end without break or return , which in this case only happens if no format ever successfully parses the datestr . 如果循环到达结束而没有breakreturn ,则for循环上的else块将运行,在这种情况下,只有在没有format成功解析datestr才会发生。


If, like @poke, you prefer to have the function not exit the whole script (as may not always be appropriate), you can remove exit(1) from the function entirely (which will therefore implicitly return None if no format matches) and do something like: 如果像@poke一样,您希望函数不exit整个脚本(可能并不总是合适),则可以从函数中完全删除exit(1) (因此,如果没有format匹配,则隐式return None ),做类似的事情:

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

You could alternatively move the whole else block outside the function, as you might not always want it to print anything, either. 您也可以将整个else块移到函数外部,因为您可能也不总是希望它print任何内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM