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操作MySQL数据库具体方法
Oct 28 Python
Python中几种操作字符串的方法的介绍
Apr 09 Python
Python中的复制操作及copy模块中的浅拷贝与深拷贝方法
Jul 02 Python
详解Python中的array数组模块相关使用
Jul 05 Python
Python编程pygal绘图实例之XY线
Dec 09 Python
对Python 窗体(tkinter)文本编辑器(Text)详解
Oct 11 Python
对python中Json与object转化的方法详解
Dec 31 Python
利用python计算windows全盘文件md5值的脚本
Jul 27 Python
Django 如何使用日期时间选择器规范用户的时间输入示例代码详解
May 22 Python
Python Tkinter实例——模拟掷骰子
Oct 24 Python
Python生成pdf目录书签的实例方法
Oct 29 Python
用Python将库打包发布到pypi
Apr 13 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
CPU步进是什么意思?i3-9100F B0步进和U0步进区别知识科普
2020/03/17 数码科技
php中使用preg_replace函数匹配图片并加上链接的方法
2013/02/06 PHP
hadoop中一些常用的命令介绍
2013/06/19 PHP
ThinkPHP2.x防范XSS跨站攻击的方法
2015/09/25 PHP
PHP Ajax JavaScript Json获取天气信息实现代码
2016/08/17 PHP
php使用ftp实现文件上传与下载功能
2017/07/21 PHP
laravel框架实现为 Blade 模板引擎添加新文件扩展名操作示例
2020/01/25 PHP
js中匿名函数的N种写法
2010/09/08 Javascript
jQuery1.6 使用方法二
2011/11/23 Javascript
javascript制作坦克大战全纪录(2)
2014/11/27 Javascript
原生javascript实现自动更新的时间日期
2016/02/12 Javascript
轻松搞定jQuery.noConflict()
2016/02/15 Javascript
js css实现垂直方向自适应的三角提示菜单
2016/06/26 Javascript
JS在Chrome浏览器中showModalDialog函数返回值为undefined的解决方法
2016/08/03 Javascript
JS匿名函数实例分析
2016/11/26 Javascript
Angular2 自定义表单验证器的实现方法
2018/12/14 Javascript
vue调用语音播放的方法
2019/09/27 Javascript
JavaScript实现像雪花一样的Hexaflake分形
2020/07/07 Javascript
使用Webpack 搭建 Vue3 开发环境过程详解
2020/07/28 Javascript
[06:38]DOTA2怒掀电竞风暴 2013Chinajoy
2013/07/27 DOTA
[00:10]DOTA2全国高校联赛 以DOTA2会友
2018/05/30 DOTA
[58:59]完美世界DOTA2联赛PWL S3 access vs CPG 第一场 12.13
2020/12/16 DOTA
浅谈python for循环的巧妙运用(迭代、列表生成式)
2017/09/26 Python
pandas dataframe添加表格框线输出的方法
2019/02/08 Python
python与字符编码问题
2019/05/24 Python
如何解决django-celery启动后迅速关闭
2019/10/16 Python
python uuid生成唯一id或str的最简单案例
2021/01/13 Python
德国网上花店:Valentins
2018/08/15 全球购物
Kathmandu美国网站:新西兰户外运动品牌
2019/03/23 全球购物
公司股权转让协议书
2014/04/12 职场文书
幼儿教师师德师风自我剖析材料
2014/09/29 职场文书
自我检讨书范文
2015/01/28 职场文书
小学教师自我评价
2015/03/04 职场文书
2016年度基层党建工作公开承诺书
2016/03/25 职场文书
公历12个月名称的由来
2022/04/12 杂记
HttpClient实现文件上传功能
2022/08/14 Java/Android