2011-09-09 11 views
4

私はこれを可能な限り最善の方法で実現する方法を考えようとしています。今私が考えることができる唯一の方法は、それを強引にすることです。Python、日付検証

ユーザは、すべての3つの例は、同じ結果を有するべきである以下の方法(例。./mypy.py日付=「20110909.00 23」)

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

のいずれかで(コマンドラインを介して)日付を入力しますそれは(私が並べ替えることができます)は、リストのような

['20110909.00', '20110909.23] 

、あるいは2つのソート別々の変数が、すべての場合、それはYYYYMMDD.HHだ、と確認するために必要で、それは確かにあるが移入場合、それは問題ではありません。日付で、テキストではありません。

アイデア?

ありがとうございます。

+++++ EDIT +++++ これを取り除いた後、最初に多くの日付をチェック/操作する必要があると思っています。すべてがうまくいっているようだ。最後の日を除いて、私は日付の検証を通じてリストを実行し、毎回通過するときでさえ、失敗します。

(私はそれを起動する) ./test.py日付= '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] re.match(thedate、item): print "validated" ... ' – Chasester

答えて

0

timeモジュールをご覧ください。具体的には、time.strptime()機能を参照してください。

時間値とdatetimeオブジェクトの間の変換もかなり簡単です。

+0

私はそれだけで解決すると思います問題のマイナーな部分。 – Achim

+0

@Achim - 私の目標は問題を解決することではありませんでした。彼はそれを自分で解決できるように、正しい参考資料を提供するだけでした。男に魚を釣ることを教えてください... –

+1

@Alex Smith、それは[宿題]というタグが付いた質問には良いアプローチですが、これは – 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(date、format)'を使用します。 –

+0

ありがとう@Blender。私は時間のためにフォーマットされたフォーマットにも%Hを追加することがわかりました。 1つの質問ですが、私はそれがはっきりしていなかったと思いますが、時間が1時間に過ぎない場合は、出力に日付を追加することをお勧めします。同様に、それはちょうど時を経ずに渡された日付です。 – 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」なしを交換しないことを

私は私自身の構文解析にtry..exceptのコード例を使用しようとしたとき、私はいくつかの問題を発見した

1

なしここに私が追加した修正のバージョンがあります。また、時間部分だけを扱う問題にも取り組んでいます:

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