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中list初始化方法示例
Sep 18 Python
pycharm中连接mysql数据库的步骤详解
May 02 Python
基于python 爬虫爬到含空格的url的处理方法
May 11 Python
TensorFlow利用saver保存和提取参数的实例
Jul 26 Python
Python3 利用requests 库进行post携带账号密码请求数据的方法
Oct 26 Python
python命令行参数用法实例分析
Jun 25 Python
python垃圾回收机制(GC)原理解析
Dec 30 Python
Python库安装速度过慢解决方案
Jul 14 Python
如何利用python发送邮件
Sep 26 Python
Python字符串的15个基本操作(小结)
Feb 03 Python
No module named ‘win32gui‘ 的解决方法(踩坑之旅)
Feb 18 Python
Python中文分词库jieba(结巴分词)详细使用介绍
Apr 07 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
编译问题
2006/10/09 PHP
深入PHP变量存储的详解
2013/06/13 PHP
YII分模块加载路由的实现方法
2018/10/01 PHP
为jquery.ui.dialog 增加“在当前鼠标位置打开”的功能
2009/11/24 Javascript
JavaScript中的isXX系列是否继续使用的分析
2011/04/16 Javascript
js jquery获取随机生成id的服务器控件的三种方法
2013/07/11 Javascript
jQuery toggleClass应用实例(附效果图)
2014/04/06 Javascript
javascript实现密码强度显示
2015/03/18 Javascript
jQuery Datatables表头不对齐的解决办法
2017/11/27 jQuery
webpack下实现动态引入文件方法
2018/02/22 Javascript
JS使用正则表达式获取小括号、中括号及花括号内容的方法示例
2018/06/01 Javascript
js数组去重的N种方法(小结)
2018/06/07 Javascript
ES6 系列之 WeakMap的使用示例
2018/08/06 Javascript
JavaScript Canvas实现验证码
2020/08/02 Javascript
使用weixin-java-tools完成微信授权登录、微信支付的示例
2018/09/26 Javascript
vue+egg+jwt实现登录验证的示例代码
2019/05/18 Javascript
vue多页面项目中路由使用history模式的方法
2019/09/23 Javascript
vue element upload组件 file-list的动态绑定实现
2019/10/11 Javascript
Python单元测试简单示例
2018/07/03 Python
在python中使用with打开多个文件的方法
2019/01/07 Python
使用Tensorflow实现可视化中间层和卷积层
2020/01/24 Python
python爬虫实例之获取动漫截图
2020/05/31 Python
Python实现打包成库供别的模块调用
2020/07/13 Python
python使用建议技巧分享(三)
2020/08/18 Python
Python3获取cookie常用三种方案
2020/10/05 Python
Selenium环境变量配置(火狐浏览器)及验证实现
2020/12/07 Python
解决pytorch 的state_dict()拷贝问题
2021/03/03 Python
环境科学专业大学生自荐信格式
2013/09/21 职场文书
促销活动策划方案
2014/01/12 职场文书
分公司负责人任命书
2014/06/04 职场文书
社区班子对照检查材料
2014/08/27 职场文书
国家助学贷款承诺书
2015/04/30 职场文书
2016读书月活动心得体会
2016/01/14 职场文书
教您:房贷工资收入证明应该怎么写?
2019/08/19 职场文书
广告文案的撰写技巧(实用干货)
2019/08/23 职场文书
python实现简单的聊天小程序
2021/07/07 Python