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实现telnet服务器的方法
Jul 10 Python
Python实现的RSS阅读器实例
Jul 25 Python
pyenv命令管理多个Python版本
Mar 26 Python
Python调用C# Com dll组件实战教程
Oct 12 Python
python如何去除字符串中不想要的字符
Jul 05 Python
python的scikit-learn将特征转成one-hot特征的方法
Jul 10 Python
windows下python虚拟环境virtualenv安装和使用详解
Jul 16 Python
python plotly绘制直方图实例详解
Jul 22 Python
Python字符串格式化输出代码实例
Nov 22 Python
django 获取字段最大值,最新的记录操作
Aug 09 Python
anaconda升级sklearn版本的实现方法
Feb 22 Python
python实现对doc、txt、xls等文档的读写操作
Apr 02 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实现的随机广告显示代码
2007/06/14 PHP
php模拟post行为代码总结(POST方式不是绝对安全)
2012/02/22 PHP
PHP中数组定义的几种方法
2013/09/01 PHP
PHP在线打包下载功能示例
2016/10/15 PHP
JavaScript 不只是脚本
2007/05/30 Javascript
JavaScript 异步调用框架 (Part 1 - 问题 &amp; 场景)
2009/08/03 Javascript
js完美实现@提到好友特效(兼容各大浏览器)
2015/03/16 Javascript
JavaScript里实用的原生API汇总
2015/05/14 Javascript
基于jquery实现省市联动特效
2015/12/17 Javascript
javascript创建对象的几种模式介绍
2016/05/06 Javascript
关于axios返回空对象的问题解决
2017/04/04 Javascript
Express + Session 实现登录验证功能
2017/09/08 Javascript
vue过滤器用法实例分析
2019/03/15 Javascript
微信小程序实现音频文件播放进度的实例代码
2020/03/02 Javascript
[01:29:42]Liquid vs VP Supermajor决赛 BO 第一场 6.10
2018/07/05 DOTA
Python基于Tkinter实现的记事本实例
2015/06/17 Python
Python的Flask框架标配模板引擎Jinja2的使用教程
2016/07/12 Python
浅谈pyhton学习中出现的各种问题(新手必看)
2017/05/17 Python
20个常用Python运维库和模块
2018/02/12 Python
Python 利用内置set函数对字符串和列表进行去重的方法
2018/06/29 Python
python 实现视频 图像帧提取
2019/12/10 Python
Python爬虫开发与项目实战
2020/12/16 Python
html5中audio支持音频格式的解决方法
2018/08/24 HTML / CSS
运动会入场词200字
2014/02/15 职场文书
《胖乎乎的小手》教学反思
2014/02/26 职场文书
初中作文评语大全
2014/04/23 职场文书
毕业生代领毕业材料的授权委托书
2014/09/29 职场文书
安全保证书怎么写
2015/02/28 职场文书
2016年寒假社会实践活动总结
2015/10/10 职场文书
2019西餐厅创业计划书范文!
2019/07/12 职场文书
python实现自动清理文件夹旧文件
2021/05/10 Python
一篇文章带你搞懂Python类的相关知识
2021/05/20 Python
pycharm安装深度学习pytorch的d2l包失败问题解决
2022/03/25 Python
Go并发4种方法简明讲解
2022/04/06 Golang
使用Mysql计算地址的经纬度距离和实时位置信息
2022/04/29 MySQL
Win11如何默认打开软件界面最大化?Win11默认打开软件界面最大化的方法
2022/07/15 数码科技