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获取本地计算机名字的方法
Apr 29 Python
Python编程之gui程序实现简单文件浏览器代码
Dec 08 Python
Python OpenCV 直方图的计算与显示的方法示例
Feb 08 Python
python实现自动发送邮件
Jun 20 Python
python截取两个单词之间的内容方法
Dec 25 Python
python识别图像并提取文字的实现方法
Jun 28 Python
python集合的创建、添加及删除操作示例
Oct 08 Python
python画蝴蝶曲线图的实例
Nov 21 Python
Python模块_PyLibTiff读取tif文件的实例
Jan 13 Python
基于pygame实现童年掌机打砖块游戏
Feb 25 Python
windows、linux下打包Python3程序详细方法
Mar 17 Python
Python读取ini配置文件传参的简单示例
Jan 05 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树的代码,可以嵌套任意层
2006/10/09 PHP
PHP缓存技术的使用说明
2011/08/06 PHP
用穿越火线快速入门php面向对象
2012/02/22 PHP
PHP读取Excel内的图片(phpspreadsheet和PHPExcel扩展库)
2019/11/19 PHP
WordPress伪静态规则设置代码实例
2020/12/10 PHP
ExtJS TabPanel beforeremove beforeclose使用说明
2010/03/31 Javascript
自定义右键属性覆盖浏览器默认右键行为实现代码
2013/02/02 Javascript
你必须知道的JavaScript 中字符串连接的性能的一些问题
2013/05/07 Javascript
js实现快速分享功能(你的文章分享工具)
2013/06/25 Javascript
jquery对dom的操作常用方法整理
2013/06/25 Javascript
JS Jquery 遍历,筛选页面元素 自动完成(实现代码)
2013/07/08 Javascript
JSON无限折叠菜单编写实例
2013/12/16 Javascript
JavaScript编程的10个实用小技巧
2014/04/18 Javascript
jQuery 过滤方法filter()选择具有特殊属性的元素
2014/06/15 Javascript
在web中js实现类似excel的表格控件
2016/09/01 Javascript
js实现简单的选项卡效果
2017/02/23 Javascript
iconfont的三种使用方式详解
2018/08/05 Javascript
jQuery实现的点击显示隐藏下拉菜单功能完整示例
2019/05/17 jQuery
js判断复选框是否选中的方法示例【基于jQuery】
2019/10/10 jQuery
前端性能优化建议
2020/09/17 Javascript
python中numpy包使用教程之数组和相关操作详解
2017/07/30 Python
Django和Flask框架优缺点对比
2019/10/24 Python
Python编译成.so文件进行加密后调用的实现
2019/12/23 Python
韩国三大免税店之一:THE GRAND 中文免税店
2016/07/21 全球购物
LightInTheBox西班牙站点:全球商品在线采购
2016/09/22 全球购物
德国著名廉价网上药店:Shop-Apotheke
2017/07/23 全球购物
Crocs美国官方网站:卡骆驰洞洞鞋
2017/08/04 全球购物
爱普生美国官网:Epson美国
2018/11/05 全球购物
eBay加拿大站:eBay.ca
2019/06/20 全球购物
J2EE中的容器都包括哪些
2013/08/21 面试题
家长给孩子的表扬信
2014/01/17 职场文书
挖掘机司机岗位职责
2014/02/12 职场文书
医学院毕业生自荐信范文
2014/03/06 职场文书
遗嘱公证书标准样本
2014/04/08 职场文书
师范生免费教育协议书范本
2014/10/09 职场文书
Python干货实战之八音符酱小游戏全过程详解
2021/10/24 Python