go的time.format不识别yyyy-mm-dd等通用占位符,只认参考时间“mon jan 2 15:04:05 mst 2006”对应数字位置,故"2006-01-02"才正确输出日期,错用则原样返回。

time.Format 的格式字符串不是占位符,而是“参考时间”的字面复刻 —— 用错就原样输出,不报错也不警告。
为什么 t.Format("yyyy-MM-dd") 返回的是字面字符串?
Go 不识别 yyyy、MM 这类通用占位符。它只认那个固定参考时间:Mon Jan 2 15:04:05 MST 2006 对应的数字位置:
-
2006→ 年份(四位) -
01→ 月份(两位) -
02→ 日期(两位) -
15→ 小时(24小时制) -
04→ 分钟 -
05→ 秒 -
MST→ 时区缩写(如CST、UTC)
所以 "yyyy-MM-dd" 会被当作纯文本返回,而 "2006-01-02" 才能正确输出日期。
常用格式字符串怎么写?
别靠记忆拼,直接按参考时间“抄数字”:
- 标准 ISO 格式:
"2006-01-02 15:04:05" - 紧凑无分隔符:
"20060102150405"(注意不是yyyyMMddHHmmss) - RFC3339 标准:
time.RFC3339(等价于"2006-01-02T15:04:05Z07:00") - 中文习惯:
"2006年01月02日 15时04分05秒" - 仅时间(12小时制):
"2006-01-02 03:04:05 PM"
连字符、空格、中英文标点可任意替换,但数字部分必须是 2006/01/02/15/04/05,顺序不能乱。
time.Parse 解析失败的常见原因
解析字符串和格式字符串不匹配时,time.Parse 返回 error,但错误信息很模糊(比如 parsing time "2026-05-24" as "2006-01-02 15:04:05": cannot parse "" as "15:04:05"),容易误判。
- 格式字符串多了时间部分,但输入只有日期 → 改用
"2006-01-02" - 输入含中文或全角符号(如“:”“年”“月”)→ 格式字符串也得用对应中文,且严格对齐
- 默认解析为 UTC 时区 → 若需本地时区,改用
time.ParseInLocation(layout, value, time.Local) - 月份/星期名大小写不一致(
Janvsjan)→ 必须完全匹配参考时间的大小写
时区和性能要注意什么?
Format 本身很快,但若频繁调用 time.Now().In(loc).Format(...),每次 In 都会做时区转换计算。
- 线上服务建议统一用 UTC 存储和传输,展示时再转本地时区
- 预加载时区:
loc, _ := time.LoadLocation("Asia/Shanghai"),避免在循环里重复调用 -
time.RFC3339和time.Stamp等内置常量已优化,比手写字符串略快 - 如果只是打日志,用
time.Now().Format(time.Stamp)(输出类似May 24 06:34:12)更轻量
最易忽略的一点:格式字符串里的空格、冒号、中英文标点必须和输入/输出预期完全一致 —— 差一个全角字符,Parse 就静默失败,Format 就原样吐出。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











