验证日期(格式和值)

时间:2012-04-03 22:51:46

标签: python regex validation date if-statement

我读了这篇文章并且非常感兴趣:Validating date format using regular expression

所以我开始编写我自己的日期验证功能版本,我认为我很接近,但不完全,我想要一些建议和提示。我花了很多时间试图调整这个功能。

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")

问题1:当我想比较它是否有效时,还有其他方法(更好)做int(myString[3:5])吗?我觉得我的方法非常重复,这个函数必须要求00/00/0000,否则会破坏。所以这个功能在这个意义上并不是那么有用。特别是我处理00/01/1989的方式,只是简单地比较它们if 00

问题2:有很多if语句,我想知道有更好的方法来编写这个测试吗?

我想了解更多有关python编程的信息,我们将非常感谢任何建议或建议。非常感谢你。

5 个答案:

答案 0 :(得分:3)

与python中的许多内容一样,已经有了检查日期的基本功能。假设您不仅仅是将其作为学术练习,那么验证日期的最简单方法就是尝试创建它。

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

如果给datetime.date一个无效的日期,它会抱怨,例如:

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

答案 1 :(得分:1)

我知道学术练习有一些价值。我不会劝阻他们。

我还认为学习Python的很大一部分就是发现哪些问题已经解决了。我认为这有几个原因。首先,我认为重新发明轮子是浪费时间。我也有机会学习代码和解决问题的不同方法。最后,我认为长期解决方案不太可能对主题中的怪癖天真。

考虑到这一点,我推荐使用dateutil库。

答案 2 :(得分:1)

from dateutil.parser import *
parse("1993-09-01")
datetime.datetime(1993, 9, 1, 0, 0)

如果格式不正确,则会引发ValueError,您可以使用try .. catch来捕获它们,以便应用程序不会意外关闭。

答案 3 :(得分:1)

基于上面的一些答案,我写了这段简短的代码,以格式验证日期: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)

答案 4 :(得分:-1)

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!')