我有一堆excel文档,我正在提取日期。我试图将这些转换为标准格式,以便我可以将它们放在数据库中。是否有一个函数我可以抛出这些字符串并获得标准格式?以下是我的数据的一小部分示例:
好消息是我知道它总是月/日
10/02/09
07/22/09
09-08-2008
9/9/2008
11/4/2010
03-07-2009
09/01/2010
我想将它们全部变成MM / DD / YYYY格式。有没有办法我可以做到这一点,而不是尝试每个模式对着字符串?
答案 0 :(得分:16)
第三方模块dateutil的函数parse
与PHP的strtotime
类似:您不需要指定特定的日期格式,它只是尝试了一堆它自己的。
>>> from dateutil.parser import parse
>>> parse("10/02/09", fuzzy=True)
datetime.datetime(2009, 10, 2, 0, 0) # default to be in American date format
它还允许您指定不同的假设:
- dayfirst - 是否将不明确的3整数日期(例如01/05/09)中的第一个值解释为日(True)或月(False)。如果yearfirst设置为True,则区分YDM和YMD。如果设置为None,则从当前parserinfo对象(其本身默认为False)中检索此值。
- yearfirst - 是否将不明确的3整数日期(例如01/05/09)中的第一个值解释为年份。如果为True,则第一个数字被视为年份,否则最后一个数字将被视为年份。如果将其设置为None,则从当前parserinfo对象(其本身默认为False)中检索该值。
答案 1 :(得分:16)
import re
ss = '''10/02/09
07/22/09
09-08-2008
9/9/2008
11/4/2010
03-07-2009
09/01/2010'''
regx = re.compile('[-/]')
for xd in ss.splitlines():
m,d,y = regx.split(xd)
print xd,' ','/'.join((m.zfill(2),d.zfill(2),'20'+y.zfill(2) if len(y)==2 else y))
结果
10/02/09 10/02/2009
07/22/09 07/22/2009
09-08-2008 09/08/2008
9/9/2008 09/09/2008
11/4/2010 11/04/2010
03-07-2009 03/07/2009
09/01/2010 09/01/2010
编辑2 :考虑到JBernardo的'{0:0>2}'.format(day)
信息,我添加了第4个解决方案,这似乎是最快的
import re
from time import clock
iterat = 100
from datetime import datetime
dates = ['10/02/09', '07/22/09', '09-08-2008', '9/9/2008', '11/4/2010',
' 03-07-2009', '09/01/2010']
reobj = re.compile(
r"""\s* # optional whitespace
(\d+) # Month
[-/] # separator
(\d+) # Day
[-/] # separator
(?:20)? # century (optional)
(\d+) # years (YY)
\s* # optional whitespace""",
re.VERBOSE)
te = clock()
for i in xrange(iterat):
ndates = (reobj.sub(r"\1/\2/20\3", date) for date in dates)
fdates1 = [datetime.strftime(datetime.strptime(date,"%m/%d/%Y"), "%m/%d/%Y")
for date in ndates]
print "Tim's method ",clock()-te,'seconds'
regx = re.compile('[-/]')
te = clock()
for i in xrange(iterat):
ndates = (reobj.match(date).groups() for date in dates)
fdates2 = ['%s/%s/20%s' % tuple(x.zfill(2) for x in tu) for tu in ndates]
print "mixing solution",clock()-te,'seconds'
te = clock()
for i in xrange(iterat):
ndates = (regx.split(date.strip()) for date in dates)
fdates3 = ['/'.join((m.zfill(2),d.zfill(2),('20'+y.zfill(2) if len(y)==2 else y)))
for m,d,y in ndates]
print "eyquem's method",clock()-te,'seconds'
te = clock()
for i in xrange(iterat):
fdates4 = ['{:0>2}/{:0>2}/20{}'.format(*reobj.match(date).groups()) for date in dates]
print "Tim + format ",clock()-te,'seconds'
print fdates1==fdates2==fdates3==fdates4
结果
number of iteration's turns : 100
Tim's method 0.295053700959 seconds
mixing solution 0.0459111423379 seconds
eyquem's method 0.0192239516475 seconds
Tim + format 0.0153756971906 seconds
True
混合解决方案很有意思,因为它结合了我的解决方案的速度和Tim Pietzcker的正则表达式在字符串中检测日期的能力。
对于结合Tim的一个和使用{:0>2}
进行格式化的解决方案,情况更是如此。我无法将{:0>2}
与我合并,因为regx.split(date.strip())
生成2年或4位数的年份
答案 2 :(得分:10)
如果您不想安装第三方模块,例如dateutil:
import re
from datetime import datetime
dates = ['10/02/09', '07/22/09', '09-08-2008', '9/9/2008', '11/4/2010', ' 03-07-2009', '09/01/2010']
reobj = re.compile(
r"""\s* # optional whitespace
(\d+) # Month
[-/] # separator
(\d+) # Day
[-/] # separator
(?:20)? # century (optional)
(\d+) # years (YY)
\s* # optional whitespace""",
re.VERBOSE)
ndates = [reobj.sub(r"\1/\2/20\3", date) for date in dates]
fdates = [datetime.strftime(datetime.strptime(date,"%m/%d/%Y"), "%m/%d/%Y")
for date in ndates]
结果:
['10/02/2009', '07/22/2009', '09/08/2008', '09/09/2008', '11/04/2010', '03/07/2009', '09/01/2010']
答案 3 :(得分:4)
您可以使用r'(\d+)\D(\d+)\D(\d+)'
这样的正则表达式来获取具有re.findall
函数的元组中的月,日和年。
然后将2位数年份与数字20
或19
连接起来,并使用您要加入的分隔符然后返回:
'/'.join(the_list)
蒂姆指出:
要规范化日期,只需执行'{0:0>2}'.format(day)
,然后执行相同的月份。