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应用程序在windows下不出现cmd窗口的办法
May 29 Python
python中(str,list,tuple)基础知识汇总
Feb 20 Python
解决python3捕获cx_oracle抛出的异常错误问题
Oct 18 Python
python把转列表为集合的方法
Jun 28 Python
Python学习笔记之Break和Continue用法分析
Aug 14 Python
pytorch 改变tensor尺寸的实现
Jan 03 Python
python十进制转二进制的详解
Feb 07 Python
python实现猜数游戏(保存游戏记录)
Jun 22 Python
keras输出预测值和真实值方式
Jun 27 Python
python 利用zmail库发送邮件
Sep 11 Python
vue.js刷新当前页面的实例讲解
Dec 29 Python
Pytorch 实现变量类型转换
May 17 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
mysql 性能的检查和优化方法
2009/06/21 PHP
回帖脱衣服的图片实现代码
2014/02/15 PHP
php使用数组填充下拉列表框的方法
2015/03/31 PHP
学习php设计模式 php实现享元模式(flyweight)
2015/12/07 PHP
php中的异常和错误浅析
2017/05/03 PHP
深入浅析PHP的session反序列化漏洞问题
2017/06/15 PHP
PHP lcfirst()函数定义与用法
2019/03/08 PHP
摘自百度的图片轮换效果代码
2007/11/19 Javascript
extjs 列表框(multiselect)的动态添加列表项的方法
2009/07/31 Javascript
jQuery 美元符冲突的解决方法
2010/03/28 Javascript
jQuery前台数据获取实现代码
2011/03/16 Javascript
深入理解JavaScript系列(49):Function模式(上篇)
2015/03/04 Javascript
省市联动效果的简单实现代码(推荐)
2016/06/06 Javascript
简单理解js的冒泡排序
2016/12/19 Javascript
angular.js指令中transclude选项及ng-transclude指令详解
2017/05/24 Javascript
JavaScript 截取字符串代码实例
2019/09/05 Javascript
jQuery实现的分页插件完整示例
2020/05/26 jQuery
python通过BF算法实现关键词匹配的方法
2015/03/13 Python
Python中偏函数用法示例
2018/06/07 Python
python2.x实现人民币转大写人民币
2018/06/20 Python
详解Python二维数组与三维数组切片的方法
2019/07/18 Python
Django url,从一个页面调到另个页面的方法
2019/08/21 Python
Python GUI库PyQt5图形和特效样式QSS介绍
2020/02/25 Python
英国最大的宝石首饰超市:QP Jewellers
2018/09/23 全球购物
Dr. Martens马汀博士法国官网:马丁靴鼻祖
2020/01/15 全球购物
非常详细的C#面试题集
2016/07/13 面试题
Unix如何在一行中运行多个命令
2015/05/29 面试题
预备党员思想汇报
2014/01/08 职场文书
运动会跳远加油稿
2014/02/20 职场文书
超市中秋节促销方案
2014/03/21 职场文书
劳资协议书范本
2014/04/23 职场文书
导师评语大全
2014/04/26 职场文书
教育局党的群众路线教育实践活动整改方案
2014/09/20 职场文书
少先队工作总结2015
2015/05/13 职场文书
警示教育片观后感
2015/06/17 职场文书
法定授权委托证明书
2015/06/18 职场文书