2011-09-09 137 views
4

我試圖想出一種方法來以儘可能最好的pythonic方式來實現這一點。現在我能想到的唯一方法就是強行推行它。Python,日期驗證

用戶輸入以下列方式中的一個的日期(通過命令行)(來自./mypy.py日期=「20110909.00 23」)

date='20110909' 
date='20110909.00 23' 
date='20110909.00 20110909.23' 

所有三個實施例應具有相同的結果,如果它填充一個列表(我可以排序),如

['20110909.00', '20110909.23] 

,甚至兩個獨立的排序變量,但在所有情況下,它的YYYYMMDD.HH,並且需要確保它確實是一個沒關係日期而不是文字。

任何想法?

謝謝。

+++++編輯+++++ 插上這個之後,我想我需要先做很多日期檢查/操作。這似乎都很好。除了最後我通過日期驗證運行列表,並且每次都失敗 - 即使它應該通過。

./test.py日期(I與啓動它)= '20110909.00 23'

(或日期的任何變化 - 即日期= '20 22' 或日期= '20110909' 或日期=」 20110909.00 23' 等)

import sys, re, time, datetime 

now = datetime.datetime.now() 
tempdate=[] 
strfirstdate=None 
strtempdate=None 

temparg2 = sys.argv 
del temparg2[0] 
tempdate = temparg2[0].replace('date=','') 
date = tempdate.split(' '); 

tempdate=[] 
date.sort(key=len, reverse=True) 
result = None 

# If no date is passed then create list according to [YYMMDD.HH, YYMMDD.HH] 
if date[0] == 'None': 
    tempdate.extend([now.strftime('%Y%m%d.00'), now.strftime('%Y%m%d.%H')]) 


# If length of date list is 1 than see if it is YYMMDD only or HH only, and create list according to [YYMMDD.HH, YYMMDD.HH] 
elif len(date) == 1: 
    if len(date[0]) == 8: 
     tempdate.extend([ date[0] + '.00', date[0] + '.23']) 
    elif len(date[0]) == 2: 
     tempdate.extend([now.strftime('%Y%m%d') + '.' + date[0], now.strftime('%Y%m%d') + '.' + date[0]]) 
    else: 
     tempdate.extend([date[0], date[0]]) 


# iterate through list, see if value is YYMMDD only or HH only or YYYYMMDD.HH, and create list accoring to [YYYYMMDD.HH, YYYYMMDD.HH] - maximum of 2 values 
else: 
    for _ in range(2): 
     if len(date[_]) == 8: 
      strfirstdate = date[0] 
      tempdate.append([ date[_] + '.00']) 
     elif len(date[_]) == 2: 
      if _ == 0: # both values passed could be hours only 
       tempdate.append(now.strftime('%Y%m%d') + '.' + date[_]) 
      else: # we must be at the 2nd value passed. 
       if strfirstdate == None: 
        tempdate.append(now.strftime('%Y%m%d') + '.' + date[_]) 
       else: 
        tempdate.append(strfirstdate + '.' + date [_]) 
     else: 
      strfirstdate = date[0][:8] 
      tempdate.append(date[_]) 

tempdate.sort() 


for s in tempdate: 
    try: 
     result = datetime.datetime.strptime(s, '%Y%m%d.%H') 
    except: 
     pass 

if result is None: 
    print 'Malformed date.' 
else: 
    print 'Date is fine.' 

print tempdate 

++++編輯2 ++++ 如果刪除所述底部部分(tempdate.sort後())和與此替換它。

strfirstdate = re.compile(r'([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]+\.[0-9][0-9])') 
for s in tempdate: 
    if re.match(strfirstdate, s): 
     result = "validated" 
    else: 
     print "#####################" 
     print "#####################" 
     print "## error in date ##" 
     print "#####################" 
     print "#####################" 
     exit 

它會適當地驗證。

這整個方法似乎不是非常pythonic。

+0

你的意思是用蠻力?顯然你必須執行一些邏輯來分離你顯示的不同情況。只要做到這一點,展示你的代碼,我們將幫助你使它變得更加pythonic。 – Achim

+0

@Achim我已經開始做了該項目的長度先看看,如果是2比對驗證數長。如果不是,則對照正則表達式'thedate = re.compile(r'([0-9] [0-9] [0-9] [0-9] [0-9] [0-9] [0- 9] [0-9] + \。[0-9] [0-9])') if re.match(thedate,item): print「validated」 ...' – Chasester

回答

0

看看time模塊。具體請參見time.strptime()函數。

在時間值和日期時間對象之間還有一個相當簡單的轉換。

+0

我認爲只解決問題的小部分。 – Achim

+0

@Achim - 我的目標不是解決問題。這只是提供正確的參考資料,所以他可以自己解決。教一個人釣魚,以及所有這些...... –

+1

@亞歷史密斯,這是一個更好的方法,用於標記[作業]的問題,這不是 – Daenyth

7

您可以創建一個掩碼並使用try...except來解析它,以確定日期字符串是否與多個掩碼中的一個匹配。我有一個項目的代碼,所以我稍微修改了它:

from time import mktime, strptime 
from datetime import datetime 

date = '20110909.00 20110909.23'.split(' ')[0] 
result = None 

for format in ['%Y%m%d', '%Y%m%d.%H']: 
    try: 
    result = datetime.strptime(date, format) 
    except: 
    pass 

if result is None: 
    print 'Malformed date.' 
else: 
    print 'Date is fine.' 
+1

+1,但我會用更簡單的'result = datetime.strptime(日期,格式)' –

+0

謝謝@Blender。我發現將格式化爲格式的格式也添加了%H。但有一個問題 - 我想我不太清楚,但如果只是通過了一小時,我希望輸出將日期添加到小時。同樣,如果這只是沒有時間的日期。 – Chasester

0

這是否對您有幫助? :

from datetime import datetime 
import re 

reg = re.compile('(\d{4})(\d\d)(\d\d)' 
       '(?:\.(\d\d)(\d\d)?(\d\d)? *' 
       '(?:(\d{4})(\d\d)(\d\d)\.)?(\d\d)(\d\d)?(\d\d)? *)?') 

for x in ('20110909', 
      '20110909.00 23', 
      '20110909.00 74', 
      '20110909.00 20110909.23', 
      '20110909.00 19980412.23', 
      '20110909.08 20110909.23', 
      '20110935.08 20110909.23', 
      '20110909.08 19970609.51'): 
    print x 

    gr = reg.match(x).groups('000') 

    try: 
     x1 = datetime(*map(int,gr[0:6])) 

     if gr[6]=='000': 

      if gr[9]=='000': 
       x2 = x1 

      else: 
       y = map(int,gr[0:3] + gr[9:12]) 
       try: 
        x2 = datetime(*y) 
       except: 
        x2 = "The second part isn't in range(0,25)" 

     else: 
      y = map(int,gr[6:12]) 
      try: 
       x2 = datetime(*y) 
      except: 
       x2 = "The second part doesn't represent a real date" 
    except: 
     x1 = "The first part dosen't represent a real date" 
     x2 = '--' 

    print [str(x1),str(x2)],'\n' 

結果

20110909 
['2011-09-09 00:00:00', '2011-09-09 00:00:00'] 

20110909.00 23 
['2011-09-09 00:00:00', '2011-09-09 23:00:00'] 

20110909.00 74 
['2011-09-09 00:00:00', "The hour in the second part isn't in range(0,25)"] 

20110909.00 20110909.23 
['2011-09-09 00:00:00', '2011-09-09 23:00:00'] 

20110909.00 19980412.23 
['2011-09-09 00:00:00', '1998-04-12 23:00:00'] 

20110909.08 20110909.23 
['2011-09-09 08:00:00', '2011-09-09 23:00:00'] 

20110935.08 20110909.23 
["The first part dosen't represent a real date", '--'] 

20110909.08 19970609.51 
['2011-09-09 08:00:00', "The second part doesn't represent a real date"] 

注意groups('000')取代每個羣組是「000」

1

我發現了一些問題,當我試圖在我自己的分析使用try..except代碼示例使這裏與我增加了一個修正版本,我還討論了只處理小時部分的問題:

from datetime import datetime 

dates = ['20110909.00','20110909.23','13','20111212','20113131'] 

def dateTest(date): 
    dateOk = False 
    for format in ['%Y%m%d', '%Y%m%d.%H', '%H']: 
    try: 
     result = datetime.strptime(date, format) 
     dateOk = (date == result.strftime(format)) # this makes sure the parsed date matches the original string 
     if format == '%H': # this handles the hour only case 
     date = '%s.%s' % (datetime.now().strftime('%Y%m%d'), date) 
    except: 
     pass 

    if dateOk: 
    print 'Date is fine.' 
    else: 
    print 'Malformed date.' 
    return date 

for date in dates: 
    print date 
    print dateTest(date) 
    print ''