如何将字符串格式的日期时间转换为 ISO 8601 标准格式(含时区)

本文详解如何在 python 中将数据库返回的 `yyyy-mm-dd hh:mm:ss` 字符串(如 `'2025-01-26 00:39:24'`)安全解析并转换为符合 xml sitemap `` 要求的 iso 8601 格式(如 `'2025-01-26t00:39:24+03:30'`),支持自动时区感知与毫秒截断。

在构建 Python 网站地图(sitemap)生成器时, 标签必须严格遵循 ISO 8601 标准,例如 2025-01-26T00:39:24+03:30 —— 即 YYYY-MM-DDTHH:MM:SS±HH:MM 格式,且需包含时区信息。而 MySQL 的 TIMESTAMP() 函数默认返回无时区的字符串(如 '2025-01-26 00:39:24'),直接调用 datetime.now().astimezone() 无法复用该时间值,因此关键在于:先解析原始字符串为带时区意识的 datetime 对象,再标准化输出

推荐使用 dateutil.parser.parse() 进行鲁棒性解析(可自动识别多种常见格式),再通过 .astimezone() 绑定本地系统时区(或显式指定时区),最后用 .replace(microsecond=0) 去除微秒以避免 ISO 格式中出现 .xxx,最终调用 .isoformat() 输出标准字符串:

from dateutil import parser
import datetime

# 假设这是从 MySQL 查询得到的时间字符串
db_timestamp = '2025-01-26 00:39:24'

# 步骤 1:解析为 naive datetime(无时区)
dt_naive = parser.parse(db_timestamp)

# 步骤 2:赋予本地系统时区(自动处理夏令时等)
dt_local = dt_naive.astimezone()

# 步骤 3:移除微秒(sitemap 不接受毫秒/微秒)
dt_clean = dt_local.replace(microsecond=0)

# 步骤 4:生成 ISO 8601 字符串(含时区偏移)
iso_lastmod = dt_clean.isoformat()
print(iso_lastmod)  # 示例输出:2025-01-26T00:39:24+03:30

注意事项

  • 若需统一使用 UTC(推荐用于跨时区服务),请改用 dt_naive.replace(tzinfo=datetime.timezone.utc) 或 dt_naive.astimezone(datetime.timezone.utc);
  • 避免手动拼接字符串(如 f"{d.year}-{d.month}..."),易出错且不兼容时区;
  • dateutil.parser 需单独安装:pip install python-dateutil;
  • 若数据库已返回 datetime 对象(非字符串),可跳过 parser.parse(),直接链式调用:db_dt.astimezone().replace(microsecond=0).isoformat()。

该方法简洁、健壮、符合 sitemap 协议规范,可直接集成至你的生成逻辑中,确保 值被主流搜索引擎(Google、Bing 等)正确识别。