在python中,如何检查日期是否有效?

时间:2012-04-03 05:57:11

标签: python validation date time

我正在构建一种日历网络应用

我在HTML

中设置了以下表单
<form action='/event' method='post'>
Year ("yyyy"):  <input type='text' name='year' />
Month ("mm"):  <input type='text' name='month' />
Day ("dd"):  <input type='text' name='day' />
Hour ("hh"):  <input type='text' name='hour' />
Description:  <input type='text' name='info' />
             <input type='submit' name='submit' value='Submit'/>
</form>

然后,来自用户的输入被提交到一个樱桃服务器

我想知道,有没有办法检查用户输入的日期是否为有效日期?

显然我可以编写很多if语句,但有没有内置函数可以检查这个?

由于

10 个答案:

答案 0 :(得分:22)

您可以尝试

import datetime
datetime.datetime(year=year,month=month,day=day,hour=hour)

将消除诸如数月> 12,小时&gt;之类的事情。 23,不存在的leapdays(月份= 2在非闰年最多28次,否则29次,其他月份最多30或31天)(错误时抛出ValueError异常)

此外,您可以尝试将其与一些健全的上/下限进行比较。 例如:

datetime.date(year=2000, month=1,day=1) < datetime.datetime(year=year,month=month,day=day,hour=hour) <= datetime.datetime.now()

相关的上下限理性取决于您的需求。

编辑:请记住,这不会处理某些可能对您的应用程序无效的日期时间(生日,假期,外部营业时间等)。

答案 1 :(得分:22)

您可以尝试使用datetime并处理异常以确定有效/无效日期: 示例:http://codepad.org/XRSYeIJJ

import datetime
correctDate = None
try:
    newDate = datetime.datetime(2008,11,42)
    correctDate = True
except ValueError:
    correctDate = False
print(str(correctDate))

答案 2 :(得分:4)

使用datetime

例如。

>>> from datetime import datetime
>>> print datetime(2008,12,2)
2008-12-02 00:00:00
>>> print datetime(2008,13,2)

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    print datetime(2008,13,2)
ValueError: month must be in 1..12

答案 3 :(得分:1)

这是一个使用时间的解决方案。

import time
def is_date_valid(year, month, day):
    this_date = '%d/%d/%d' % (month, day, year)
    try:
        time.strptime(this_date, '%m/%d/%Y')
    except ValueError:
        return False
    else:
        return True

答案 4 :(得分:1)

您可以尝试使用datetime并处理异常以确定有效/无效日期:

import datetime

def check_date(year, month, day):
    correctDate = None
    try:
        newDate = datetime.datetime(year, month, day)
        correctDate = True
    except ValueError:
        correctDate = False
    return correctDate

#handles obvious problems
print(str(check_date(2008,11,42)))

#handles leap days
print(str(check_date(2016,2,29)))
print(str(check_date(2017,2,29)))

#handles also standard month length
print(str(check_date(2016,3,31)))
print(str(check_date(2016,4,31)))

gives

False
True
False
True
False

这是an answer by DhruvPathak的改进,作为编辑更有意义,但被拒绝为“This edit was intended to address the author of the post and makes no sense as an edit. It should have been written as a comment or an answer.

答案 5 :(得分:0)

该问题假定没有库的解决方案涉及“大量的if语句”,但没有:

def is_valid_date(year, month, day):
    day_count_for_month = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    if year%4==0 and (year%100 != 0 or year%400==0):
        day_count_for_month[2] = 29
    return (1 <= month <= 12 and 1 <= day <= day_count_for_month[month])

答案 6 :(得分:0)

y = int(input("Year: "))
m = int(input("Month: "))
d = int(input("Day: "))

if 0 <= y and 0 < m < 13 and 0 < d < 32: #Check whether date is under limit.

    if y % 4 == 0: # Every 4 year "Leap" year occures so checking...
        if m == 2: # In "Leap" year February has 29 days
            if d < 30:
                print("<Correct>")
            else:
                print("<Wrong>")

    elif m == 2: # But if it's not "Leap" year February will have 28 days
        if d < 29:
            print("<Correct>")
        else:
            print("<Wrong>")
    elif y % 4 != 0 and m != 2: # Otherwise print "Correct"
        print("<Correct>")

else:
    print("<Wrong>")

答案 7 :(得分:0)

您可以尝试使用dateutil.parser模块来简化日期解析:

from dateutil.parser import parse
def is_valid_date(date):
    if date:
        try:
            parse(date)
            return True
        except:
            return False
    return False

希望这会有所帮助。

答案 8 :(得分:0)

基于@codehia 答案,以下内容还允许检查日期的格式,并将字符串拆分为年、月、日 - 以上所有假设已经有年、月、日。

from dateutil.parser import parse
import string
p=print
space_punct_dict = dict((ord(punct), ' ') for punct in string.punctuation)
def is_valid_date_p(date):
    if date:
        try:
            date = date.translate(space_punct_dict)
            new_date = str(parse(date))[:10]
            year = new_date[:4]
            month = new_date[5:7]
            day = new_date[8:]
            p(year, month, day)
            return True, year, month, day
        except:
            p('invalid:', date)
            return False
    return False
year, month, day = 2021, 6, 1
  
is_valid_date_p(f'{month}/{day}/{year}')
is_valid_date_p(f'{month}.{day}.{year}')
is_valid_date_p(f'{month},{day},{year}')
is_valid_date_p(f'{month}/{day}/{year}')
is_valid_date_p(f'{month}-{day}-{year}')
is_valid_date_p(f'{month} {day} {year}')
p()
is_valid_date_p('12/1/20')
is_valid_date_p('12/31/20')
p()
is_valid_date_p('31/12/20')
is_valid_date_p('30/6/2020')
is_valid_date_p('2020/30/6')

输出:

2021 06 01

2021 06 01

2021 06 01

2021 06 01

2021 06 01

2021 06 01

2020 年 12 月 1 日

2020 年 12 月 31 日

2020 年 12 月 31 日

2020 06 30

无效:2020 30 6

答案 9 :(得分:-1)

所以,这是我的hacky解决方案来纠正提供的无效日期。这假定用户从提供第1-31天的通用html表单作为选项提交。主要问题是用户提供当月不存在的一天(9月31日之前)

def sane_date(year, month, day):
    # Calculate the last date of the given month
    nextmonth = datetime.date(year, month, 1) + datetime.timedelta(days=35)
    lastday = nextmonth.replace(day=1) - datetime.timedelta(days=1)
    return datetime.date(year, month, min(day, lastday.day))

class tests(unittest.TestCase):

    def test_sane_date(self):
        """ Test our sane_date() method"""
        self.assertEquals(sane_date(2000,9,31), datetime.date(2000,9,30))
        self.assertEquals(sane_date(2000,2,31), datetime.date(2000,2,29))
        self.assertEquals(sane_date(2000,1,15), datetime.date(2000,1,15))