日期的转换及计算

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

参考资料

来源

David M. Beazley;Brian K. Jones.Python Cookbook, 3rd Edtioni.O'Reilly Media.2013.

"8.1. datetime — Basic date and time types".docs.python.org.Retrieved 11 January 2020

"8.2. calendar — General calendar-related functions".docs.python.org.Retrieved 13 January 2020

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持聚米学院。

python日期计算,Python 日期的转换及计算的具体使用详解相关推荐

  1. python计算各类型电影的评分_【Python数据科学实战项目】之 基于MovieLens的影评趋势分析|详解...

    原标题:[Python数据科学实战项目]之 基于MovieLens的影评趋势分析|详解 注:图片源于https://movielens.org/ 1. 项目任务 1.1 数据来源 本项目使用Group ...

  2. [python opencv 计算机视觉零基础到实战] 四、了解色彩空间及其详解

    一.学习目标 了解什么是色彩空间 了解opencv中色彩空间的转换 目录 [python opencv 计算机视觉零基础到实战] 一.opencv的helloworld [[python opencv ...

  3. 基于点击量的趋势分析python_【Python数据科学实战项目】之 基于MovieLens的影评趋势分析详解...

    原标题:[Python数据科学实战项目]之 基于MovieLens的影评趋势分析详解 本文转自: 数据科学DataScience 注:图片源于https://movielens.org/ 1. 项目任 ...

  4. Python的Django框架中forms表单类的使用方法详解2

    用户表单是Web端的一项基本功能,大而全的Django框架中自然带有现成的基础form对象,本文就Python的Django框架中forms表单类的使用方法详解. Form表单的功能 自动生成HTML ...

  5. python调用shell脚本的参数_使用python执行shell脚本 并动态传参 及subprocess的使用详解

    最近工作需求中 有遇到这个情况 在web端获取配置文件内容 及 往shell 脚本中动态传入参数 执行shell脚本这个有多种方法 最后还是选择了subprocess这个python标准库 subpr ...

  6. python整数池_对Python中小整数对象池和大整数对象池的使用详解

    1. 小整数对象池 整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池, 避免为整数频繁申请和销毁内存空间. Python 对小整数的定义是 [-5, 256] 这些整数对象是提 ...

  7. 站长在线Python精讲:在Python中使用split()方法分割、使用join()方法合并字符串详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<在Python中使用split()方法分割.使用join()方法合并字符串详解>.本知识点主要内容有:在Python中使用s ...

  8. 用windows系统下的DOS命令将腾讯视频客户端下载的qlv文件转换成MP4格式(图文详解)

    用windows系统下的DOS命令将腾讯视频客户端下载的qlv文件转换成MP4格式(图文详解) 前言 原理 工具 步骤 延伸 博主联系方式 前言 本人喜欢收集各种优秀的视频,但是很多情况下我们看到的视 ...

  9. 站长在线Python精讲:Python中字符串编码转换encode编码和decode解码详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<Python中字符串编码转换:encode编码和decode解码详解>.本知识点主要内容有:常用编码简介.使用encode( ...

  10. python爬虫常见报错_Python爬虫常见HTTP响应状态码详解

    在使用Python进行网页数据抓取时,经常会遇到无数据返还或错误等异常,这个时候可以通过status_code命令来查看获得http请求返回的状态码,以便查找原因并制定相应的解决方案.import r ...

最新文章

  1. 自动驾驶软件工程课程之SLAM(1)
  2. windows XP下DCOM的权限配置
  3. java实现邮件发送准备工作(前期配置)
  4. Neutorn LBaaS 原理
  5. 容器编排技术 -- 使用Vagrant本地运行Kubernetes
  6. 设计模式学习笔记——状态(State)模式框架
  7. delphi7 如何判定dbgrid两行重复_良渚文化陶器上的图案、符号和文字(5)良渚文化陶器上文字的判定...
  8. Kafka的架构设计
  9. 常见的通配符_8、数据库常见操作
  10. 【量产】波士顿动力机器狗,当警犬不错,上战场。。。
  11. 使用递归判断二叉树对称
  12. [Swust OJ 188]--异面空间(读懂题意很重要)
  13. IOC容器-Autofac在MVC中实现json方式注入使用
  14. FT5X06 如何应用在10寸电容屏
  15. Excel表格中正数设置为红色负为绿色
  16. 用友U9破解装备制造业信息化世界级难题
  17. vulnhub-Tiki - 类oscp靶机攻略1
  18. 巅峰对决!2020人工智能创新创业大赛总决赛评委阵容、项目亮点震撼揭晓
  19. 独家-县域统计年鉴Excel版(2000-2021年)-包含县市及乡镇卷
  20. Asterisk支持通话录音前语音提示

热门文章

  1. 通过监听手势滑动解决DrawerLayout只能边缘打开抽屉问题
  2. MATLAB音频数字水印算法实现
  3. 引央视主播康辉大笑的度晓晓,是个只会吹彩虹屁的 AI 助手吗?
  4. Typora怎么将文本居中
  5. c语言编程输出等腰三角形,C语言输出等腰三角形
  6. Java——线程回顾汇总:同步/生产者消费者模式/定时调度
  7. 《精益创业》读书笔记
  8. MFC 资源脚本问题:fatal error CVT1100: 资源重复。类型: AFX DIALOG LAYOUT
  9. 巴斯大学计算机世界专业排名,2019上海软科世界一流学科排名计算机科学与工程专业排名巴斯大学排名第301-400...
  10. 【贪玩巴斯】传感器与检测技术 (二)「半导体传感器基础」2021-09-30