我正在构建一种日历网络应用程序
我已经在 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])
您可以尝试使用
dateutil.parser
模块来更轻松地进行日期解析:
from dateutil.parser import parse, ParserError
def is_valid_date(date):
if not date:
return False
try:
parse(date)
return True
except ParserError:
return False
希望这有帮助。
使用
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 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 的答案的改进,作为编辑更有意义,但它被拒绝为“此编辑旨在向帖子的作者讲话,作为编辑没有任何意义。它应该写成评论或答案。”
导入时间 def is_date_valid(年、月、日): this_date = '%d/%d/%d' %(月、日、年) 尝试: time.strptime(this_date, '%m/%d/%Y') 除了值错误: 返回错误 别的: 返回真
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>")
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日
deteutil.parser
,它可以在解析日期时简化代码。通过此代码片段,您还可以捕获无效日期:
import dateutil.parser
input_date = '2022-06-30'
try:
result_date = dateutil.parser.parse(input_date, dayfirst=True).strftime('%Y-%m-%d')
except dateutil.parser._parser.ParserError as ex:
print(ex) # handle the exception from here on
其中 strftime('%Y-%m-%d')
部分固定输出格式。如果没有该方法,即仅
result_date = dateutil.parser.parse(input_date, dayfirst=True)
,它会返回一个日期时间对象。可选的
dayfirst=True
会省略像
3/6/2022
这样不明确的日期,将被解析为 6 月 3 日(而不是 3 月 6 日)。让我们尝试一些不同格式的输入,甚至添加一些垃圾:
multiple_inputs = ['2022-06-30', '30/6/2022', '30 06 2022', '3/6/2022',
'2022-06-31', '2022-15-30', '', 'garbage']
for input_date in multiple_inputs:
try:
result_date = dateutil.parser.parse(input_date, dayfirst=True).strftime('%Y-%m-%d')
print(f'Valid date: {result_date}')
except dateutil.parser._parser.ParserError as ex:
print(ex)
这给出了:
Valid date: 2022-06-30
Valid date: 2022-06-30
Valid date: 2022-06-30
Valid date: 2022-06-03
day is out of range for month: 2022-06-31
month must be in 1..12: 2022-15-30
String does not contain a date:
Unknown string format: garbage