Python日期验证
我正在想办法用最符合Python风格的方式来实现这个功能。目前我能想到的唯一方法就是蛮干。
用户通过命令行输入一个日期,格式可以是这样(例如: ./mypy.py date='20110909.00 23')
date='20110909'
date='20110909.00 23'
date='20110909.00 20110909.23'
这三种例子应该得到相同的结果,不管是把日期放到一个列表里(我可以对这个列表进行排序),比如说
['20110909.00', '20110909.23]
或者是把日期放到两个单独的已排序变量里,但无论哪种情况,格式都是YYYYMMDD.HH,并且需要确保输入的确实是日期,而不是文本。
有什么好主意吗?
谢谢。
+++++ 编辑 +++++
经过一番努力,我觉得我需要先做很多日期的检查和处理。现在这一切似乎都运作得很好。只是到了最后,我把列表通过日期验证时,每次都失败——即使在应该通过的时候。
(我用这个命令启动它)
./test.py date='20110909.00 23'
(或者任何日期的变体,比如 date='20 22' 或 date='20110909' 或 date='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
它就能正确验证了。
这个方法看起来就是不太符合Python的风格。
4 个回答
看看这个 time 模块。特别是,看看 time.strptime() 这个函数。
时间值和日期时间对象之间的转换也很简单。
我在尝试使用 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 ''
你可以创建一个“面具”(也就是格式),然后用它来检查日期字符串是否符合这些格式。可以使用 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.'