Python日期验证

4 投票
4 回答
6247 浏览
提问于 2025-04-17 01:56

我正在想办法用最符合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 个回答

0

看看这个 time 模块。特别是,看看 time.strptime() 这个函数。

时间值和日期时间对象之间的转换也很简单。

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

撰写回答