Datetime (日期时间)
官方文档: https://docs.python.org/zh-cn/3.12/library/datetime.html
| 类型 | 说明 |
|---|---|
| datetime.datetime | 日期 + 时间(最常用) |
| datetime.date | 只有日期 |
| datetime.time | 只有时间 |
| datetime.timedelta | 时间差 |
最常用的是 datetime.datetime。
from datetime import datetime
now = datetime.now()
utc_now = datetime.utcnow()
⚠️ utcnow() 返回“天真时间”(无时区)。
字符串 -> datetime(解析)
from datetime import datetime
dt = datetime.strptime("2025-06-24 10:30:00", "%Y-%m-%d %H:%M:%S")
datetime -> 字符串(格式化)
s = dt.strftime("%Y-%m-%d %H:%M:%S")
常见格式化标记:
| 标记 | 含义 |
|---|---|
| %Y | 4位年份 |
| %m | 月 |
| %d | 日 |
| %H | 小时 |
| %M | 分钟 |
| %S | 秒 |
| %f | 微秒 |
from datetime import timedelta
yesterday = datetime.now() - timedelta(days=1)
after_30_min = datetime.now() + timedelta(minutes=30)
dt = datetime.now()
date_part = dt.date() # datetime.date
time_part = dt.time() # datetime.time
year = dt.year
month = dt.month
day = dt.day
hour = dt.hour
minute = dt.minute
second = dt.second
日期
from datetime import date
d = date(2025, 6, 24)
时间
from datetime import time
t = time(14, 30, 0)
日期 + 时间
from datetime import datetime
dt = datetime(2025, 6, 24, 14, 30, 0)
Python 3.9+ 内置:
from datetime import datetime
from zoneinfo import ZoneInfo
dt = datetime.now(ZoneInfo("Asia/Shanghai"))
时区转换
utc = dt.astimezone(ZoneInfo("UTC"))
datetime -> timestamp
ts = dt.timestamp()
timestamp -> datetime
dt = datetime.fromtimestamp(ts)
❌ 不要使用 naive datetime(无时区)
Naive datetime 在多机部署、日志系统、API、数据库时会出问题。
✅ 最佳实践:
- 获取时间始终带时区
- 存数据库用 UTC
- API 输出用 ISO8601(带 Z)
安全解析(自动判断格式)
from datetime import datetime
def parse_dt(s: str) -> datetime | None:
for fmt in ("%Y-%m-%d", "%Y-%m-%d %H:%M:%S", "%Y/%m/%d"):
try:
return datetime.strptime(s, fmt)
except ValueError:
continue
return None
| 需求 | 格式 |
|---|---|
| 标准时间 | %Y-%m-%d %H:%M:%S |
| 日期 | %Y-%m-%d |
| 仅时间 | %H:%M:%S |
| 文件名安全 | %Y%m%d_%H%M%S |
| ISO8601 | dt.isoformat() |
FastAPI JSON 输出 datetimes
FastAPI 会自动依照 ISO8601 输出:
“2025-06-24T10:30:00+08:00”
SQLAlchemy(PostgreSQL)
你常使用:
- Date
- DateTime(timezone=True)
推荐:
Column(DateTime(timezone=True), server_default=func.now())
| 功能 | 写法 |
|---|---|
| 当前时间 | datetime.now() |
| 当前 UTC | datetime.now(ZoneInfo("UTC")) |
| 字符串解析 | datetime.strptime() |
| 格式化字符串 | datetime.strftime() |
| 时间差 | datetime.now() - datetime.now() |
| 加分钟 | dt + timedelta(minutes=30) |
| 转时间戳 | dt.timestamp() |
| 从时间戳恢复 | datetime.fromtimestamp(ts) |
| 取日期 | dt.date() |
| 取时间 | dt.time() |
| 时区转换 | dt.astimezone() |
| ISO8601 输出 | dt.isoformat() |