人人都会AI编程

14.2 datetime 模块:日期、时间、时间差、时区处理

更新时间:2026-07-12

在 Python 里,处理日期和时间最常用的就是标准库中的 datetime 模块。它提供了四个核心类来分别表达不同类型的日期时间对象,以及一个用于表示时间差的类。这一节只讲你最可能用到的部分,不堆砌冷门内容。

核心类与创建对象

  • datetime.date:只包含年月日。
    from datetime import date
    d = date(2025, 3, 27)        # 2025-03-27
    d.year, d.month, d.day       # (2025, 3, 27)
    date.today()                 # 获取当天日期
    
  • datetime.time:只包含时分秒、微秒及时区(一般不单独使用)。
    from datetime import time
    t = time(14, 30, 45)         # 14:30:45
    
  • datetime.datetime:最常用,包含日期和时间。
    from datetime import datetime
    dt = datetime(2025, 3, 27, 14, 30, 45)   # 2025-03-27 14:30:45
    datetime.today()                         # 当前本地日期时间(不含时区)
    datetime.now()                           # 当前本地日期时间(可选时区)
    datetime.now(tz=timezone.utc)            # 当前 UTC 时间
    
  • datetime.timedelta:表示两个日期/时间之间的差值,或一段时间。
    from datetime import timedelta
    delta = timedelta(days=7, hours=2)       # 7天2小时
    # 支持常用单位:days, seconds, microseconds, minutes, hours, weeks
    

日期时间运算

时间计算的核心就是用 datetime 对象加上或减去 timedelta 对象。

from datetime import datetime, timedelta

now = datetime.now()
yesterday = now - timedelta(days=1)
in_a_week = now + timedelta(weeks=1)
one_hour_later = now + timedelta(hours=1)

# 两个 datetime 相减得到 timedelta
delta = datetime(2025, 4, 1) - datetime(2025, 3, 27)
print(delta.days)     # 5
print(delta.seconds)  # 0(因为只相差整天)

时间格式化与解析

实际开发中,经常要在字符串和 datetime 对象之间转换。

  • strftime:格式化输出。
  • strptime:从字符串解析。
from datetime import datetime

# 格式化成字符串
dt = datetime(2025, 3, 27, 14, 30)
s = dt.strftime('%Y-%m-%d %H:%M:%S')   # "2025-03-27 14:30:00"
s2 = dt.strftime('%B %d, %Y')          # "March 27, 2025"

# 从字符串解析
dt2 = datetime.strptime("2025-03-27 14:30:00", "%Y-%m-%d %H:%M:%S")
# 注意:格式必须完全匹配

常用格式代码速查:

| 代码 | 含义 | 示例 |
|------|------------------|---------|
| %Y | 四位年份 | 2025 |
| %m | 月份(零填充) | 03 |
| %d | 日期(零填充) | 27 |
| %H | 小时(24小时制) | 14 |
| %M | 分钟 | 30 |
| %S | 秒 | 00 |
| %f | 微秒 | 000000 |
| %A | 星期全称 | Monday |
| %B | 月份全称 | March |
| %I | 小时(12小时制) | 02 |
| %p | AM/PM | PM |

时区处理

在 Python 3.9+ 中,推荐使用内置的 zoneinfo 模块(标准库)处理时区;之前版本常用 pytz 第三方库。下面以 zoneinfo 为例。

from datetime import datetime, timezone
from zoneinfo import ZoneInfo

# 创建带时区的当前时间
utc_now = datetime.now(tz=timezone.utc)      # UTC 时间
cn_now = datetime.now(tz=ZoneInfo("Asia/Shanghai"))  # 北京时间

# 不同时区的转换
utc = datetime(2025, 3, 27, 6, 0, tzinfo=timezone.utc)
beijing = utc.astimezone(ZoneInfo("Asia/Shanghai"))  # 2025-03-27 14:00:00+08:00
tokyo = utc.astimezone(ZoneInfo("Asia/Tokyo"))       # 2025-03-27 15:00:00+09:00

实际建议

  • 数据库或 API 传递时间时,统一用 UTC 时间存储,避免时区混乱。
  • 在前端展示时,再根据用户时区转换成本地时间。
  • 计算时间间隔时,尽量用带时区的 datetime 对象,以免因为夏令时等问题出错。

常用便捷方法

# 获取时间戳(秒数)
ts = datetime.now().timestamp()

# 时间戳转 datetime
datetime.fromtimestamp(ts)          # 本地时间
datetime.utcfromtimestamp(ts)       # UTC 时间(已弃用,建议用 fromtimestamp 带时区)

# ISO 8601 格式
iso_str = datetime.now().isoformat()   # "2025-03-27T14:30:00"
datetime.fromisoformat(iso_str)       # 解析 ISO 格式字符串

典型场景

示例1:活动剩余天数

from datetime import date

event_date = date(2025, 6, 1)
today = date.today()
remaining = (event_date - today).days
print(f"距离活动还有 {remaining} 天")

示例2:日志时间解析

from datetime import datetime

log_line = "2025-03-27 14:32:10 ERROR Something failed"
# 提取时间部分并解析
timestamp_str = log_line[:19]
log_time = datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M:%S")

以上这些是你日常开发中 90% 会碰到的 datetime 用法。记住一个原则:所有存储和计算尽量用 datetime 对象,只在与用户交互时做字符串格式转换,就能少踩很多坑。