繁体   English   中英

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

[英]In python, how to check if a date is valid?

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

我已经在 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>

来自用户的输入然后被提交到一个cherrypy服务器中

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

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

谢谢

你可以尝试做

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

这将消除诸如月 > 12 、小时 > 23、不存在的闰日(月 = 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()

相关的上限和下限取决于您的需要。

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

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

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

这个问题假设没有库的解决方案涉及“大量的 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])

使用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

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

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

您可以尝试使用 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)))

False
True
False
True
False

这是DhruvPathak 对答案的改进,作为编辑更有意义,但被拒绝,因为“此编辑旨在解决帖子的作者,作为编辑没有意义。它应该写为评论或回答。

您可以尝试使用dateutil.parser模块来更轻松地解析日期:

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

希望这可以帮助。

所以,这是我纠正提供的无效日期的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))
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>")

基于@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 01

2020 12 31

2020 12 31

2020 06 30

无效:2020 30 6

暂无
暂无

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

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