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中的实例方法、静态方法、类方法、类变量和实例变量浅析
Apr 26 Python
wxPython框架类和面板类的使用实例
Sep 28 Python
python开发之list操作实例分析
Feb 22 Python
Python实现Linux的find命令实例分享
Jun 04 Python
机器学习python实战之手写数字识别
Nov 01 Python
Python内置函数——__import__ 的使用方法
Nov 24 Python
python实现连连看游戏
Feb 14 Python
基于Python爬取股票数据过程详解
Oct 21 Python
python 图像增强算法实现详解
Jan 24 Python
Python使用tkinter实现小时钟效果
Feb 22 Python
pytorch 运行一段时间后出现GPU OOM的问题
Jun 02 Python
asyncio异步编程之Task对象详解
Mar 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
DIY一个适配电脑声卡的动圈话筒放大器
2021/03/02 无线电
用PHP查询搜索引擎排名位置的代码
2010/01/05 PHP
在PHP中使用curl_init函数的说明
2010/11/02 PHP
解析phpstorm + xdebug 远程断点调试
2013/06/20 PHP
FleaPHP框架数据库查询条件($conditions)写法总结
2016/03/19 PHP
微信公众平台DEMO(PHP)
2016/05/04 PHP
Symfony2创建基于域名的路由相关示例
2016/11/14 PHP
Ext.MessageBox工具类简介
2009/12/10 Javascript
JavaScript操作XML 使用百度RSS作为新闻源示例
2012/02/17 Javascript
IE下使用cloneNode注意事项分享
2012/11/22 Javascript
利用JQuery和Servlet实现跨域提交请求示例分享
2014/02/12 Javascript
微信小程序中显示html格式内容的方法
2017/04/25 Javascript
JS实现简单获取最近7天和最近3天日期的方法
2018/04/18 Javascript
微信小程序开发之转发分享功能
2019/10/22 Javascript
jquery轮播图插件使用方法详解
2020/07/31 jQuery
如何基于jQuery实现五角星评分
2020/09/02 jQuery
基于vuex实现购物车功能
2021/01/10 Vue.js
[04:49]期待西雅图之战 2016国际邀请赛中国区预选赛WINGS战队赛后采访
2016/06/29 DOTA
Python上传package到Pypi(代码简单)
2016/02/06 Python
Python使用中文正则表达式匹配指定中文字符串的方法示例
2017/01/20 Python
python处理数据,存进hive表的方法
2018/07/04 Python
python对象与json相互转换的方法
2019/05/07 Python
详解将Python程序(.py)转换为Windows可执行文件(.exe)
2019/07/19 Python
django数据模型on_delete, db_constraint的使用详解
2019/12/24 Python
python实现3D地图可视化
2020/03/25 Python
Python使用pdb调试代码的技巧
2020/05/03 Python
keras K.function获取某层的输出操作
2020/06/29 Python
吉尔德利巧克力公司:Ghirardelli Chocolate Company
2019/03/27 全球购物
建筑施工安全生产责任书
2014/07/22 职场文书
销售顾问工作计划书
2014/09/15 职场文书
群众路线党员自我评议范文2014
2014/09/24 职场文书
小学英语新课改心得体会
2016/01/22 职场文书
判断Python中的Nonetype类型
2021/05/25 Python
Python爬取英雄联盟MSI直播间弹幕并生成词云图
2021/06/01 Python
Vue vee-validate插件的简单使用
2021/06/22 Vue.js
Python+OpenCV实现图片中的圆形检测
2022/04/07 Python