Python 日期的转换及计算的具体使用详解
作者:大梦三千秋 发布时间:2023-01-06 11:31:27
日期的转换及计算
对于日期,有时需执行不同时间单位的转换,或者接受字符串格式的日期,转换为 datetime 对象。有时需计算日期的范围,以及特定某个星期几的日期。这里更多用到的是 Python 提供的 datetime 模块。
datetime 模块
日期与时间的简单转换
datetime 模块中可以通过创建 timedelta 对象表示一个时间段。如下示例:
>>> from datetime import timedelta
>>> a = timedelta(days=2, hours=6)
>>> b = timedelta(hours=4.5)
>>> c = a + b
>>> c
datetime.timedelta(2, 37800)
>>> c.days
2
>>> c.seconds
37800
>>> c.seconds / 3600
10.5
>>> c.total_seconds() / 3600
58.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
>>> d
datetime.timedelta(19)
>>> d.days
19
>>> 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 - b
datetime.timedelta(2)
>>> (a - b).days
2
>>> c = datetime(2019, 3, 1)
>>> d = datetime(2019, 2, 28)
>>> c - d
datetime.timedelta(1)
>>> (c - d).days
1
字符串与日期的转换
当编写的程序接受以字符串格式表达的日期输入时,需求为将此类字符串转换为 datetime 对象进行计算。
使用 datetime 对象中的 strptime() 方法实现,如下代码:
>>> from datetime import datetime
>>> text = '2020-01-15'
>>> y = datetime.strptime(text, '%Y-%m-%d')
>>> y
datetime.datetime(2020, 1, 15, 0, 0)
>>> z = datetime.now()
>>> z
datetime.datetime(2020, 1, 15, 11, 10, 11, 71792)
>>> diff = z-y
>>> diff
datetime.timedelta(0, 40211, 71792)
上述 %Y 的含义是以十进制表示的带世纪的年份,%m 为以补零后的十进制表示的月份,%d 为以补零后的十进制表示月份中的一天。
以下是几项格式代码。例如:
指令 | 含义 |
---|---|
%a | 当地工作日的缩写 |
% A | 当地工作日的全名 |
% b | 当地月份的缩写 |
% B | 当地月份的全名 |
% H | 补零后十进制表示的小时(24小时制) |
% I | 补零后十进制表示的小时(12小时制) |
% M | 补零后十进制表示的分钟 |
% S | 补零后十进制表示的秒 |
将日期格式化为英文易读形式,如下:
>>> z
datetime.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 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 [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: yiluolion@126.com
'''
# put the import lib here
from datetime import date, timedelta
import calendar
def 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 timedelta
In [2]: from datetime_calendar import get_month_range
In [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-01
2020-01-02
2020-01-03
2020-01-04
2020-01-05
2020-01-06
2020-01-07
2020-01-08
...
注意:若在交互解释器下无法导入自己写的模块中的方法,尝试直接在文件所在的路径下打开交互解释器。
上面的代码中,首先将 start_date 对应月份的第一天的日期计算出来。这里使用了 date 对象的 replace() 方法将 day 属性设置为 1,即表示第一天。
calendar.monthrange() 函数返回指定年份指定月份第一天是星期几,以及这个月的天数。
获得月份天数后,加上开始日期可得结束日期。这里需要注意的是,结束日期并不包含在这个日期范围。在遍历的时候,判断条件为 first_day < last_day,不输出 last_day 的值,以 timedelta 实例进行递增日期。
参考资料
来源
David M. Beazley;Brian K. Jones.Python Cookbook, 3rd Edtioni.O'Reilly Media.2013.
"8.1. datetime — Basic date and time types".docs.python.org.Retrieved 11 January 2020
"8.2. calendar — General calendar-related functions".docs.python.org.Retrieved 13 January 2020
来源:https://segmentfault.com/a/1190000021592489


猜你喜欢
- 十六进制(Hexadecimal)是计算机中数据的一种表示方法。同日常生活中的表示法不一样,它由0-9,A-F组成,字母不区分大小写。与10
- 发现问题比解决问题重要,使用php集成开发环境Appserv网页会提示各种语法错误,但自己配置开发环境无法提示错误,特别当不是语法错误,比如
- Vue的项目中,如果项目简单, 父子组件之间的数据传递可以使用 props 或者 $emit 等方式 进行传递但是如果是大中型项目中,很多时
- 之前一直在写有关scrapy爬虫的事情,今天我们看看使用scrapy如何把爬到的数据放在MySQL数据库中保存。有关python操作MySQ
- python封装利用begin end执行多条sql因为业务需求,优化模型运行时间。考虑到sql语句每一次执行都要建立连接,查询,获取数据耗
- 今天我想和大家分享 4 个省时的 Python 技巧,可以节省 10~20% 的 Python 执行时间。反转列表Python 中通常有两种
- 本篇文章主要基于python语言和OpenCV库(cv2)进行车牌区域识别和字符分割,开篇之前针对在python中安装opencv的环境这里
- 什么是双端队列双端队列是与队列类似的有序集合。它有一前、一后两端,元素在其中保持自己的位置。与队列不同的是,双端队列对在哪一端添加和移除元素
- 环境:pyecharts库,echarts-countries-pypkg,echarts-china-provinces-pypkg,ec
- 当然,页面最好不要刷新,但是,拷贝一下浏览器的链接,又希望是下次能定位到你播发的那个视频。方法很简单,改变一下 url 的 fragment
- 目前很多软件都限制单实例,大多数软件都是用Mutex来实现的 而这个东西咱们可以用handle去干掉它,并且不影响使用。 钉钉也是一样的步骤
- 本文实例讲述了MySql采用GROUP_CONCAT合并多条数据显示的方法,分享给大家供大家参考。具体实现方法如下:假设有这样一个需求:1:
- 分享人:轻侯设计师常有这样的疑惑:如何知道用户浏览网页的习惯?如何设计出符合用户使用习惯的网页?如何从搜索引擎带来更多的流量?眼动研究可以帮
- 前言只统计像素的灰度值这一特征,可将其成为一维直方图。二维直方图可以统计像素的色相和饱和度,用于查找图像的颜色直方图。一、OpenCV中的二
- 前几天,在所有数据库服务器部署了监控磁盘空间的存储过程和作业后(MS SQL 监控磁盘空间告警),今天突然收到了两封告警邮件,好吧,存储规划
- Python实现12306火车票抢票系统效果图如下所示:具体代码如下所示:import urllib.request as request
- 一、函数解释在torch/_C/_VariableFunctions.py的有该定义,意义就是实现一下公式:换句话说,就是需要传入5个参数,
- 1. 写在前面今天整理OpenCV入门的第三个实战小项目,前面的两篇文章整理了信用卡数字识别以及文档OCR扫描, 大部分用到的是OpenCV
- 在已有的shapefile文件的基础上增加字段: # -*- coding:gb2312 -*-import shapefiler=shap
- function AutomateExcel() { try { //Start Excel and get Application obj