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操作列表的函数使用代码详解
Dec 28 Python
python实现12306抢票及自动邮件发送提醒付款功能
Mar 08 Python
Python中判断输入是否为数字的实现代码
May 26 Python
python3 深浅copy对比详解
Aug 12 Python
pip 安装库比较慢的解决方法(国内镜像)
Oct 06 Python
python 画3维轨迹图并进行比较的实例
Dec 06 Python
基于YUV 数据格式详解及python实现方式
Dec 09 Python
django连接mysql数据库及建表操作实例详解
Dec 10 Python
python字符串,元组,列表,字典互转代码实例详解
Feb 14 Python
Python实现名片管理系统
Feb 14 Python
Python如何将装饰器定义为类
Jul 30 Python
使用Python制作一个数据预处理小工具(多种操作一键完成)
Feb 07 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新手上路(四)
2006/10/09 PHP
PHP 引用文件技巧
2010/03/02 PHP
PHP json_encode中文乱码问题的解决办法
2013/09/09 PHP
destoon网站转移服务器后搜索汉字出现乱码的解决方法
2014/06/21 PHP
php插入mysql数据返回id的方法
2018/05/31 PHP
PHP文件操作实例总结【文件上传、下载、分页】
2018/12/08 PHP
Laravel 自带的Auth验证登录方法
2019/09/30 PHP
JavaScript语句可以不以;结尾的烦恼
2007/03/08 Javascript
如何确保JavaScript的执行顺序 之jQuery.html并非万能钥匙
2011/03/03 Javascript
jQuery.clean使用方法及思路分析
2013/01/07 Javascript
js实现用户离开页面前提示是否离开此页面的方法(包括浏览器按钮事件)
2015/07/18 Javascript
js控制多图左右滚动切换效果代码分享
2015/08/26 Javascript
为什么JavaScript没有块级作用域
2016/05/22 Javascript
浅谈Vue Element中Select下拉框选取值的问题
2018/03/01 Javascript
Zookeeper接口kazoo实例解析
2018/01/22 Python
使用Python如何测试InnoDB与MyISAM的读写性能
2018/09/18 Python
Windows下Python3.6安装第三方模块的方法
2018/11/22 Python
对python 合并 累加两个dict的实例详解
2019/01/21 Python
python 实现查找文件并输出满足某一条件的数据项方法
2019/06/12 Python
如何运行带参数的python脚本
2019/11/15 Python
python+opencv实现移动侦测(帧差法)
2020/03/20 Python
python如何导出微信公众号文章方法详解
2020/08/31 Python
ebookers英国:隶属全球最大的在线旅游公司Expedia
2017/12/28 全球购物
演讲稿怎么写才完美
2014/01/02 职场文书
校园新闻广播稿
2014/01/10 职场文书
中学生家长评语大全
2014/04/16 职场文书
企业总经理任命书
2014/06/05 职场文书
个人对照检查剖析材料
2014/10/13 职场文书
见习报告怎么写
2014/10/31 职场文书
实施意见格式范本
2015/06/05 职场文书
中学生国庆节演讲稿2015
2015/07/30 职场文书
公司员工离职感言
2015/08/03 职场文书
2019个人半年工作总结
2019/06/21 职场文书
聊一聊Redis与MySQL双写一致性如何保证
2021/06/26 Redis
Pyhton爬虫知识之正则表达式详解
2022/04/01 Python
PostgreSQL 插入INSERT、删除DELETE、更新UPDATE、事务transaction
2022/04/12 PostgreSQL