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中的sort方法使用详解
Jul 25 Python
跟老齐学Python之用while来循环
Oct 02 Python
Python基于select实现的socket服务器
Apr 13 Python
python中nan与inf转为特定数字方法示例
May 11 Python
python opencv检测目标颜色的实例讲解
Apr 02 Python
python获取本机所有IP地址的方法
Dec 26 Python
浅谈PySpark SQL 相关知识介绍
Jun 14 Python
python实现监控阿里云账户余额功能
Dec 16 Python
解决Tensorflow sess.run导致的内存溢出问题
Feb 05 Python
Python logging模块异步线程写日志实现过程解析
Jun 30 Python
Pycharm连接gitlab实现过程图解
Sep 01 Python
Python实现迪杰斯特拉算法过程解析
Sep 18 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
php取整函数ceil,floo,round的用法及介绍
2013/08/31 PHP
分享一个超好用的php header下载函数
2014/01/31 PHP
YII Framework框架教程之国际化实现方法
2016/03/14 PHP
兼容IE/Firefox/Opera/Safari的检测页面装载完毕的脚本Ext.onReady的实现
2009/07/14 Javascript
safari,opera嵌入iframe页面cookie读取问题解决方法
2010/06/23 Javascript
JQuery入门——事件切换之toggle()方法应用介绍
2013/02/05 Javascript
js实现收缩菜单效果实例代码
2013/10/30 Javascript
移动端JQ插件hammer使用详解
2015/07/03 Javascript
javascript数据类型验证方法
2015/12/31 Javascript
jQuery调用WebMethod(PageMethod) NET2.0的方法
2016/04/15 Javascript
JS双击变input框批量修改内容
2016/12/12 Javascript
Bootstrap Img 图片样式(推荐)
2016/12/13 Javascript
在使用JSON格式处理数据时应该注意的问题小结
2017/05/20 Javascript
Angular2 组件间通过@Input @Output通讯示例
2017/08/24 Javascript
使用Angular CLI生成 Angular 5项目教程详解
2018/03/18 Javascript
vue基于element的区间选择组件
2018/09/07 Javascript
vue实现数字动态翻牌的效果(开箱即用)
2019/12/08 Javascript
浅谈element中InfiniteScroll按需引入的一点注意事项
2020/06/05 Javascript
通过实例解析JavaScript for in及for of区别
2020/06/15 Javascript
Vue实现Header渐隐渐现效果的实例代码
2020/11/05 Javascript
python实现在无须过多援引的情况下创建字典的方法
2014/09/25 Python
在Django框架中伪造捕捉到的URLconf值的方法
2015/07/18 Python
Python之web模板应用
2017/12/26 Python
Django 多表关联 存储 使用方法详解 ManyToManyField save
2019/08/09 Python
python实现猜数字游戏
2020/03/25 Python
Python要求O(n)复杂度求无序列表中第K的大元素实例
2020/04/02 Python
详解如何使用Pytest进行自动化测试
2021/01/14 Python
利用CSS3实现圆角的outline效果的教程
2015/06/05 HTML / CSS
携程英文网站:Trip.com
2017/02/07 全球购物
美国体育用品在线:Modell’s Sporting Goods
2018/06/07 全球购物
JAVA程序员面试题
2012/10/03 面试题
维修工先进事迹
2014/05/29 职场文书
淘宝活动总结范文
2014/06/26 职场文书
开平碉楼导游词
2015/02/06 职场文书
签订劳动合同通知书
2015/04/16 职场文书
行政处罚事先告知书
2015/07/01 职场文书