1. 什么是 tzdata? #

2. 前置知识 #

2.1 UTC、naive 与 aware #

2.2 IANA 时区名称 #

3. 环境准备 #

3.1 安装与验证 #

# 说明:安装 tzdata 时区数据包
py -m pip install tzdata
# -*- coding: utf-8 -*-
# 说明:从 datetime 导入 datetime 类
from datetime import datetime

# 说明:从 zoneinfo 导入 ZoneInfo,指定 IANA 时区
from zoneinfo import ZoneInfo

# 说明:获取上海时区的当前时间
now = datetime.now(ZoneInfo("Asia/Shanghai"))

# 说明:打印当前时间
print("上海当前时间:", now)

# 说明:打印验证通过提示
print("验证通过")

4. 常用操作 #

4.1 获取当前时间与 UTC 转本地 #

# -*- coding: utf-8 -*-
# 说明:导入 datetime 和 timezone
from datetime import datetime, timezone

# 说明:导入 ZoneInfo
from zoneinfo import ZoneInfo

# 说明:定义项目本地时区为上海
LOCAL_TZ = ZoneInfo("Asia/Shanghai")

# 说明:获取 UTC 当前时间(aware)
utc_now = datetime.now(timezone.utc)
print("UTC:", utc_now)

# 说明:获取上海当前时间
print("上海:", datetime.now(LOCAL_TZ))

# 说明:将 UTC 时间转换为上海时间并格式化
local = utc_now.astimezone(LOCAL_TZ)
print("转换:", local.strftime("%Y-%m-%d %H:%M:%S"))

4.2 数据库 naive 时间转本地 #

# -*- coding: utf-8 -*-
# 说明:导入 datetime 和 timezone
from datetime import datetime, timezone

# 说明:导入 ZoneInfo
from zoneinfo import ZoneInfo

# 说明:本地时区
LOCAL_TZ = ZoneInfo("Asia/Shanghai")

# 说明:模拟从数据库读出的 UTC naive 时间
db_time = datetime(2026, 5, 30, 4, 30, 0)

# 说明:标记为 UTC aware 时间
utc_aware = db_time.replace(tzinfo=timezone.utc)

# 说明:转为上海时间并格式化为字符串
local_str = utc_aware.astimezone(LOCAL_TZ).strftime("%Y-%m-%d %H:%M")
print("页面显示:", local_str)

5. 项目实战:Flask 本地时间 #

# -*- coding: utf-8 -*-
# 说明:导入 datetime 和 timezone
from datetime import datetime, timezone

# 说明:导入 ZoneInfo
from zoneinfo import ZoneInfo

# 说明:项目统一本地时区
LOCAL_TZ = ZoneInfo("Asia/Shanghai")


def format_localtime(dt, fmt="%Y-%m-%d %H:%M"):
    """将 UTC naive 时间格式化为上海本地时间字符串。"""
    # 说明:空值返回空字符串
    if not dt:
        return ""
    # 说明:标记为 UTC
    utc_dt = dt.replace(tzinfo=timezone.utc)
    # 说明:转本地并格式化
    return utc_dt.astimezone(LOCAL_TZ).strftime(fmt)


# 说明:Flask 中可注册为 @app.template_filter("localtime")

# 说明:测试:UTC 04:30 应显示为上海 12:30
print(format_localtime(datetime(2026, 5, 30, 4, 30, 0)))

6. 常见问题 #

6.1 ZoneInfoNotFoundError #

6.2 naive 与 aware 混用 #

6.3 其他注意点 #

7. API 速查 #

操作 写法
安装 py -m pip install tzdata
创建时区 ZoneInfo("Asia/Shanghai")
UTC 现在 datetime.now(timezone.utc)
本地现在 datetime.now(ZoneInfo("Asia/Shanghai"))
naive → UTC aware dt.replace(tzinfo=timezone.utc)
转本地 dt.astimezone(ZoneInfo("Asia/Shanghai"))
格式化 dt.strftime("%Y-%m-%d %H:%M:%S")
时间加减 dt + timedelta(hours=1)