Python不规范的日期字符串处理类


Posted in Python onJune 10, 2014

我分析了形如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类如下:

import re
import datetime# ***************************************************
# *
# * Description: 非标准的日期字符串处理
# * Author: wangye  <pcn88 at hotmail dot com>
# *
# ***************************************************
class DateParser(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.month if flags[1] else 1
        d = date.day if flags[2] else 1
        return datetime.date(y, m, d)
    def __mergeFlags(self, flags1, flags2):
        l = []
        length = min(len(flags1), len(flags2))
        for i in range(0, length):
            if flags1[i] and flags2[i]:
                l.append(True)
            else:
                l.append(False)
        return l
    def parse(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]
        if m:
            matches = list(m.groups())
            flags = list(map(lambda x:True if x!=None else False, matches))
            results = list(map(lambda x:int(x) if x!=None else 1, matches))
            # results = list(map(lambda x:1 if x==None else x, results))
            if results[0]<100:
                if results[0]>9:
                    results[0] += 1900
                else:
                    results[0] += 2000
            return (datetime.date(results[0], results[1], results[2]), flags)
        else:
            return None
    def convert(self, strdate, format):
        """
        描述:转换日期为指定格式。
        参数:strdate 同parse方法的strdate参数。
              format Python时间格式标识,同datetime.date.strftime格式化标识。
        返回值:
            如果成功,返回指定format格式的时间字符串。
            如果失败,返回None。
        """
        date = self.parse(strdate)
        if date:
            date = date[0]
            return datetime.date.strftime(date, format)
        else:
            return None
    def compare(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)
        if date1 == None and date2 != None:
            return -4
        if date1 != None and date2 == None:
            return -3
        elif date1 == None and date2 == None:
            return -2
        flags = self.__mergeFlags(flags1, flags2)
        date1 = self.__cutDate(date1, flags)
        date2 = self.__cutDate(date2, flags)
        if date1>date2:
            return 1
        elif date1<date2:
            return -1
        else:
            return 0

下面举几个例子供大家参考:

>>> 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
Python 相关文章推荐
python实现sublime3的less编译插件示例
Apr 27 Python
python数据清洗系列之字符串处理详解
Feb 12 Python
Python 专题一 函数的基础知识
Mar 16 Python
Python编程实现双击更新所有已安装python模块的方法
Jun 05 Python
用Pygal绘制直方图代码示例
Dec 07 Python
python使用生成器实现可迭代对象
Mar 20 Python
Python英文文本分词(无空格)模块wordninja的使用实例
Feb 20 Python
Win10下Python3.7.3安装教程图解
Jul 08 Python
用OpenCV将视频分解成单帧图片,图片合成视频示例
Dec 10 Python
Numpy实现卷积神经网络(CNN)的示例
Oct 09 Python
python Polars库的使用简介
Apr 21 Python
Opencv实现二维直方图的计算及绘制
Jul 21 Python
Python ORM框架SQLAlchemy学习笔记之数据查询实例
Jun 10 #Python
Python ORM框架SQLAlchemy学习笔记之数据添加和事务回滚介绍
Jun 10 #Python
Python ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
Jun 10 #Python
Python ORM框架SQLAlchemy学习笔记之关系映射实例
Jun 10 #Python
Python ORM框架SQLAlchemy学习笔记之安装和简单查询实例
Jun 10 #Python
Python使用htpasswd实现基本认证授权的例子
Jun 10 #Python
python网络编程学习笔记(10):webpy框架
Jun 09 #Python
You might like
解析PayPal支付接口的PHP开发方式
2010/11/28 PHP
ajax 的post方法实例(带循环)
2011/07/04 PHP
php提示无法加载或mcrypt没有找到 PHP 扩展 mbstring解决办法
2012/03/27 PHP
一个PHP并发访问实例代码
2012/09/06 PHP
迅速确定php多维数组的深度的方法
2014/01/07 PHP
ecshop后台编辑器替换成ueditor编辑器
2015/03/03 PHP
javascript编程起步(第五课)
2007/02/27 Javascript
JavaScript 实现??打印?理
2007/04/28 Javascript
jquery 实现的全选和反选
2009/04/15 Javascript
jquery、js操作checkbox全选反选
2014/03/12 Javascript
node.js中使用socket.io的方法
2014/12/15 Javascript
浅谈JavaScript Date日期和时间对象
2014/12/29 Javascript
jQuery插件animateSlide制作多点滑动幻灯片
2015/06/11 Javascript
全面解析Bootstrap中transition、affix的使用方法
2016/05/30 Javascript
node.js平台下的mysql数据库配置及连接
2017/03/31 Javascript
微信小程序本地缓存数据增删改查实例详解
2017/05/24 Javascript
使用Dropzone.js上传的示例代码
2017/10/10 Javascript
react router4+redux实现路由权限控制的方法
2018/05/03 Javascript
微信小程序开发之tabbar图标和颜色的实现
2018/10/17 Javascript
Vue+Java+Base64实现条码解析的示例
2020/09/23 Javascript
浅谈Python类里的__init__方法函数,Python类的构造函数
2016/12/10 Python
Python实现读取json文件到excel表
2017/11/18 Python
python性能测量工具cProfile使用解析
2019/09/26 Python
全球知名的珠宝首饰品牌:Kay Jewelers
2018/02/11 全球购物
Rag & Bone官网:瑞格布恩高级成衣
2018/04/19 全球购物
Carmen Sol官网:购买果冻鞋、手袋和配件
2021/01/01 全球购物
计算机应用专业毕业生求职信
2013/10/24 职场文书
小学安全工作汇报材料
2014/08/19 职场文书
股东授权委托书范文
2014/09/13 职场文书
夫妻房产协议书的格式
2014/10/11 职场文书
遗失说明具结保证书
2015/02/26 职场文书
结婚保证书(三从四德)
2015/02/26 职场文书
大学生简历自我评价2015
2015/03/03 职场文书
退休教师欢送会致辞
2015/07/31 职场文书
重阳节主题班会
2015/08/17 职场文书
Python包管理工具pip的15 个使用小技巧
2021/05/17 Python