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深入06——python的内存管理详解
Dec 07 Python
python snownlp情感分析简易demo(分享)
Jun 04 Python
Python元字符的用法实例解析
Jan 17 Python
python3.x上post发送json数据
Mar 04 Python
使用WingPro 7 设置Python路径的方法
Jul 24 Python
Django外键(ForeignKey)操作以及related_name的作用详解
Jul 29 Python
深入浅析Python 命令行模块 Click
Mar 11 Python
python用Configobj模块读取配置文件
Sep 26 Python
编写python代码实现简单抽奖器
Oct 20 Python
关于python scrapy中添加cookie踩坑记录
Nov 17 Python
Python Pandas知识点之缺失值处理详解
May 11 Python
Python3使用Qt5来实现简易的五子棋小游戏
May 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
兼容firefox,chrome的网页灰度效果
2011/08/08 PHP
php实现批量下载百度云盘文件例子分享
2014/04/10 PHP
destoon实现公司新闻详细页添加评论功能的方法
2014/07/15 PHP
php实现计数器方法小结
2015/01/05 PHP
thinkphp5 URL和路由的功能详解与实例
2017/12/26 PHP
jQuery EasyUI API 中文文档 - Form表单
2011/10/06 Javascript
基于jquery的文字向上跑动类似跑马灯的效果
2014/09/22 Javascript
javascript操作数组详解
2014/12/17 Javascript
jQuery实现Tab选项卡切换效果简单演示
2015/11/23 Javascript
全面解析JavaScript中“&amp;&amp;”和“||”操作符(总结篇)
2016/07/18 Javascript
用headjs来管理和加载js 提高网站加载速度
2016/11/29 Javascript
jQuery Ajax实现跨域请求
2017/01/21 Javascript
Angular2管道Pipe及自定义管道格式数据用法实例分析
2017/11/29 Javascript
详解Webpack+Babel+React开发环境的搭建的方法步骤
2018/01/09 Javascript
Vue2.0生命周期的理解
2018/08/20 Javascript
layui点击弹框页面 表单请求的方法
2019/09/21 Javascript
详解Nuxt内导航栏的两种实现方式
2020/04/16 Javascript
vue实现lodop打印功能的示例
2020/11/11 Javascript
js实现验证码干扰(静态)
2021/02/22 Javascript
python中的多线程实例教程
2014/08/27 Python
django js实现部分页面刷新的示例代码
2018/05/28 Python
Django 限制用户访问频率的中间件的实现
2018/08/23 Python
Python使用Selenium模拟浏览器自动操作功能
2020/09/08 Python
关于Python 解决Python3.9 pandas.read_excel(‘xxx.xlsx‘)报错的问题
2020/11/28 Python
使用gunicorn部署django项目的问题
2020/12/30 Python
番木瓜健康和保健产品第一大制造商:Herbal Papaya
2017/04/25 全球购物
英国美发和美容产品商城:HQhair
2019/02/08 全球购物
会计学财务管理专业个人的自我评价
2013/10/19 职场文书
自我评价怎么写好呢?
2013/12/05 职场文书
物流管理专业职业生涯规划书
2014/01/06 职场文书
食品厂厂长岗位职责
2014/01/30 职场文书
机械设计及其自动化专业求职信
2014/06/09 职场文书
初中学校对照检查材料
2014/08/19 职场文书
2014年度个人工作总结范文
2015/03/09 职场文书
选对餐饮营销策略,营业额才会上涨
2019/08/27 职场文书
MySQL视图概念以及相关应用
2022/04/19 MySQL