用 date 存纯日期(如生日)、datetime 存带时分秒的时间(如下单时间);数据库类型需与 python 类型对齐;优先用 dateutil.parser 解析字符串;zoneinfo 替代 pytz,注意 windows 需装 tzdata;跨时区比较须统一转 utc;相对时间用 dateutil.rrule 或 pendulum;序列化时转 utc 并用 "z" 结尾。

用 datetime 还是 date?先看字段要不要带时分秒
业务里存“生日”“合同生效日”这类纯日期,用 date 类型更安全;一旦涉及“下单时间”“支付回调时间”,就必须上 datetime。混用会埋坑:比如用 date 存时间戳,再和 datetime.now() 比大小,Python 会静默转成当天零点,结果永远偏小。
- 数据库字段类型要和 Python 类型对齐:
DATE→date,TIMESTAMP WITH TIME ZONE→datetime+tzinfo - API 接收字符串时,别用
strptime硬写格式,优先走dateutil.parser.parse(),它能自动识别"2024-03-15"和"2024-03-15T14:22:00+08:00" - ORM(如 SQLAlchemy)默认把
DateTime字段映射为datetime,但若 DB 实际存的是DATE,得显式指定type_=Date,否则取出来是带时分秒的datetime对象,容易误参与时间计算
pytz 已淘汰,zoneinfo 是标准方案但有兼容陷阱
Python 3.9+ 原生支持 zoneinfo,但很多老项目还在用 pytz。关键区别在于:pytz 的 localize() 和 astimezone() 行为不一致,zoneinfo 则统一用 datetime.replace(tzinfo=...) 和 .astimezone(),更符合直觉。
- Windows 上
zoneinfo默认没时区数据,会抛ZoneInfoNotFoundError,得手动装tzdata包:pip install tzdata - 不要用
zoneinfo.ZoneInfo("Asia/Shanghai")直接构造时区对象去替换datetime的tzinfo,而要用.replace(tzinfo=...)—— 否则夏令时切换点附近可能出错 - 跨时区比较前,必须都转成 UTC 或同一时区:
dt1.astimezone(UTC) == dt2.astimezone(UTC),直接比带不同tzinfo的datetime可能返回NotImplemented
“今天”“本周一”这种相对时间,别手算,用 dateutil.rrule 或 pendulum
业务代码里频繁出现“本月第一天”“上个月最后一天”“未来 3 个工作日”,硬写 timedelta 容易漏掉月末天数变化、节假日、时区偏移。用现成库更稳。
用 php + mysql 驱动的在线商城系统,我们的目标为中国的中小企业及个人提供最简洁,最安全,最高效的在线商城解决方案,使用了自建的会员积分折扣功能,不同的会员组有不同的折扣,让您的商店吸引更多的后续客户。 系统自动加分处理功能,自动处理会员等级,免去人工处理的工作量,让您的商店运作起来更方便省事 采用了自建的直接模板技术,免去了模板解析时间,提高了代码利用效率 独立开发的购物车系统,使用最
-
dateutil.rrule轻量且标准,适合简单周期:rrule(DAILY, count=3, dtstart=date.today())得到未来三天 -
pendulum更贴近业务语义,比如pendulum.today().start_of('month')、pendulum.now().next(pendulum.WEDNESDAY),但它不是标准库,得额外引入 - 警惕
datetime.utcnow()—— 它返回 naive datetime,没时区信息,后续转时区会出错;改用datetime.now(timezone.utc)或pendulum.utcnow()
序列化时区 datetime 到 JSON,别只调 isoformat()
datetime.isoformat() 输出像 "2024-03-15T14:22:00+08:00",看着规范,但前端 JS 的 Date 构造函数对带 +08:00 的字符串解析不稳定,尤其在 Safari 上。更稳妥的是转成 UTC 时间戳或 ISO 格式统一用 Z 结尾。
立即学习“Python免费学习笔记(深入)”;
- 推荐做法:序列化前先转 UTC,再用
.isoformat().replace("+00:00", "Z"),确保输出形如"2024-03-15T06:22:00Z" - Django 用户注意:
DateTimeField默认序列化会保留时区,但若 DB 存的是 naive datetime,DRF 会报ValueError: naive datetime while time zone support is active,得在settings.py关闭USE_TZ = False或提前补全tzinfo - FastAPI 的
pydantic模型默认把datetime序列化为 ISO 字符串,但若字段值是 naive 的,它不会报错,只是丢掉时区信息——这会导致下游误以为是本地时间









