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中使用OpenCV进行人脸检测的例子
Apr 18 Python
Python封装shell命令实例分析
May 05 Python
使用py2exe在Windows下将Python程序转为exe文件
Mar 04 Python
python实现简单遗传算法
Mar 19 Python
TensorFlow损失函数专题详解
Apr 26 Python
python获取程序执行文件路径的方法(推荐)
Apr 26 Python
python多进程使用及线程池的使用方法代码详解
Oct 24 Python
FFrpc python客户端lib使用解析
Aug 24 Python
python递归下载文件夹下所有文件
Aug 31 Python
python 采用paramiko 远程执行命令及报错解决
Oct 21 Python
关于Keras模型可视化教程及关键问题的解决
Jan 24 Python
Python2与Python3的区别详解
Feb 09 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
用PHP伪造referer突破网盘禁止外连的代码
2008/06/15 PHP
php使用指定字符列表生成随机字符串的方法
2015/04/18 PHP
Yii框架实现记录日志到自定义文件的方法
2017/05/23 PHP
php中的依赖注入实例详解
2019/08/14 PHP
今天是星期几的4种JS代码写法
2013/09/17 Javascript
利用js实现前台动态添加文本框,后台获取文本框内容(示例代码)
2013/11/25 Javascript
jquery获得同源iframe内body下标签的值的方法
2014/09/25 Javascript
jQuery仿Flash上下翻动的中英文导航菜单实例
2015/03/10 Javascript
js代码实现无缝滚动(文字和图片)
2015/08/20 Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
2016/09/17 Javascript
JavaScript限制在客户区可见范围的拖拽(解决scrollLeft和scrollTop的问题)(2)
2017/05/17 Javascript
jsTree事件和交互以及插件plugins详解
2017/08/29 Javascript
JavaScript中递归实现的方法及其区别
2017/09/12 Javascript
Vue中的Props(不可变状态)
2018/09/29 Javascript
vue-cli脚手架引入弹出层layer插件的几种方法
2019/06/24 Javascript
React+Redux实现简单的待办事项列表ToDoList
2019/09/29 Javascript
vue实现购物车的监听
2020/04/20 Javascript
springboot+vue+对接支付宝接口+二维码扫描支付功能(沙箱环境)
2020/10/15 Javascript
[02:02:38]VG vs Mineski Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
[01:47]2018年度DOTA2最佳教练-完美盛典
2018/12/16 DOTA
Python中atexit模块的基本使用示例
2015/07/08 Python
通过实例了解python property属性
2019/11/01 Python
Python Print实现在输出中插入变量的例子
2019/12/25 Python
图解Python中深浅copy(通俗易懂)
2020/09/03 Python
matplotlib绘制多子图共享鼠标光标的方法示例
2021/01/08 Python
柒牌官方商城:中国男装优秀品牌
2017/06/30 全球购物
英国时尚泳装品牌:Maru Swimwear
2019/10/06 全球购物
美国一站式电动和手动工具商店:International Tool
2020/11/26 全球购物
什么是Rollback Segment
2013/04/22 面试题
大学生的网上创业计划书
2013/12/31 职场文书
教学器材管理制度
2014/01/26 职场文书
小区门卫岗位职责范本
2014/08/24 职场文书
学习优秀党务工作者先进事迹材料思想报告
2014/09/17 职场文书
因工资原因离职的辞职信范文
2015/05/12 职场文书
起诉意见书范文
2015/05/19 职场文书
gateway网关接口请求的校验方式
2021/07/15 Java/Android