
Go 的 time.Parse 要求布局字符串必须使用固定参考时间 Mon Jan 2 15:04:05 MST 2006 中的特定值(如 01/02/2006 03:04 AM),而非任意示例时间;直接复用输入样例 "01/31/2000 12:59 AM" 作为 layout 会导致 hour out of range 错误。
go 的 time.parse 要求布局字符串必须使用固定参考时间 `mon jan 2 15:04:05 mst 2006` 中的特定值(如 `01/02/2006 03:04 am`),而非任意示例时间;直接复用输入样例 `"01/31/2000 12:59 am"` 作为 layout 会导致 `hour out of range` 错误。
在 Go 中,time.Parse(layout, value) 的 layout 参数不是占位符模板,而是一个具有严格语义的“参考时间格式”——它必须精确匹配 Go 内置的基准时间 Mon Jan 2 15:04:05 MST 2006(即 Unix 时间戳 1136239445)中各字段的字面值。例如:
- 月份固定用
01(一月), - 日固定用
02(每月第二日), - 年固定用
2006, -
12 小时制小时固定用
03(而非12或01), - 分钟固定用
04, - 上下午标识用
PM或AM(大小写敏感,且必须存在空格)。
因此,你原代码中 layout := "01/31/2000 12:59 AM" 是错误的:31 不是合法的“日”参考值(应为 02),2000 不是合法年份参考(应为 2006),最关键的是 12 作为小时 —— 在 12 小时制布局中,Go 要求使用 03 表示小时位置(对应参考时间中的 3 AM/PM),而非实际数值 12。否则解析器会尝试将输入中的 12 映射到 12 小时制的第 12 小时,但在内部校验时因布局未声明“允许 12 小时制上下文”而触发范围错误。
✅ 正确的布局应为:
layout := "01/02/2006 03:04 AM"
完整可运行示例:
package main
import (
"fmt"
"time"
)
func main() {
layout := "01/02/2006 03:04 AM"
input := "01/31/2000 12:59 AM"
t, err := time.Parse(layout, input)
if err != nil {
fmt.Println("Failed to decode time:", err) // 不再触发 "hour out of range"
return
}
fmt.Println("Time decoded:", t) // 输出:2000-01-31 00:59:00 +0000 UTC
}⚠️ 注意事项:
-
03表示 12 小时制小时位(支持1–12),15表示 24 小时制小时位(支持0–23); -
AM/PM必须与03配合使用;若输入为13:30等 24 小时格式,应改用"01/02/2006 15:04"并移除AM; - 空格、斜杠、冒号、大小写均需完全一致 —— 例如
"01/02/2006 03:04:05 PM"中的:和PM前空格不可省略; - 推荐使用
time.ParseInLocation指定时区,避免默认解析为 UTC 导致业务偏差。
掌握这一“参考时间即布局”的设计哲学,是正确使用 Go 时间解析的关键前提。

















