Python 日期处理:datetime 模块转换、计算与性能优化

Finn
Finn
发布时间:2026-10-13| 5人浏览过
原创

本文详解 Python 中 datetime 模块的核心用法,涵盖时间段的 timedelta 创建、日期加减运算及闰年处理。重点解析字符串与 datetime 对象的相互转换,通过 strptime 和 strftime 实现格式化。针对大量固定格式日期解析的性能瓶颈,提供自定义 parse_ymd 方案,实测速度提升 7 倍。最后结合 calendar 模块实现月份日期范围遍历,适用于各类日期处理场景。

Python 日期处理概述

日期的转换及计算

在实际开发中,经常需要对不同时间单位进行转换,或将字符串格式的日期解析为 datetime 对象。此外,还需计算日期区间或查找特定星期几的日期。这些操作主要依赖 Python 内置的 datetime 模块。

datetime 模块

datetime 基础:时间段与日期运算

日期与时间的简单转换

在 datetime 模块中,可以使用 timedelta 对象来表示一段时间跨度。以下示例展示了如何创建和使用 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 倍以上。若需处理大量格式固定的日期,建议采用此方案。

利用 calendar 模块计算月份日期范围

计算某个月份的日期范围

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 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。