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两种遍历字典(dict)的方法比较
May 29 Python
Python中除法使用的注意事项
Aug 21 Python
python下10个简单实例代码
Nov 15 Python
详解Python下ftp上传文件linux服务器
Jun 21 Python
OpenCV+python手势识别框架和实例讲解
Aug 03 Python
Django中日期处理注意事项与自定义时间格式转换详解
Aug 06 Python
python flask安装和命令详解
Apr 02 Python
Python读取实时数据流示例
Dec 02 Python
15行Python代码实现免费发送手机短信推送消息功能
Feb 27 Python
Python私有属性私有方法应用实例解析
Sep 15 Python
python实现马丁策略的实例详解
Jan 15 Python
Python中的socket网络模块介绍
Jul 23 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
Linux环境下php实现给网站截图的方法
2016/05/03 PHP
解决PHP 7编译安装错误:cannot stat ‘phar.phar’: No such file or directory
2017/02/25 PHP
Laravel5中Cookie的使用详解
2017/05/03 PHP
PHP自定义函数实现assign()数组分配到模板及extract()变量分配到模板功能示例
2018/05/23 PHP
php查询内存信息操作示例
2019/05/09 PHP
javascript各种复制代码收集
2008/09/20 Javascript
return false,对阻止事件默认动作的一些测试代码
2010/11/17 Javascript
js 实现在离开页面时提醒未保存的信息(减少用户重复操作)
2013/01/16 Javascript
jQuery ajax(复习)—Baidu ajax request分离版
2013/01/24 Javascript
jquery ajax应用中iframe自适应高度问题解决方法
2014/04/12 Javascript
javascript实现随机读取数组的方法
2015/08/03 Javascript
解析Node.js异常处理中domain模块的使用方法
2016/02/16 Javascript
jQuery代码实现对话框右上角菜单带关闭×
2016/05/03 Javascript
Bootstrap布局之栅格系统详解
2016/06/13 Javascript
JS实现微信里判断页面是否被分享成功的方法
2017/06/06 Javascript
jQuery.form.js的使用详解
2017/06/14 jQuery
通俗解释JavaScript正则表达式快速记忆
2017/08/23 Javascript
JS验证码实现代码
2017/09/14 Javascript
vue登录注册及token验证实现代码
2017/12/14 Javascript
js prototype深入理解及应用实例分析
2019/11/25 Javascript
解决echarts图表使用v-show控制图表显示不全的问题
2020/07/19 Javascript
JS pushlet XMLAdapter适配器用法案例解析
2020/10/16 Javascript
python访问类中docstring注释的实现方法
2015/05/04 Python
Python 结巴分词实现关键词抽取分析
2017/10/21 Python
Python文本特征抽取与向量化算法学习
2017/12/22 Python
Python中使用支持向量机(SVM)算法
2017/12/26 Python
对python生成业务报表的实例详解
2019/02/03 Python
python3.6下Numpy库下载与安装图文教程
2019/04/02 Python
python爬虫爬取幽默笑话网站
2019/10/24 Python
《春到梅花山》教学反思
2014/04/16 职场文书
小学生期末评语大全
2014/04/21 职场文书
安全教育月活动总结
2014/05/05 职场文书
群众路线教育实践活动自我剖析思想汇报
2014/10/04 职场文书
司法局群众路线教育实践活动开展情况总结
2014/10/25 职场文书
新闻稿怎么写
2015/07/18 职场文书
手把手教你怎么用Python实现zip文件密码的破解
2021/05/27 Python