2013-06-01 53 views
63

我有一个Python方法,它接受日期输入为字符串如何在Python中验证日期字符串格式?

如何添加验证以确保传递给方法的日期字符串在ffg中。格式:

'YYYY-MM-DD' 

,如果它不是,方法应该提高某种错误

+2

这可能是更Python(请求原谅,而不是许可)没有在所有检查,并捕捉发生的任何由此产生的异常。 – Thomas

+0

相关:[在python中,如何检查日期是否有效?](http://stackoverflow.com/q/9987818/55075) – kenorb

回答

101
>>> import datetime 
>>> def validate(date_text): 
    try: 
     datetime.datetime.strptime(date_text, '%Y-%m-%d') 
    except ValueError: 
     raise ValueError("Incorrect data format, should be YYYY-MM-DD") 


>>> validate('2003-12-23') 
>>> validate('2003-12-32') 

Traceback (most recent call last): 
    File "<pyshell#20>", line 1, in <module> 
    validate('2003-12-32') 
    File "<pyshell#18>", line 5, in validate 
    raise ValueError("Incorrect data format, should be YYYY-MM-DD") 
ValueError: Incorrect data format, should be YYYY-MM-DD 
+0

有没有办法做到这一点,没有尝试/除外?当异常被引发和捕获时,Python往往会显着减速。 – chiffa

+1

@chiffa你可以匹配一个日期格式的正则表达式,但不推荐使用它,因为它不够健壮,异常更清晰。你确定日期验证是你的瓶颈吗? – jamylak

+0

不是真的,所以最后我会将throw-except构造包装在一个函数中。我只是感到惊讶,没有布尔返回验证函数会触发日期时间库中的异常抛出。 – chiffa

34

Python dateutil库是专门为这个(及以上)。它会自动将它转换为datetime对象,如果它不能,则会引发ValueError

举个例子:

>>> from dateutil.parser import parse 
>>> parse("2003-09-25") 
datetime.datetime(2003, 9, 25, 0, 0) 

这就提出了一个ValueError如果日期的格式不正确:

>>> parse("2003-09-251") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/jacinda/envs/dod-backend-dev/lib/python2.7/site-packages/dateutil/parser.py", line 720, in parse 
    return DEFAULTPARSER.parse(timestr, **kwargs) 
    File "/Users/jacinda/envs/dod-backend-dev/lib/python2.7/site-packages/dateutil/parser.py", line 317, in parse 
    ret = default.replace(**repl) 
ValueError: day is out of range for month 

dateutil也是非常有用的,如果你开始需要解析其他格式的未来,因为它可以智能处理大多数已知格式,并允许您修改规格:dateutil parsing examples

它也处理时区,如果你需要的话。

更新基于意见parse还接受关键字参数dayfirst控制一天或一个月是否有望先来,如果日期是模糊的。这默认为False。例如。

>>> parse('11/12/2001') 
>>> datetime.datetime(2001, 11, 12, 0, 0) # Nov 12 
>>> parse('11/12/2001', dayfirst=True) 
>>> datetime.datetime(2001, 12, 11, 0, 0) # Dec 11 
+0

它可能接受太多例如,'parse('13/12/2001')'是“12月13日”,但是“解析”('11/12/2001')'是“11月12日”(第一个结果暗示“12月11日”)。 – jfs

+0

'parse'实际上需要一个'dayfirst'关键字参数,它允许你控制这个参数。 '解析('11/12/2001',dayfirst = True)'将返回“12月11日”。 dateutil的默认值是'dayfirst = False' – Jacinda

+0

你错过了'datetutil.parser.parse()'接受太多时间格式的问题(你可以找到其他含有模糊输入的例子)。如果你想验证你的输入是YYYY-MM-DD格式,那么'parse()'函数是错误的工具。 – jfs

11
from datetime import datetime 

datetime.strptime(date_string, "%Y-%m-%d") 

..this提出了一个ValueError如果它接收到不兼容的格式。

..如果你处理的日期和时间很多(在日期时间对象的意义上,而不是unix timestamp浮点数),查看pytz模块和storage/db是一个好主意,以UTC存储所有内容。

+2

你的速度更快,我自己也发布了它(http://ideone.com/vuxDDf)。给予好评。 – Tadeck

+0

..只是在发布之后才发现它,并且恰好今天已经使用了datetime对象。 –

6

我觉得完全验证功能应该是这样的:

from datetime import datetime 

def validate(date_text): 
    try: 
     if date_text != datetime.strptime(date_text, "%Y-%m-%d").strftime('%Y-%m-%d'): 
      raise ValueError 
     return True 
    except ValueError: 
     return False 

执行只是

datetime.strptime(date_text, "%Y-%m-%d") 

是不够的,因为strptime方法不检查的那个月和日月份是零填充十进制数字。例如

datetime.strptime("2016-5-3", '%Y-%m-%d') 

将被执行而没有错误。

+1

“你在技术上是正确的 - 最好的一种正确的。”我需要确保我的字符串。 – delrocco

0

这是最简单的方法:

date = datetime.now() 
date = date.strftime('%Y-%m-%d_%H-%M-%S.jpg') 
+0

所提问题的日期格式错误 –