Python 日期的转换及计算的具体使用详解


Posted in Python onJanuary 16, 2020

日期的转换及计算

对于日期,有时需执行不同时间单位的转换,或者接受字符串格式的日期,转换为 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 实例进行递增日期。

参考资料

来源

  1. David M. Beazley;Brian K. Jones.Python Cookbook, 3rd Edtioni.O'Reilly Media.2013.
  2. "8.1. datetime — Basic date and time types".docs.python.org.Retrieved 11 January 2020
  3. "8.2. calendar — General calendar-related functions".docs.python.org.Retrieved 13 January 2020

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python学习之asyncore模块用法实例教程
Sep 29 Python
python登录并爬取淘宝信息代码示例
Dec 09 Python
Python3中的json模块使用详解
May 05 Python
Django读取Mysql数据并显示在前端的实例
May 27 Python
python 搜索大文件的实例代码
Jul 08 Python
python psutil监控进程实例
Dec 17 Python
python新手学习使用库
Jun 11 Python
python实现xlwt xlrd 指定条件给excel行添加颜色
Jul 14 Python
Python 发送邮件方法总结
Aug 10 Python
python中翻译功能translate模块实现方法
Dec 17 Python
一劳永逸彻底解决pip install慢的办法
May 24 Python
详解Python生成器和基于生成器的协程
Jun 03 Python
Python使用循环神经网络解决文本分类问题的方法详解
Jan 16 #Python
win10安装tesserocr配置 Python使用tesserocr识别字母数字验证码
Jan 16 #Python
Python通过VGG16模型实现图像风格转换操作详解
Jan 16 #Python
Python使用turtle库绘制小猪佩奇(实例代码)
Jan 16 #Python
PyCharm汉化安装及永久激活详细教程(靠谱)
Jan 16 #Python
python如何使用Redis构建分布式锁
Jan 16 #Python
Python中url标签使用知识点总结
Jan 16 #Python
You might like
常用星际术语索引(新手指南)
2020/03/04 星际争霸
phpmyadmin中配置文件现在需要绝密的短语密码的解决方法
2007/02/11 PHP
php使用simplexml_load_file加载XML文件并显示XML的方法
2015/03/19 PHP
js对象之JS入门之Array对象操作小结
2011/01/09 Javascript
基于jQuery的前端数据通用验证库
2011/08/08 Javascript
jquery内置验证(validate)使用方法示例(表单验证)
2013/12/04 Javascript
JS字符串拼接在ie中都报错的解决方法
2014/03/27 Javascript
jQuery学习笔记之jQuery.fn.init()的参数分析
2014/06/09 Javascript
Javascript函数的参数
2015/07/16 Javascript
JavaScript 判断一个对象{}是否为空对象的简单方法
2016/10/09 Javascript
原生js编写焦点图效果
2016/12/08 Javascript
Express之get,pos请求参数的获取
2017/05/02 Javascript
微信小程序switch组件使用详解
2018/01/31 Javascript
bootstrap 弹出框modal添加垂直方向滚轴效果
2018/07/09 Javascript
微信小程序实现自动定位功能
2018/10/31 Javascript
Nodejs模块的调用操作实例分析
2018/12/25 NodeJs
element-ui 远程搜索组件el-select在项目中组件化的实现代码
2019/12/04 Javascript
Javascript实现打鼓效果
2021/01/29 Javascript
[55:44]完美世界DOTA2联赛决赛 FTD vs Phoenix 第二场 11.08
2020/11/11 DOTA
python实现删除文件与目录的方法
2014/11/10 Python
python实现的简单RPG游戏流程实例
2015/06/28 Python
Python实现的微信公众号群发图片与文本消息功能实例详解
2017/06/30 Python
Django内容增加富文本功能的实例
2017/10/17 Python
Python 判断文件或目录是否存在的实例代码
2018/07/19 Python
python 列表递归求和、计数、求最大元素的实例
2018/11/28 Python
python中hasattr()、getattr()、setattr()函数的使用
2019/08/16 Python
python GUI计算器的实现
2020/10/09 Python
CSS3 渐变(Gradients)之CSS3 线性渐变
2016/07/08 HTML / CSS
CSS3制作Dropdown下拉菜单的方法
2015/07/18 HTML / CSS
HTML5+CSS3实例 :canvas 模拟实现电子彩票刮刮乐代码
2016/12/30 HTML / CSS
webView加载html图片遇到的问题解决
2019/10/08 HTML / CSS
大学生表扬信范文
2014/01/09 职场文书
经典英文广告词
2014/03/18 职场文书
python3实现Dijkstra算法最短路径的实现
2021/05/12 Python
解决numpy和torch数据类型转化的问题
2021/05/23 Python
FFmpeg视频处理入门教程(新手必看)
2022/01/22 杂记