2011-09-09 138 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 ''