【问题标题】:Validating date (both format and value)验证日期(格式和值)
【发布时间】:2012-04-03 22:51:46
【问题描述】:

我读了这篇文章并很感兴趣: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 编程的知识,任何建议或建议将不胜感激。非常感谢。

【问题讨论】:

    标签: python regex validation date if-statement


    【解决方案1】:

    像 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
    

    【讨论】:

    • 我想把它写成一个编程练习。我认为您的实现更简洁,我喜欢list(日期部分)中的吐痰,它使计数不那么混乱。我会查找try:except,似乎我应该使用它而不是if 语句。谢谢你。 datetime.date() 会做我写的一切吗?
    • 是的,在 python 中处理异常而不是试图预测它们通常被认为更干净。您还应该查看except ValueError: 的含义,它允许您针对某些类别的错误。 datetime.date() 创建一个日期对象,如果传递给它的年、月或日的无效值将引发异常。
    • 我想我没有选择最佳实践问题,但感谢您教我使用try:except: ValueError。谢谢。
    【解决方案2】:

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

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

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

    【讨论】:

    • 我明白了,感谢关于 dateutil 模块的建议!我只是想练习我的python代码:)
    【解决方案3】:
    from dateutil.parser import *
    parse("1993-09-01")
    datetime.datetime(1993, 9, 1, 0, 0)
    

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:
        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!')
        

        【讨论】:

          猜你喜欢
          • 2017-04-04
          • 2016-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-09-01
          • 1970-01-01
          • 2021-01-17
          • 2011-06-29
          相关资源
          最近更新 更多