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中expandtabs()方法的使用
May 18 Python
Python实现批量将word转html并将html内容发布至网站的方法
Jul 14 Python
Python2.7编程中SQLite3基本操作方法示例
Aug 09 Python
Python导入模块时遇到的错误分析
Aug 30 Python
python使用phoenixdb操作hbase的方法示例
Feb 28 Python
使用python打印十行杨辉三角过程详解
Jul 10 Python
浅谈PyQt5中异步刷新UI和Python多线程总结
Dec 13 Python
Pycharm 2020年最新激活码(亲测有效)
Sep 18 Python
python图形开发GUI库wxpython使用方法详解
Feb 14 Python
在Python中字典按值排序的实现方法
Nov 12 Python
python接口自动化框架实战
Dec 23 Python
python Django框架快速入门教程(后台管理)
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
php 缩略图实现函数代码
2011/06/23 PHP
打开超链需要“确认”对话框的方法
2007/03/08 Javascript
关于onScroll事件在IE6下每次滚动触发三次bug说明
2011/09/21 Javascript
js实现鼠标拖动图片并兼容IE/FF火狐/谷歌等主流浏览器
2013/06/06 Javascript
javascript中Number对象的toString()方法分析
2014/12/20 Javascript
javaScript基础语法介绍
2015/02/28 Javascript
基于jQuery通过jQuery.form.js插件实现异步上传
2015/12/13 Javascript
AngularJS实现DOM元素的显示与隐藏功能
2016/11/22 Javascript
ionic开发中点击input时键盘自动弹出
2016/12/23 Javascript
JS实现页面中所有img对象添加onclick事件及新窗口查看图片的方法
2016/12/27 Javascript
vue之数据交互实例代码
2017/06/16 Javascript
Angular实现图片裁剪工具ngImgCrop实践
2017/08/17 Javascript
JS实现动态生成html table表格的方法分析
2018/07/11 Javascript
解决vue的变量在settimeout内部效果失效的问题
2018/08/30 Javascript
vue 左滑删除功能的示例代码
2019/01/28 Javascript
[00:52]DOTA2齐天大圣预告片
2016/08/13 DOTA
python3.3实现乘法表示例
2014/02/07 Python
用Python中的__slots__缓存资源以节省内存开销的方法
2015/04/02 Python
python使用PyGame模块播放声音的方法
2015/05/20 Python
在Python的Django框架中更新数据库数据的方法
2015/07/17 Python
深入理解Python中的super()方法
2017/11/20 Python
Python调用C语言的方法【基于ctypes模块】
2018/01/22 Python
Django项目使用CircleCI的方法示例
2019/07/14 Python
使用 Python 在京东上抢口罩的思路详解
2020/02/27 Python
Spark处理数据排序问题如何避免OOM
2020/05/21 Python
Python如何实现的二分查找算法
2020/05/27 Python
Python 必须了解的5种高级特征
2020/09/10 Python
详解CSS3浏览器兼容
2016/12/14 HTML / CSS
成人高等教育毕业生自我鉴定
2013/10/22 职场文书
优秀中专生推荐信
2013/11/17 职场文书
事业单位公务员的职业生涯规划
2014/01/15 职场文书
上班离岗检讨书
2014/01/27 职场文书
文明好少年事迹材料
2014/08/19 职场文书
乡镇党委书记第三阶段个人整改措施
2014/09/16 职场文书
信访工作个人总结
2015/03/03 职场文书
Pygame如何使用精灵和碰撞检测
2021/11/17 Python