Menu

Python datetime:日期、时间、时间差和时区

Python datetime 模块实用指南:解析、格式化、对日期做运算,以及不再被时区绕晕的处理方法。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

两个核心类型:date 和 datetime

datetime 模块提供了四样值得了解的东西:date、time、datetime 和 timedelta。前三个就是字面意思;第四个表示一段时间。

date 表示某一天,也就是年、月、日,不带时钟时间。datetime 是日期加上时间。如果你不需要时钟时间,date 是更简洁的选择。

创建指定的日期

直接构造:

date 的参数是 year, month, day,datetime 的参数最多可以到 year, month, day, hour, minute, second, microsecond。

读取各个字段

每个 date 或 datetime 都有这些属性:

要输出机器可读的内容,isoformat() 是你的好帮手:它生成类似 "2026-04-20T09:30:15" 的字符串,其他系统可以毫无歧义地解析。

用 strftime 格式化

要输出给人看的内容,.strftime(fmt) 能把 date 或 datetime 变成格式化的字符串:

最值得记住的格式代码:

  • %Y:4 位年份(2026)
  • %m:月份数字,不足两位补零(04)
  • %d:月份中的第几天,不足两位补零(20)
  • %H / %I:小时,24 小时制 / 12 小时制
  • %M:分钟
  • %S:秒
  • %A / %a:星期名称,完整 / 缩写(Monday / Mon)
  • %B / %b:月份名称,完整 / 缩写(April / Apr)
  • %p:AM/PM

你不需要把它们背下来;把一份参考资料加入书签,需要时查一下就行。

用 strptime 解析

反过来:把一个格式已知的字符串变成 datetime:

格式字符串必须和输入完全匹配。如果不匹配,strptime 会抛出 ValueError。

对于 ISO-8601 字符串(机器可读的标准格式),新版本的 Python 有一个更简单的快捷方式:

如果你要处理五花八门的格式,第三方的 dateutil 包(pip install python-dateutil)提供了一个很宽容的 parser.parse(),它会做出合理的猜测。

用 timedelta 做运算

要对日期做运算,就用 timedelta 表示差值或偏移量:

timedelta 的参数有:days、seconds、microseconds、milliseconds、minutes、hours、weeks。没有 months 和 years,因为每个月的长度不一样。按月或按年计算,请用 dateutil.relativedelta:

from dateutil.relativedelta import relativedelta
from datetime import date

today = date.today()
next_quarter = today + relativedelta(months=3)
print(next_quarter)

时区:naive 与 aware

不带时区信息的 datetime 是 naive(朴素)的,Python 不知道它代表哪个时区。只要你一直待在同一个逻辑时区内,对 naive datetime 做时间运算是没问题的;一旦来自不同时区的数据碰到一起,麻烦就来了。

aware(感知时区)的 datetime 自带时区信息。显式地加上时区:

Python 3.9 新增了 zoneinfo 模块,用于按名称指定时区(使用系统的 IANA 数据库):

用 .astimezone() 在时区之间转换:

有一条规则值得牢记:以 UTC 存储 datetime,只在显示时才转换为本地时区。仅这一个习惯就能避免大多数时区 bug。

时间戳

Unix 时间戳是从 1970-01-01 UTC 起经过的秒数。Python 可以轻松地转换:

时间戳适合用来比较、排序,以及和其他系统交互。要输出给人看,先把它转换回 datetime。

测量某件事花了多长时间

要快速计时,把两个 datetime 相减:

要做更严肃的性能测量,请用 time.perf_counter():它的精度高于微秒级,而且不受系统时钟调整的影响。对于“这次 API 调用花了多久”这类数字,datetime.now() 就够用了。

你会反复用到的写法

要点回顾

  • date、datetime 和 timedelta 能满足 90% 的需求。
  • 机器可读用 ISO-8601;人类可读用 strftime。
  • 以 UTC 存储;显示时再转换。
  • 按名称指定时区用 zoneinfo。
  • 按月和按年计算,用 dateutil.relativedelta。

你的实用工具箱里还差一样工具:正则表达式,下一篇就讲。

常见问题

在 Python 中怎么获取当前的日期和时间?

datetime.now() 返回当前的本地日期和时间。datetime.utcnow() 返回 UTC 时间(不过现在更推荐用 datetime.now(timezone.utc),因为 utcnow() 返回的是不带时区的 datetime)。如果只要日期,就用 date.today()。

怎么把日期格式化成字符串?

使用 .strftime(format),配合格式代码,比如表示年-月-日的 %Y-%m-%d。例如:datetime.now().strftime('%Y-%m-%d %H:%M')。要把字符串解析回来,就用 datetime.strptime(text, format),格式代码相同。

在 Python 中怎么给日期加上几天?

使用 timedelta:from datetime import date, timedelta; date.today() + timedelta(days=7)。timedelta 支持天、小时、分钟、秒、周等单位。按月和按年计算,请用第三方的 dateutil.relativedelta,timedelta 不认识月份。

Coddy 编程语言插图

和 Coddy 一起学编程

开始