在 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 对象,只在与用户交互时做字符串格式转换,就能少踩很多坑。