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 multiprocessing.Manager介绍和实例(进程间共享数据)
Nov 21 Python
python通过yield实现数组全排列的方法
Mar 18 Python
详解Django中Request对象的相关用法
Jul 17 Python
Django 添加静态文件的两种实现方法(必看篇)
Jul 14 Python
Tensorflow实现卷积神经网络的详细代码
May 24 Python
对dataframe进行列相加,行相加的实例
Jun 08 Python
pandas 数据实现行间计算的方法
Jun 08 Python
Python脚本利用adb进行手机控制的方法
Jul 08 Python
Pytorch根据layers的name冻结训练方式
Jan 06 Python
pyinstaller打包单文件时--uac-admin选项不起作用怎么办
Apr 15 Python
Keras 在fit_generator训练方式中加入图像random_crop操作
Jul 03 Python
selenium与xpath之获取指定位置的元素的实现
Jan 26 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递归方法实现无限分类实例代码
2014/02/28 PHP
PHP中的事务使用实例
2015/05/26 PHP
ThinkPHP框架整合微信支付之Native 扫码支付模式二图文详解
2019/04/09 PHP
php设计模式之策略模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
网页自动刷新,不产生嗒嗒声的一个解决方法
2007/03/27 Javascript
javascript之卸载鼠标事件的代码
2007/05/14 Javascript
使用js正则控制input标签只允许输入的值
2013/07/29 Javascript
JavaScript+html5 canvas绘制缤纷多彩的三角形效果完整实例
2016/01/26 Javascript
基于jQuery实现以手风琴方式展开和折叠导航菜单
2016/01/28 Javascript
使用React实现轮播效果组件示例代码
2016/09/05 Javascript
jQuery实现自动调用和触发某个事件的方法
2016/11/18 Javascript
微信小程序 ES6Promise.all批量上传文件实现代码
2017/04/14 Javascript
Windows下Node.js安装及环境配置方法
2017/09/18 Javascript
浅谈vue引入css,less遇到的坑和解决方法
2018/01/20 Javascript
vue 注册组件的使用详解
2018/05/05 Javascript
JavaScript实现浅拷贝与深拷贝的方法分析
2018/07/05 Javascript
详解webpack自定义loader初探
2018/08/29 Javascript
vue element中axios下载文件(后端Python)
2019/05/10 Javascript
vue+element创建动态的form表单及动态生成表格的行和列
2019/05/20 Javascript
highcharts.js数据绑定方式代码实例
2019/11/13 Javascript
初学Python实用技巧两则
2014/08/29 Python
Windows下Python2与Python3两个版本共存的方法详解
2017/02/12 Python
基于python的Tkinter编写登陆注册界面
2017/06/30 Python
Python 输出时去掉列表元组外面的方括号与圆括号的方法
2018/12/24 Python
Python获取时间范围内日期列表和周列表的函数
2019/08/05 Python
Python解析微信dat文件的方法
2020/11/30 Python
CSS3 中的@keyframes介绍
2014/09/02 HTML / CSS
HTML5 Canvas渐进填充与透明实现图像的Mask效果
2013/07/11 HTML / CSS
法国床上用品商店:La Compagnie du lit
2019/12/26 全球购物
会计与审计专业大专生求职信
2013/10/03 职场文书
工程地质勘察专业大学生求职信
2013/10/13 职场文书
社会治安综合治理责任书
2015/01/29 职场文书
2015年世界无烟日活动总结
2015/02/10 职场文书
SpringBoot整合RabbitMQ的5种模式实战
2021/08/02 Java/Android
python自动化操作之动态验证码、滑动验证码的降噪和识别
2021/08/30 Python
JavaScript 与 TypeScript之间的联系
2021/11/27 Javascript