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 相关文章推荐
Pthon批量处理将pdb文件生成dssp文件
Jun 21 Python
python简单文本处理的方法
Jul 10 Python
python通过百度地图API获取某地址的经纬度详解
Jan 28 Python
python 除法保留两位小数点的方法
Jul 16 Python
python3 实现一行输入,空格隔开的示例
Nov 14 Python
浅谈Python在pycharm中的调试(debug)
Nov 29 Python
在Python中居然可以定义两个同名通参数的函数
Jan 31 Python
django迁移数据库错误问题解决
Jul 29 Python
python 单线程和异步协程工作方式解析
Sep 28 Python
Python 内置变量和函数的查看及说明介绍
Dec 25 Python
matplotlib基础绘图命令之bar的使用方法
Aug 13 Python
Pytorch 如何实现常用正则化
May 27 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编写发红包程序
2015/07/22 PHP
php+ajax制作无刷新留言板
2015/10/27 PHP
Zend Framework教程之MVC框架的Controller用法分析
2016/03/07 PHP
thinkPHP连接sqlite3数据库的实现方法(附Thinkphp代码生成器下载)
2016/05/27 PHP
php中关于换行的实例写法
2019/09/26 PHP
防止网站内容被拷贝的一些方法与优缺点好处与坏处分析
2007/11/30 Javascript
Javascript模块化编程(一)模块的写法最佳实践
2013/01/17 Javascript
Javascript中引用示例介绍
2014/02/21 Javascript
如何高效率去掉js数组中的重复项
2016/04/12 Javascript
BootStrap智能表单实战系列(十一)级联下拉的支持
2016/06/13 Javascript
基于JavaScript实现购物车功能
2017/02/07 Javascript
基于input框覆盖掉数字英文的实例讲解
2017/07/21 Javascript
Vue单文件组件基础模板小结
2017/08/10 Javascript
JavaScript自执行函数和jQuery扩展方法详解
2017/10/27 jQuery
Vue.js实现双向数据绑定方法(表单自动赋值、表单自动取值)
2018/08/27 Javascript
JS实现的对象去重功能示例
2019/06/04 Javascript
JS 设计模式之:单例模式定义与实现方法浅析
2020/05/06 Javascript
[02:57]DOTA2亚洲邀请赛小组赛第四日 赛事回顾
2015/02/02 DOTA
给Python IDLE加上自动补全和历史功能
2014/11/30 Python
python数组复制拷贝的实现方法
2015/06/09 Python
python3中property使用方法详解
2019/04/23 Python
Django框架使用mysql视图操作示例
2019/05/15 Python
Python依赖包整体迁移方法详解
2019/08/15 Python
python集成开发环境配置(pycharm)
2020/02/14 Python
python多项式拟合之np.polyfit 和 np.polyld详解
2020/02/18 Python
html标签之Object和EMBED标签详解
2013/07/04 HTML / CSS
webView加载html图片遇到的问题解决
2019/10/08 HTML / CSS
英国广泛的照明产品网站:Lights4living
2018/01/28 全球购物
Kangol帽子官网:坎戈尔袋鼠
2018/09/26 全球购物
美国智能家居专家:tink
2019/06/04 全球购物
如何进行Linux分区优化
2013/02/12 面试题
ktv总经理岗位职责
2014/02/17 职场文书
小班评语大全
2014/05/04 职场文书
小学雷锋月活动总结
2014/07/03 职场文书
学校标语口号大全
2015/12/26 职场文书
SQL Server的存储过程与触发器以及系统函数和自定义函数
2022/04/10 SQL Server