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中urllib模块用法实例详解
Nov 19 Python
Python实现信用卡系统(支持购物、转账、存取钱)
Jun 24 Python
视觉直观感受若干常用排序算法
Apr 13 Python
利用python实现xml与数据库读取转换的方法
Jun 17 Python
python用户评论标签匹配的解决方法
May 31 Python
Python 爬取携程所有机票的实例代码
Jun 11 Python
Python WEB应用部署的实现方法
Jan 02 Python
python selenium执行所有测试用例并生成报告的方法
Feb 13 Python
python自定义时钟类、定时任务类
Feb 22 Python
python爬虫开发之使用python爬虫库requests,urllib与今日头条搜索功能爬取搜索内容实例
Mar 10 Python
Django 删除upload_to文件的步骤
Mar 30 Python
python​格式化字符串
Apr 20 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
咖啡的化学
2021/03/03 咖啡文化
如何在PHP中使用Oracle数据库(5)
2006/10/09 PHP
PHP仿博客园 个人博客(2) 数据库增添改删
2013/07/05 PHP
php通过function_exists检测函数是否存在的方法
2015/03/18 PHP
php封装的smartyBC类完整实例
2016/10/19 PHP
对采用动态原型方式无法展示继承机制得思考
2009/12/04 Javascript
jQuery的强大选择器小结
2009/12/27 Javascript
来自国外的页面JavaScript文件优化
2010/12/08 Javascript
利用javascript打开模态对话框(示例代码)
2014/01/11 Javascript
js加载读取内容及显示与隐藏div示例
2014/02/13 Javascript
JQuery弹出层示例可自定义
2014/05/19 Javascript
深入浅析JavaScript字符串操作方法 slice、substr、substring及其IE兼容性
2015/12/16 Javascript
基于JavaScript实现跳转提示页面
2016/09/24 Javascript
vue2.0全局组件之pdf详解
2017/06/26 Javascript
将Sublime Text 3 添加到右键中的简单方法
2017/12/12 Javascript
Bootstrap导航菜单点击后无法自动添加active的处理方法
2018/08/10 Javascript
jQuery模仿ToDoList实现简单的待办事项列表
2019/12/30 jQuery
Node.js API详解之 Error模块用法实例分析
2020/05/14 Javascript
JavaScript实现简单日历效果
2020/09/11 Javascript
python中Matplotlib实现绘制3D图的示例代码
2017/09/04 Python
python 输出上个月的月末日期实例
2018/04/11 Python
Python 中的Selenium异常处理实例代码
2018/05/03 Python
python tkinter canvas 显示图片的示例
2019/06/13 Python
Python:type、object、class与内置类型实例
2019/12/25 Python
Python实例教程之检索输出月份日历表
2020/12/16 Python
宏碁西班牙官网:Acer西班牙
2021/01/08 全球购物
升职自荐信范文
2013/10/05 职场文书
应付会计岗位职责
2013/12/12 职场文书
员工评语大全
2014/01/19 职场文书
安全横幅标语
2014/06/09 职场文书
镇副书记专题民主生活会对照检查材料思想汇报
2014/10/02 职场文书
学校政风行风自查自纠报告
2014/10/21 职场文书
简易离婚协议书(范本)
2014/10/25 职场文书
卖车协议书范文
2016/03/23 职场文书
PHP对接阿里云虚拟号的实现(号码隐私保护)
2021/04/06 PHP
CSS3 制作精美的定价表
2021/04/06 HTML / CSS