I read this and got really interested: Validating date format using regular expression
so I started writing my own version of the date validation function, I think I am close, but not quite, and I would like some suggestion as well as tips. I have spend a lot of time trying to tweak the function.
import re
import datetime
# Return True if the date is in the correct format
def checkDateFormat(myString):
isDate = re.match('[0-1][0-9]\/[0-3][0-9]\/[1-2][0-9]{3}', myString)
return isDate
# Return True if the date is real date, by real date it means,
# The date can not be 00/00/(greater than today)
# The date has to be real (13/32) is not acceptable
def checkValidDate(myString):
# Get today's date
today = datetime.date.today()
myMaxYear = int(today.strftime('%Y'))
if (myString[:2] == '00' or myString[3:5] == '00'):
return False
# Check if the month is between 1-12
if (int(myString[:2]) >= 1 or int(myString[:2]) <=12):
# Check if the day is between 1-31
if (int(myString[3:5]) >= 1 or int(myString[3:2]) <= 31):
# Check if the year is between 1900 to current year
if (int(myString[-4:]) <= myMaxYear):
return True
else:
return False
testString = input('Enter your date of birth in 00/00/0000 format: ')
# Making sure the values are correct
print('Month:', testString[:2])
print('Date:', testString[3:5])
print('Year:', testString[-4:])
if (checkDateFormat(testString)):
print('Passed the format test')
if (checkValidDate(testString)):
print('Passed the value test too.')
else:
print('But you failed the value test.')
else:
print("Failed. Try again")
Question 1: Is there other way (better) to do int(myString[3:5])
when I want to compare if it is valid? I feel my method is very repetitive, and this function must require 00/00/0000, otherwise it will break. So the function isn't all that useful in that sense. Especially the way I handle my 00/01/1989
, it is just simply comparing if
they are indeed 00
.
Question 2: There are many if
statement, I wonder are there better way to write this test?
I would like to learn more about programming in python, any suggestion or advice will be greatly appreciated. Thank you very much.
Like many things in python there's already underlying capabilities to check dates. Assuming you aren't just doing this as an academic exercise the most straightforward way to validate a date is to try and create it.
import datetime
minyear = 1900
maxyear = datetime.date.today().year
mydate = '12/12/2000'
dateparts = mydate.split('/')
try:
if len(dateparts) != 3:
raise ValueError("Invalid date format")
if int(dateparts[2]) > maxyear or int(dateparts[2]) < minyear:
raise ValueError("Year out of range")
dateobj = datetime.date(int(dateparts[2]),int(dateparts[1]),int(dateparts[0]))
except:
// handle errors
if datetime.date is given an invalid date it will complain, eg:
datetime.date(2000,45,23)
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
datetime.date(2000,45,23)
ValueError: month must be in 1..12
except ValueError:
which allows you to target certain classes of errors. datetime.date() creates a date object, if you pass it invalid values for year, month or day it will raise an exception - SpliFF 2012-04-03 23:23
try:
and except: ValueError
. Thank you - George 2012-04-04 00:05
I understand there's some value in academic exercises. I wouldn't discourage them.
I also think a big part of learning Python is discovering which problems have already been solved. There are several reasons I think this way. First, I think it's a waste of time to re-invent the wheel. Also I get a chance to study code and different approaches to solving problems. Finally, I think a long-standing solution is less likely to be naive about quirks in the subject matter.
With that in mind, I recommend the dateutil library.
from dateutil.parser import *
parse("1993-09-01")
datetime.datetime(1993, 9, 1, 0, 0)
If the format is not proper, then it will raise a ValueError, you can use try.. catch to catch them so that the application does not close unexpectedly.
Based on some answers above I wrote this short piece of code which validates date to in the format: DD/MM/YYYY.
date = "29/02/2016"
min_year = 1900
max_year = min_year + 200
days_31 = ['01', '03', '05', '07', '08', '10', '12']
days_30 = ['04', '06', '10', '11']
days_28 = ['02']
month_dict = {'01':'January',
'02':'February',
'03':'March',
'04':'April',
'05':'May',
'06':"June",
'07':'July',
'08':'August',
'09':'September',
'10':'October',
'11':'November',
'12':'December'}
def validate(day, month, leap_year_or_not):
if leap_year_or_not:
max_day = 29
else:
max_day=28
if month in days_28:
if day > max_day:
print "Invalid day: %s for month %s" %(day, month_dict[month])
return False
else:
return True
elif month in days_30:
if day > 30:
print "Invalid day: %s for month %s" %(day, month_dict[month])
return False
else:
return True
elif month in days_31:
if day <= 31:
return True
else:
print "Invalid day: %s for month %s" %(day, month_dict[month])
return False
else:
print "Invalid month:%s, Invalid day:%s" %(month, day)
return False
if len(date)!= 10:
print "Invalid Format. Please enter date in DD/MM/YYYY"
else:
day, month, year = date.split("/")
if len(day) != 2:
print "Length of day in not 2. Please enter day as 01 for first!"
elif len(month) != 2:
print "Length of month in not 2. Please enter month as 01 for January!"
elif len(year) != 4:
print "Length of year in not 4. Please enter year as 2001!"
else:
day=int(day)
month=int(month)
year=int(year)
if day < 1 or day > 31:
print "Day %s is not in range [1-31]" %str(day)
else:
if month < 1 or month > 12:
print "Month %s is not in range [1-12]" %str(month)
else:
if year < min_year or year > max_year:
print "Year is not in range [%s-%s]" (str(min_year), str(max_year))
else:
if year%4 == 0:
leap_year = True
else:
leap_year = False
valid_day_month = validate(day, str(month).zfill(2), leap_year)
import time
import datetime
self.date = raw_input('Enter the date to travel in (yyyy-mm-dd) format: ')
try:
valid_date = time.strptime(self.date, '%Y-%m-%d')
today_date=str(datetime.date.today())
if self.date<today_date:
print "date got over"
else:
print " "
except ValueError:
print('Invalid date!')
list
(dateparts), it makes the counting less messy. I will look up thetry:
except
, seems like it is what I should use instead ofif
statements. Thank you.And does the
datetime.date()
do everything I write and then more - George 2012-04-03 23:18