2012-04-03 18 views
1

を検証私はこれを読んで、本当に興味を持った私は、日付の検証機能の私自身のバージョンを書き始め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でのプログラミングについてもっと学びたいと思います。どんな提案や助言も大歓迎です。どうもありがとうございました。

答えて

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 
+0

私はこれをプログラミング演習として書いています。私はあなたの実装がより洗練されていると思う、私は 'list'(dateparts)で拍手が好きです。私は 'try:' 'except'を調べますが、' if'文の代わりに使うべきだと思われます。ありがとうございました。 'datetime.date()は私が書いたすべてを行い、それ以上のことをしますか? – George

+0

はい、一般的に、Pythonでは例外を処理するのではなく、例外を処理することが一般的です。特定のクラスのクラスを対象とすることを可能にする 'except ValueError:'の意味を見てください。日付時刻。date()は日付オブジェクトを作成します。年、月、または日に無効な値を渡すと例外が発生します。 – SpliFF

+0

私はベストプラクティスの問題を選択しなかったと思うが、 'try:'と 'except:ValueError'を使うように教えてくれてありがとう。ありがとうございました。 – George

1

私は学術的な演習では、いくつかの価値があると理解しています。私は彼らを落胆させないだろう。

私はまた、Pythonを学ぶ上で大きな問題は、どの問題がすでに解決されているかを発見することです。このように考える理由はいくつかあります。まず、ホイールを再発明するのは時間の無駄だと思います。また、問題を解決するためのコードとさまざまなアプローチを学ぶチャンスがあります。最後に、私は長年にわたる解決策が、主題の癖についてあまり知られていない可能性が低いと思います。

これを念頭に置いて、私はdateutilライブラリをお勧めします。アプリケーションが予期せず終了しないように形式が適切でない場合

+0

私はdateutilモジュールの提案に感謝します!私はちょうど私のpythonコードを練習しようとしています:) – George

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

、それはValueErrorを送出します、あなたはそれらをキャッチする...キャッチを試みることができます。

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