Go语言解析日期字符串必须用time.Parse,其第一个参数是按参考时间“Mon Jan 2 15:04:05 MST 2006”编写的布局模板,如"20060102";输入无时区需用ParseInLocation指定location,中文或不规则格式须先正则提取再转换。

Go 语言解析日期字符串,核心就一条:time.Parse 的第一个参数不是“你想要的格式”,而是“输入字符串实际长什么样”的布局模板,且必须严格按 Go 的参考时间 Mon Jan 2 15:04:05 MST 2006 来写。用错布局,必报 parsing time "..." as "...": cannot parse ...。
为什么 time.Parse("20101011", "20101011") 会 panic
因为 time.Parse 把第一个参数当作“布局定义”,而不是“目标值”。"20101011" 不含任何可映射的参考时间字段(比如 2006、01、02),Go 无法识别哪段是年、哪段是月、哪段是日。
- ✅ 正确布局是
"20060102":它明确告诉 Go,“前4位是年(对应参考时间的 2006),中间2位是月(对应 01),后2位是日(对应 02)” - ❌
"20101011"是无效布局——它没有结构语义,只是个普通字符串 - ❌
"YYYYMMDD"或"%Y%m%d"同样无效——Go 不支持占位符语法
time.Parse 和 time.ParseInLocation 怎么选
关键看输入字符串是否带时区信息:
- 输入如
"2026-05-22T10:30:00Z"或"2026-05-22 10:30:00 +0800":用time.Parse,布局中需包含时区部分(如"2006-01-02T15:04:05Z"或"2006-01-02 15:04:05 -0700") - 输入如
"2026-05-22"或"2026/05/22 10:30"(无显式时区):必须用time.ParseInLocation显式指定上下文,例如time.ParseInLocation("2006-01-02", s, time.Local) - 忽略时区会导致解析出的时间对象默认为 UTC,但本地显示可能偏差 8 小时(中国用户最常踩的坑)
解析中文日期或不规则格式,别硬刚 time.Parse
像 "2026年05月22日"、"五月二十二日 2026" 这类非标准格式,time.Parse 无法直接处理——它只认数字和固定缩写(Jan、MST 等),不识别中文字符或模糊表达。
立即学习“go语言免费学习笔记(深入)”;
- 先用正则提取年、月、日数字(例如
regexp.MustCompile(`(\d{4})年(\d{1,2})月(\d{1,2})日`)) - 再拼成标准格式字符串,如
"2026-05-22",最后用time.ParseInLocation("2006-01-02", cleanStr, time.Local) - 不要在一个正则里塞所有日期变体(如
MM/DD/YYYY|DD/MM/YYYY|YYYY-MM-DD),命名捕获组索引会错乱;应为每种格式单独编译、依次匹配
Go 1.20+ 的 time.DateOnly 要怎么用
time.DateOnly 是预定义常量,值为 "2006-01-02",仅用于「输入已是 YYYY-MM-DD 格式」的场景:
- ✅
time.Parse(time.DateOnly, "2026-05-22")—— 安全、语义清晰 - ❌
time.Parse(time.DateOnly, "20260522")—— 失败,布局与输入不匹配 - ❌
time.Parse(time.DateOnly, "2026/05/22")—— 同样失败,斜杠不匹配短横线 - 若原始数据是
YYYYMMDD,仍得用"20060102"解析,之后再t.Format(time.DateOnly)输出
真正容易被忽略的是:哪怕你只关心“日期”,只要输入字符串里没带时区,又没显式指定 time.Local 或其他 location,解析出的 time.Time 对象内部时区就是 UTC,后续调用 t.Hour() 或 t.In(time.Local).Hour() 会得到完全不同结果。


















