Python 常用日期处理 -- calendar 与 dateutil 模块的使用


Posted in Python onSeptember 02, 2020

本文紧承上一篇 Python 常用日期处理,因制于篇幅的大小需求才临时分立新篇,这里要简单提到 calendar 和 dateutil 模块的使用,其中 calendar 是 Python 内置的。相比于上一篇而言,此处主旨会更明确一些,只记录三个应用案例,分别是

  • 用 dateutil 灵活的解析 datetime 字符串
  • 给定起始日期后的连续日期
  • 给定起始日期后连续的月末日期

dateutil 灵活的解析 datetime 字符串

使用 Python 内容的 date 或 datetime, 构造它们的实例时需要逐个的传入年月日或时分秒,或者要调用 fromisoformat() 方法解析严格的字符串表示格式。而 dateutil.parser 的 parse() 方法就显得特别的聪明和随意,它可以智能的解析更丰富的字符串表示方式。详细的支持格式请参考官方文档的 parse examples,恐怕官方文档也未列举完全,只要觉得合理的时间字符串就可以尝试去解析。下方是一些例子

>>> from dateutil.parser import parse
>>>
>>> parse('2018-02-28')
datetime.datetime(2018, 2, 28, 0, 0)
>>> parse('2018-02-28T12:08:23')
datetime.datetime(2018, 2, 28, 12, 8, 23)
>>> parse('2018-02-28T12:08:23PM') # 下午
datetime.datetime(2018, 2, 28, 12, 8, 23)
>>> parse('2018-02-28T12:08:23+05:00') # 加上时区偏移
datetime.datetime(2018, 2, 28, 12, 8, 23, tzinfo=tzoffset(None, 18000))
>>> parse('Jan 18, 2018')
datetime.datetime(2018, 1, 18, 0, 0)
>>> parse('Oct. 10, 2008 10:43am CST') # 加上时区
datetime.datetime(2008, 10, 10, 10, 43, tzinfo=tzlocal())
>>> parse('Wed Jul 08 17:08:48 GMT 2009')
datetime.datetime(2009, 7, 8, 17, 8, 48, tzinfo=tzutc())
>>> parse("09-25-2003")
datetime.datetime(2003, 9, 25, 0, 0)
>>> parse("13-02-2003")  # 第一段大于 12 不可能是月份,所以推断为日期
datetime.datetime(2003, 2, 13, 0, 0)
>>>parse('09:23pm')
datetime.datetime(2019, 4, 30, 21, 23)

parser.parse() 返回的总是 datetime 类型,这也很好理解,因为 datetime 有完整的时间信息,可由此得到 date 或 time 实例。

给定起始日期后的连续日期

从一个给定日期一天天往后推可以直接用 Python 内置的 datetime(date 和 timedelta),还用不上 calendar 模块

>>> from datetime import date, timedelta
>>> start_date = date(2018, 2, 25)
>>> for i in range(1, 10):
...   print(start_date + timedelta(days = i))
...
2018-02-26
2018-02-27
2018-02-28
2018-03-01
2018-03-02
2018-03-03
2018-03-04
2018-03-05
2018-03-06

使用 timedelta 来计算日期偏移只能支持以下的度量

timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)

不能按月,年来换算,而 dateutil.relativedelta 就更强大了,看下它的构造函数

relativedelta(dt1=None, dt2=None, years=0, months=0, days=0, leapdays=0, weeks=0, hours=0, minutes=0, seconds=0, microseconds=0, year=None, month=None, day=None, weekday=None, yearday=None, nlyearday=None, hour=None, minute=None, second=None, microsecond=None)

我们可以换用 relativedelta 来重写上面的代码

>>> from datetime import date
>>> from dateutil.relativedelta import relativedelta
>>> start_date = date(2018, 2, 25)
>>> for i in range(1, 10):
...   print(start_date + relativedelta(days = i))
...
2018-02-26
2018-02-27
2018-02-28
2018-03-01
2018-03-02
2018-03-03
2018-03-04
2018-03-05
2018-03-06

如果想要推算下一个,下一个月,或下下年就需要用 relativedelta。

给定起始日期后连续的月末日期

假如用 relativedelta 按月推算日期的话就要涉及到 calendar 模块了,因为无论 30 天往下推算或是 relativedelta(months = 1) 得到的都可能不是自己想要的结果。例如

  • 2019-01-30 + relativedelta(months = 1) 是 2019-02-28
  • 2019-02-28 + relativedelta(months = 1) 是 2019-03-28

日期部分飘忽不定,这种按月推演出的结果没多大意思,一般来说我们可能需要的是每个月月末日期,可以使用 calendar 来确定指定年月的最小和最大日期。

>>> from datetime import date
>>> from dateutil.relativedelta import relativedelta
>>> from calendar import monthrange
>>>
>>> monthend = date(2019, 1, 31)
>>> for i in range(1, 10):
...   dd = monthend + relativedelta(months = i)
...   dd = dd.replace(day = monthrange(dd.year, dd.month)[1])
...   print(dd)
...
2019-02-28
2019-03-31
2019-04-30
2019-05-31
2019-06-30
2019-07-31
2019-08-31
2019-09-30
2019-10-31

Python 自带的 calendar 模块还有许多好玩的函数,如对星期,月份的遍历,真正的日历输出为文本或 HTML 代码的功能,详情请见Python CALENDAR Tutorial with Example.

来份简单的例子

>>> import calendar
>>> c = calendar.TextCalendar(calendar.SUNDAY)
>>> str = c.formatmonth(2019, 4)
>>> print(str)
   April 2019
Su Mo Tu We Th Fr Sa
  1 2 3 4 5 6
 7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

显示出与 bash 命令 cal -h 4 2019 一样的内容。

以上就是Python 日期处理 -- calendar 与 dateutil 模块的详细内容,更多关于python 日期处理的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
在Python的web框架中中编写日志列表的教程
Apr 30 Python
Python标准库之Sys模块使用详解
May 23 Python
详解Python网络爬虫功能的基本写法
Jan 28 Python
Python设计模式之命令模式简单示例
Jan 10 Python
python 返回一个列表中第二大的数方法
Jul 09 Python
python实现人工智能Ai抠图功能
Sep 05 Python
浅谈Python_Openpyxl使用(最全总结)
Sep 05 Python
pycharm设置当前工作目录的操作(working directory)
Feb 14 Python
Python网络爬虫信息提取mooc代码实例
Mar 06 Python
django 多数据库及分库实现方式
Apr 01 Python
Python错误的处理方法
Jun 23 Python
Python爬取梨视频的示例
Jan 29 Python
python 常用日期处理-- datetime 模块的使用
Sep 02 #Python
详解Python中的路径问题
Sep 02 #Python
python dict如何定义
Sep 02 #Python
python基本算法之实现归并排序(Merge sort)
Sep 01 #Python
在pycharm中文件取消用 pytest模式打开的操作
Sep 01 #Python
Python内置函数property()如何使用
Sep 01 #Python
mac安装python3后使用pip和pip3的区别说明
Sep 01 #Python
You might like
php 判断访客是否为搜索引擎蜘蛛的函数代码
2011/07/29 PHP
浏览器预览PHP文件时顶部出现空白影响布局分析原因及解决办法
2013/01/11 PHP
自己写的php curl库实现整站克隆功能
2015/02/12 PHP
codeigniter中实现一次性加载多个view的方法
2015/03/20 PHP
利用“多说”制作留言板、评论系统
2015/07/14 PHP
PHP+Mysql+jQuery实现发布微博程序 php篇
2015/10/15 PHP
php实现不通过扩展名准确判断文件类型的方法【finfo_file方法与二进制流】
2017/04/18 PHP
thinkPHP3.2.2框架行为扩展及demo示例
2018/06/19 PHP
PHP正则匹配到2个字符串之间的内容方法
2018/12/24 PHP
解决laravel session失效的问题
2019/10/14 PHP
thinkphp框架无限级栏目的排序功能实现方法示例
2020/03/29 PHP
探讨javascript是不是面向对象的语言
2013/11/21 Javascript
JavaScript使用Math.Min返回两个数中较小数的方法
2015/04/06 Javascript
javascript实现的右下角弹窗实例
2015/04/24 Javascript
javascript动态获取登录时间和在线时长
2016/02/25 Javascript
Vuejs第七篇之Vuejs过渡动画案例全面解析
2016/09/05 Javascript
详解AngularJS验证、过滤器、指令
2017/01/04 Javascript
vue中当图片地址无效的时候,显示默认图片的方法
2018/09/18 Javascript
一起写一个即插即用的Vue Loading插件实现
2019/10/31 Javascript
JS性能优化实现方法及优点进行
2020/08/30 Javascript
vue实现禁止浏览器记住密码功能的示例代码
2021/02/03 Vue.js
[00:58]2016年国际邀请赛勇士令状宣传片
2016/06/01 DOTA
python网络爬虫采集联想词示例
2014/02/11 Python
Python Map 函数的使用
2020/08/28 Python
Python: glob匹配文件的操作
2020/12/11 Python
美国休闲服装品牌:J.Crew Factory
2017/03/04 全球购物
社区端午节活动方案
2014/01/28 职场文书
大学生活动策划方案
2014/02/10 职场文书
厨师长岗位职责范本
2014/08/25 职场文书
反腐倡廉警示教育活动心得体会
2014/09/04 职场文书
运动会广播稿150字(9篇)
2014/09/20 职场文书
政府班子四风问题整改措施
2014/10/04 职场文书
党员四风自我剖析材料
2014/10/07 职场文书
2015年企业新年寄语
2014/12/08 职场文书
《语言的突破》读后感3篇
2019/12/12 职场文书
Python打包exe时各种异常处理方案总结
2021/05/18 Python