pytz 是什么?
pytz 就是把 IANA(以前叫 Olson)时区数据库搬进 Python 里的一个库。它把全世界几百个时区的历史规则、夏令时切换、甚至一次性改时的怪异情况,都封装成可以直接调用的 tzinfo 对象。
一句话概括:想在 Python 里靠谱地处理本地时间、夏令时、跨时区转换?pytz 拿下!
它解决了哪些痛点?
| | |
| 夏令时切换产生的歧义 | 直接给 datetime(..., tzinfo=tz),结果会得到奇怪的 LMT+0018,根本不靠谱 | 用 timezone.localize() 明确指定是 DST 还是标准时间 |
| 跨时区算时间差 | | astimezone() |
| 历史时区变更 | 只能靠硬编码,遇到 1915 年 Warsaw 那种一次性调 24 分钟的情况,根本不可能 | pytz 完整保留了历史记录,直接用对应 tz 名称即可 |
| 跨平台不一致 | Windows、Linux、macOS 各自的时区实现不统一,导致同一段代码在不同机器上跑出不同结果 | |
安装 & 上手
pip install pytz
如果你在离线环境,直接下载源码,用 python setup.py install 也行。
最常见的几行代码
from datetime import datetime, timedeltaimport pytz# 1️⃣ 拿到时区对象eastern = pytz.timezone('US/Eastern')amsterdam = pytz.timezone('Europe/Amsterdam')# 2️⃣ 本地化(把“裸”datetime 变成带时区的)naive = datetime(2023, 10, 29, 9, 0, 0) # 没有 tzinfolocal_dt = eastern.localize(naive) # 指定是 EST/EDT# 3️⃣ 跨时区转换ams_dt = local_dt.astimezone(amsterdam)print(local_dt) # 2023-10-29 09:00:00-04:00print(ams_dt) # 2023-10-29 15:00:00+01:00
几个小技巧
- • 统一使用 UTC:内部所有时间都用
pytz.UTC,只有对外展示时才 astimezone() 成目标时区。 - • 处理夏令时歧义:
localize(dt, is_dst=True/False),或直接把时间从 UTC 转来,省掉猜。 - • 算时间差:跨 DST 区间做加减要记得
normalize(),否则可能得到错误的时区标记。
优缺点一览
| |
| ✅ 完整覆盖 IANA 数据库,几乎所有历史时区都有 | ⚠️ 对 Python 3.9+ 已有原生 zoneinfo,pytz 只保留兼容老代码的价值 |
| ✅ 跨平台一致,Windows/Linux/Mac 都表现相同 | 🛠️ API 与标准 datetime.tzinfo 不完全吻合,需要 localize、normalize 两个额外步骤 |
| 📚 文档相对零散,初学者要花点时间理清 “naive vs aware” 的概念 |
| 🚫 已进入维护模式,不再新增特性,只跟随 IANA 更新 |
实战案例:日志分析
假设我们有一批服务器日志,记录的时间都是 UTC,想把它们转成北京时区(Asia/Shanghai)再做统计:
import pytz, csvfrom datetime import datetimeutc = pytz.UTCshanghai = pytz.timezone('Asia/Shanghai')hour_counter = [0]*24withopen('logs.csv') as f:for line in csv.reader(f):# 假设第一列是 ISO8601 UTC 时间字符串 utc_dt = datetime.fromisoformat(line[0]).replace(tzinfo=utc) local_dt = utc_dt.astimezone(shanghai) # 转北京时区 hour_counter[local_dt.hour] += 1# 按小时计数print('北京时区每小时日志数:')for h, cnt inenumerate(hour_counter):print(f'{h:02d}:00 - {cnt} 条')
几行代码就搞定了跨时区统计,省掉了手动算时差、夏令时导致的坑。
小结
- • pytz 把全球时区规则搬进了 Python,解决了夏令时、历史时区变更等一大堆麻烦。
- • 对于 Python 3.9+,推荐直接使用标准库的
zoneinfo(配合 tzdata 包),但 老项目、兼容性需求 仍然离不开 pytz。 - • 学会
localize、astimezone、normalize 三招,你就可以在任何时区间自由穿梭,时间算得稳、代码写得简。
记住:内部统一用 UTC,输出前再转本地时区;遇到 DST 歧义,用 is_dst 明确指明,否则让库抛异常,别让它偷偷猜。
项目地址: https://github.com/stub42/pytz