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中join和split用法实例
Apr 14 Python
使用Python对微信好友进行数据分析
Jun 27 Python
详解python读取和输出到txt
Mar 29 Python
Python中将两个或多个list合成一个list的方法小结
May 12 Python
numpy和pandas中数组的合并、拉直和重塑实例
Jun 28 Python
Python绘制堆叠柱状图的实例
Jul 09 Python
在Python中os.fork()产生子进程的例子
Aug 08 Python
Django静态资源部署404问题解决方案
May 11 Python
python实现数学模型(插值、拟合和微分方程)
Nov 13 Python
Biblibili视频投稿接口分析并以Python实现自动投稿功能
Feb 05 Python
PyTorch中的torch.cat简单介绍
Mar 17 Python
Python docx库删除复制paragraph及行高设置图片插入示例
Jul 23 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
怎么在Windows系统中搭建php环境
2013/08/31 PHP
PHP5中实现多态的两种方法实例分享
2014/04/21 PHP
基于OpenCart 开发支付宝,财付通,微信支付参数错误问题
2015/10/01 PHP
浅谈PHP5.6 与 PHP7.0 区别
2019/10/09 PHP
js history对象简单实现返回和前进
2013/10/30 Javascript
jquery序列化表单去除指定元素示例代码
2014/04/10 Javascript
JavaScript 学习笔记之变量及其作用域
2015/01/14 Javascript
js仿土豆网带缩略图的焦点图片切换效果实现方法
2015/02/23 Javascript
JS实现仿QQ效果的三级竖向菜单
2015/09/25 Javascript
举例讲解JavaScript中将数组元素转换为字符串的方法
2015/10/25 Javascript
JS事件添加和移出的兼容写法示例
2016/06/20 Javascript
AngularJs基本特性解析(一)
2016/07/21 Javascript
vue2.0父子组件及非父子组件之间的通信方法
2017/01/21 Javascript
angular+bootstrap的双向数据绑定实例
2017/03/03 Javascript
JS实现颜色动态淡化效果
2017/03/06 Javascript
Angular实现搜索框及价格上下限功能
2018/01/19 Javascript
javascript实现自由编辑图片代码详解
2019/06/21 Javascript
[00:58]2016年国际邀请赛勇士令状宣传片
2016/06/01 DOTA
Python实现配置文件备份的方法
2015/07/30 Python
python3 线性回归验证方法
2019/07/09 Python
python实现音乐播放器 python实现花框音乐盒子
2020/02/25 Python
python request 模块详细介绍
2020/11/10 Python
使用jquery实现HTML5响应式导航菜单教程
2014/04/02 HTML / CSS
美国领先的精品家居照明和装饰产品在线零售商:LightsOnline.com
2018/01/23 全球购物
马德里运动鞋商店:Nigra Mercato
2020/02/16 全球购物
Chinti & Parker官网:奢华羊绒女装和创新针织设计
2021/01/01 全球购物
网络维护管理员的自我评价分享
2013/11/11 职场文书
英语感恩演讲稿
2014/01/14 职场文书
班组安全员工作职责
2014/02/01 职场文书
小学生学雷锋演讲稿
2014/04/25 职场文书
施工质量承诺书范文
2014/05/30 职场文书
大学生党员自我批评思想汇报
2014/10/10 职场文书
法定代表人授权委托书格式
2014/10/14 职场文书
党的群众路线教育实践活动制度建设计划方案
2014/10/31 职场文书
自制短波长线天线频率预选器 - 成功消除B2K之流的镜像
2021/04/22 无线电
使用Nginx的访问日志统计PV与UV
2022/05/06 Servers