Python不规范的日期字符串处理类
我分析了形如19920203、199203、1992.02.03、1992.02、1992-02-03、1992-02、920203时间格式特征,列出了正则表达式如下:
^((?:19|20)?\d{2})[-.]?((?:[0-1]?|1)[0-9])[-.]?((?:[0-3]?|[1-3])[0-9])?$
当然这个表达式还不是很完善,只能做简单的切割,不能判断日期的合法性,关于日期是否合法,我还是交给Python的时间功能来处理吧。
根据上面的正则表达式,我写的DateParser类如下:
importre importdatetime #*************************************************** #* #*Description:非标准的日期字符串处理 #*Author:wangye <pcn88athotmaildotcom> #* #*************************************************** classDateParser(object): def__init__(self): self.pattern=re.compile( r'^((?:19|20)?\d{2})[-.]?((?:[0-1]?|1)[0-9])[-.]?((?:[0-3]?|[1-3])[0-9])?$' ) def__cutDate(self,date,flags): y=date.year m=date.monthifflags[1]else1 d=date.dayifflags[2]else1 returndatetime.date(y,m,d) def__mergeFlags(self,flags1,flags2): l=[] length=min(len(flags1),len(flags2)) foriinrange(0,length): ifflags1[i]andflags2[i]: l.append(True) else: l.append(False) returnl defparse(self,strdate): """ 描述:时间解析方法。 参数:strdate要分析的时间字符串,比如目标时间类型datetime(1992,2,3) 可以被解析的是下述字符串之一: 19920203 199203 1992.02.03 1992.02 1992-02-03 1992-02 920203 返回值: 如果成功 元组(datetime,flags),其中datetime表示转换完成的合法时间, flags是标志位,表示有效位数,比如199202实际转换了年和月,日没有, 但是本函数将默认返回1日,但是flags将表示为(True,True,False), 前面两个True分别表示年和月被转换,最后一个False表示日没有被转换。 如果失败 返回None。 """ m=self.pattern.match(strdate) flags=[False,False,False] ifm: matches=list(m.groups()) flags=list(map(lambdax:Trueifx!=NoneelseFalse,matches)) results=list(map(lambdax:int(x)ifx!=Noneelse1,matches)) #results=list(map(lambdax:1ifx==Noneelsex,results)) ifresults[0]<100: ifresults[0]>9: results[0]+=1900 else: results[0]+=2000 return(datetime.date(results[0],results[1],results[2]),flags) else: returnNone defconvert(self,strdate,format): """ 描述:转换日期为指定格式。 参数:strdate同parse方法的strdate参数。 formatPython时间格式标识,同datetime.date.strftime格式化标识。 返回值: 如果成功,返回指定format格式的时间字符串。 如果失败,返回None。 """ date=self.parse(strdate) ifdate: date=date[0] returndatetime.date.strftime(date,format) else: returnNone defcompare(self,strdate1,strdate2): """ 描述:比较两个日期。 参数:strdate1和strdate2同parse方法的strdate参数 返回值: 可以是下列值之一 -4 strdate1无效, strdate2有效 -3 strdate1有效, strdate2无效 -2 strdate1和strdate2无效 -1 strdate1<strdate2 0 strdate1=strdate2 1 strdate1>strdate2 """ date1,flags1=self.parse(strdate1) date2,flags2=self.parse(strdate2) ifdate1==Noneanddate2!=None: return-4 ifdate1!=Noneanddate2==None: return-3 elifdate1==Noneanddate2==None: return-2 flags=self.__mergeFlags(flags1,flags2) date1=self.__cutDate(date1,flags) date2=self.__cutDate(date2,flags) ifdate1>date2: return1 elifdate1<date2: return-1 else: return0
下面举几个例子供大家参考:
>>>DateParser().parse("19860126") (datetime.date(1986,1,26),[True,True,True]) >>>DateParser().parse("199111") (datetime.date(1991,11,1),[True,True,False]) >>>DateParser().parse("1991") (datetime.date(1919,9,1),[True,True,True]) >>>DateParser().parse("8511") (datetime.date(1985,11,1),[True,True,False]) >>>DateParser().convert("19911101","%Y*%m*%d") '1991*11*01' >>>DateParser().convert("1990.1.01","%Y.%m.%d") '1990.01.01' >>>DateParser().compare("1992.2","19922") 0 >>>DateParser().compare("1992.2","1956.03.1") 1