Python 日期的转换及计算的具体使用详解
Python  /  管理员 发布于 7年前   218
日期的转换及计算
对于日期,有时需执行不同时间单位的转换,或者接受字符串格式的日期,转换为 datetime 对象。有时需计算日期的范围,以及特定某个星期几的日期。这里更多用到的是 Python 提供的 datetime 模块。
datetime 模块
日期与时间的简单转换
datetime 模块中可以通过创建 timedelta 对象表示一个时间段。如下示例:
>>> from datetime import timedelta>>> a = timedelta(days=2, hours=6)>>> b = timedelta(hours=4.5)>>> c = a + b>>> cdatetime.timedelta(2, 37800)>>> c.days2>>> c.seconds37800>>> c.seconds / 360010.5>>> c.total_seconds() / 360058.5
如果想表示指定的日期和时间,需要先创建 datetime 对象然后使用标准数学运算执行操作。示例如下:
>>> from datetime import datetime>>> a = datetime(2020, 1, 15)>>> print(a + timedelta(days=10))2020-01-25 00:00:00>>> b = datetime(2020, 2, 3)>>> d = b - a>>> ddatetime.timedelta(19)>>> d.days19>>> now = datetime.today()>>> print(now)2020-01-15 10:59:10.230995>>> print(now + timedelta(minutes=10))2020-01-15 11:09:10.230995
datetime 对象能够自行处理闰年的问题,如下示例:
>>> a = datetime(2020, 3, 1)>>> b = datetime(2020, 2, 28)>>> a - bdatetime.timedelta(2)>>> (a - b).days2>>> c = datetime(2019, 3, 1)>>> d = datetime(2019, 2, 28)>>> c - ddatetime.timedelta(1)>>> (c - d).days1
字符串与日期的转换
当编写的程序接受以字符串格式表达的日期输入时,需求为将此类字符串转换为 datetime 对象进行计算。
使用 datetime 对象中的 strptime() 方法实现,如下代码:
>>> from datetime import datetime>>> text = '2020-01-15'>>> y = datetime.strptime(text, '%Y-%m-%d')>>> ydatetime.datetime(2020, 1, 15, 0, 0)>>> z = datetime.now()>>> zdatetime.datetime(2020, 1, 15, 11, 10, 11, 71792)>>> diff = z-y>>> diffdatetime.timedelta(0, 40211, 71792)
上述 %Y 的含义是以十进制表示的带世纪的年份,%m 为以补零后的十进制表示的月份,%d 为以补零后的十进制表示月份中的一天。
以下是几项格式代码。例如:
指令 | 含义 |
---|---|
%a | 当地工作日的缩写 |
% A | 当地工作日的全名 |
% b | 当地月份的缩写 |
% B | 当地月份的全名 |
% H | 补零后十进制表示的小时(24小时制) |
% I | 补零后十进制表示的小时(12小时制) |
% M | 补零后十进制表示的分钟 |
% S | 补零后十进制表示的秒 |
将日期格式化为英文易读形式,如下:
>>> zdatetime.datetime(2020, 1, 15, 11, 10, 11, 71792)>>> format_z = datetime.strftime(z, "%A %B %d, %Y")>>> format_z'Wednesday January 15, 2020'
datetime.strftime() 函数返回一个由显示格式字符串所指定的代表日期的字符串。格式指令,如上述代码中的 "%A %B %d, %Y"。其中该函数的第一个参数为 datetime 对象。
这里需要注意的地方是,strptime 的性能比较差。若明确需求是解析大量并且已经知道格式的日期字符串,可以考虑自己实现一套解析方案。假设格式如 YYYY-MM-DD,可用如下代码实现解析函数:
from datetime import datetimedef parse_ymd(s): year_s, mon_s, day_s = s.split('-') return datetime(int(year_s), int(mon_s), int(day_s))
两者实现的效果:
In [1]: from datetime import datetime ...: def parse_ymd(s): ...: year_s, mon_s, day_s = s.split('-') ...: return datetime(int(year_s), int(mon_s), int(day_s))In [2]: text = "2020-01-15"In [3]: %timeit datetime.strptime(text, '%Y-%m-%d')7.75 µs ± 31 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)In [4]: %timeit parse_ymd(text)1.05 µs ± 3.07 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
可以看出,parse_ymd() 函数比 datetime.strptime() 快 7 倍多。若是进行大量处理的设计日期,且格式固定的情况下,可以考虑这个方案。
计算某个月份的日期范围
Python 提供的 calendar 模块提供了与日历相关的函数。可以考虑配合 datetime 模块实现需求:
#!/usr/bin/env python# -*- coding:utf-8 -*-'''@File: datetime_calendar.py@Time: 2020/01/15 12:46:58@Author: 大梦三千秋@Contact: [email protected]'''# put the import lib herefrom datetime import date, timedeltaimport calendardef get_month_range(start_date=None): '''获取月份的范围 Args: start_date: 开始的日期,默认为 None Returns: 返回包含月份开始日期和结束日期的元组 ''' if start_date is None: # 若 start_date 为空,赋值为当月的第一天 start_date = date.today().replace(day=1) # 获取月份的天数 _, days_in_month = calendar.monthrange(start_date.year, start_date.month) # 计算结束日期 end_date = start_date + timedelta(days=days_in_month) # 返回开始日期和结束日期的元组 return (start_date, end_date)
在交互式解释器中使用如下:
In [1]: from datetime import timedeltaIn [2]: from datetime_calendar import get_month_rangeIn [3]: a_day = timedelta(days=1)In [4]: first_day, last_day = get_month_range()In [5]: while first_day < last_day: ...: print(first_day) ...: first_day += a_day ...:2020-01-012020-01-022020-01-032020-01-042020-01-052020-01-062020-01-072020-01-08...
注意:若在交互解释器下无法导入自己写的模块中的方法,尝试直接在文件所在的路径下打开交互解释器。
上面的代码中,首先将 start_date 对应月份的第一天的日期计算出来。这里使用了 date 对象的 replace() 方法将 day 属性设置为 1,即表示第一天。
calendar.monthrange() 函数返回指定年份指定月份第一天是星期几,以及这个月的天数。
获得月份天数后,加上开始日期可得结束日期。这里需要注意的是,结束日期并不包含在这个日期范围。在遍历的时候,判断条件为 first_day < last_day,不输出 last_day 的值,以 timedelta 实例进行递增日期。
参考资料
来源
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号