strftime 将 datetime 转字符串但默认用本地时区且不自动处理 tzinfo;strptime 对格式严苛,易因空格、年份位数、时区缩写等报错;struct_time 需用 time.strftime 而非 datetime.strftime;ISO 格式优先用 isoformat()/fromisoformat()。

strftime 把 datetime 变成字符串,但时区和本地化容易出错
用 strftime 格式化时间,本质是把 datetime 对象按模板转成字符串。最常踩的坑是:没意识到它默认用系统本地时区,且不处理 tzinfo 自动转换。
- 如果原始
datetime带时区(比如datetime.now(timezone.utc)),直接调strftime会输出 UTC 时间,但格式里看不到时区标识——除非你显式加%z或%Z -
%Y是 4 位年份,%y是 2 位,混用会导致 2024 → "24",存库或传输时可能歧义 - Windows 下
%#d(去掉日期前导零)会报错,得用%-d(Linux/macOS),跨平台建议统一用%d再手动.lstrip('0')
示例:dt.strftime('%Y-%m-%d %H:%M:%S%z') 输出类似 '2024-05-22 14:30:00+0000';缺 %z 就只输出时间,不带偏移。
strptime 把字符串变 datetime,格式必须严丝合缝
strptime 是反向操作,但比 strftime 更脆弱:字符串里多一个空格、少一位数字、时区缩写写错(比如把 CST 当作中国标准时间,其实是美国中部时间),全都会抛 ValueError: time data ... does not match format。
- 常见错误:用
%Y去解析两位年份字符串(如"24-05-22"),应改用%y - 中文环境读取 Excel 或日志里的“5月22日”,不能直接用
%B(需先设 locale,但 locale 不跨平台,更稳的方式是映射字典预处理) - 带毫秒的字符串如
"2024-05-22 14:30:00.123",必须用%f,且注意%f解析的是 6 位微秒,不足补零;"123" 实际被当作 123000 微秒
示例:datetime.strptime("2024-05-22 14:30:00", "%Y-%m-%d %H:%M:%S") 成功;但把中间空格换成 \t 或多了个逗号,就立刻失败。
立即学习“Python免费学习笔记(深入)”;
time.struct_time 不该直接拿来格式化,它是中间态
有人从 time.gmtime() 或 time.localtime() 拿到 struct_time,想直接喂给 strftime,结果报错:TypeError: descriptor 'strftime' requires a 'time.struct_time' object but received a 'tuple' —— 因为 strftime 是 datetime 的方法,不是 time 模块的函数。
- 正确路径:先用
time.mktime(t)或calendar.timegm(t)转成时间戳,再用datetime.fromtimestamp(ts)或datetime.utcfromtimestamp(ts)构造对象 - 或者干脆别绕路:需要本地时间就用
datetime.now(),需要 UTC 就用datetime.utcnow()(注意后者不带 tzinfo,推荐用datetime.now(timezone.utc)) -
struct_time真正适合的场景是搭配time.strftime(fmt, t)(注意这是time模块的函数,不是datetime的方法)
关键记清:两个 strftime,一个在 datetime 类里(实例方法),一个在 time 模块里(函数),参数类型完全不同。
ISO 格式优先用 isoformat() 和 fromisoformat(),别硬套 strftime/strptime
处理 "2024-05-22T14:30:00.123+08:00" 这类 ISO 8601 字符串,硬写 strptime 格式串既难读又易错(比如时区部分 %z 不支持冒号分隔的 +08:00)。
-
datetime.isoformat()默认输出带微秒和时区(如果对象有tzinfo),可传timespec='seconds'控制精度 -
datetime.fromisoformat(s)能原生解析带冒号时区的 ISO 字符串,Python 3.7+ 支持;但不支持省略秒的格式(如"2024-05-22T14:30"),得先补上 - 老版本 Python(fromisoformat,可用第三方
dateutil.parser.parse(),但它太“宽容”,可能把错误格式也吞掉,线上慎用
示例:dt = datetime(2024, 5, 22, 14, 30, 0, 123000, timezone(timedelta(hours=8))); dt.isoformat() → '2024-05-22T14:30:00.123000+08:00'。
时区、精度、平台差异、格式容错——这些地方一松手,时间就悄悄跑偏。尤其在日志对齐、API 时间戳校验、定时任务触发点这些场景,差一秒都可能引发连锁问题。










