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中的set实现不重复的排序原理
Jan 24 Python
Python实现一个服务器监听多个客户端请求
Apr 12 Python
TensorFlow数据输入的方法示例
Jun 19 Python
Python实现的txt文件去重功能示例
Jul 07 Python
pygame游戏之旅 创建游戏窗口界面
Nov 20 Python
django云端留言板实例详解
Jul 22 Python
python3.5 cv2 获取视频特定帧生成jpg图片
Aug 28 Python
python统计函数库scipy.stats的用法解析
Feb 25 Python
python异常处理、自定义异常、断言原理与用法分析
Mar 23 Python
Pycharm无法打开双击没反应的问题及解决方案
Aug 17 Python
PyCharm设置注释字体颜色以及是否倾斜的操作
Sep 16 Python
python数字图像处理实现图像的形变与缩放
Jun 28 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 zend 相对路径问题
2009/01/12 PHP
在Yii框架中使用PHP模板引擎Twig的例子
2014/06/13 PHP
php事务回滚简单实现方法示例
2017/03/28 PHP
PHP实现的最大正向匹配算法示例
2017/12/19 PHP
PHP7.1实现的AES与RSA加密操作示例
2018/06/15 PHP
小程序微信退款功能实现方法详解【基于thinkPHP】
2019/05/05 PHP
php伪静态验证码不显示的解决方案
2019/09/26 PHP
jQuery ui1.7 dialog只能弹出一次问题
2009/08/27 Javascript
Javascript this 的一些学习总结
2012/08/31 Javascript
表单验证的完整应用案例探讨
2013/03/29 Javascript
angularJS 中$scope方法使用指南
2015/02/09 Javascript
EasyUI,点击开启编辑框,并且编辑框获得焦点的方法
2015/03/01 Javascript
详细分析JavaScript变量类型
2015/07/08 Javascript
jQuery实现带渐显效果的人物多级关系图代码
2015/10/16 Javascript
Bootstrap栅格系统的使用和理解2
2016/12/14 Javascript
在vue中高德地图引入和轨迹的绘制的实现
2019/10/11 Javascript
基于JavaScript实现单例模式
2019/10/30 Javascript
详解如何使用React Hooks请求数据并渲染
2020/10/18 Javascript
Python对文件操作知识汇总
2016/05/15 Python
Python爬取网易云音乐热门评论
2017/03/31 Python
Python工厂函数用法实例分析
2018/05/14 Python
python使用Matplotlib画饼图
2018/09/25 Python
python 输入一个数n,求n个数求乘或求和的实例
2018/11/13 Python
Python字典的基本用法实例分析【创建、增加、获取、修改、删除】
2019/03/05 Python
Python3简单爬虫抓取网页图片代码实例
2019/08/26 Python
linux面试题参考答案(7)
2012/10/29 面试题
外企测试工程师面试题
2015/02/01 面试题
送货司机岗位职责
2013/12/11 职场文书
部队领导证婚词
2014/01/12 职场文书
作风建设演讲稿
2014/05/23 职场文书
大学毕业生个人自荐书
2014/07/02 职场文书
副主任竞聘演讲稿
2014/08/18 职场文书
“四风”查摆问题自我剖析材料
2014/09/27 职场文书
区域销售大会开幕词
2016/03/04 职场文书
PostgreSQL并行计算算法及参数强制并行度设置方法
2022/04/06 PostgreSQL
python模拟浏览器 使用selenium进入好友QQ空间并留言
2022/04/12 Python