time.Format专用于time.Time类型格式化,模板必须用固定时间点“Mon Jan 2 15:04:05 MST 2006”对应字段,如2006表示年、01表示带零月份;错误使用nil指针或非法layout会panic或返回空字符串;时区需显式指定IANA名称,中文星期等复杂需求需额外处理。

time.Format 不是格式化任意字符串的工具,它专用于 time.Time 类型的日期时间排版——用错地方会 panic 或返回空字符串。
Go 里 time.Format 的模板字符串怎么写
Go 不用 %Y-%m-%d 这类 C 风格占位符,而是用「一个具体时间点」作为参考模板:Mon Jan 2 15:04:05 MST 2006。每个字段对应固定值,比如 2006 表示年份,01 表示月份(带前导零),1 表示不带前导零的月份。
常见组合示例:
now := time.Now()
now.Format("2006-01-02") // 2024-05-20
now.Format("2006/01/02 15:04") // 2024/05/20 14:23
now.Format("Jan 2, 2006 at 3:04PM") // May 20, 2024 at 2:23PM
注意:01 和 1、04 和 4 效果不同;大小写敏感(PM vs pm);空格和标点需原样写出。
立即学习“go语言免费学习笔记(深入)”;
为什么 time.Format 返回空字符串或 panic
两种典型错误:
- 对 nil 的
*time.Time调用Format→ panic: "value method time.Time.Format called on nil pointer" - 传入非法 layout 字符串(如包含未定义的动词或乱序结构)→ 返回空字符串且无提示
安全做法:
- 确保变量非 nil,必要时先做
if t.IsZero()判断 - layout 字符串必须包含完整的时间组件(哪怕只显示年月,也要从标准模板中截取,不要自创)
- 调试时可先用
time.Now().Format("2006-01-02T15:04:05Z07:00")验证 layout 是否合法
本地时区 vs UTC 时间显示差异
time.Format 默认使用 t.Location(),即原始时间绑定的时区。如果时间来自 time.Now(),它带本地时区;如果来自 time.Now().UTC() 或解析时指定 time.UTC,则按 UTC 渲染。
常见误区:
- 以为
Parse("2006-01-02", "2024-05-20")返回的是 UTC 时间 → 实际返回的是本地时区时间(因为没指定 location) - 想显示东八区时间却直接用
time.Now().In(time.FixedZone("CST", 8*60*60)).Format(...)→ 更推荐用time.LoadLocation("Asia/Shanghai"),避免 FixedZone 在夏令时等场景出错
简写时区名(如 CST、PST)不可靠,Go 不内置映射,应优先用 IANA 时区名或显式偏移。
定制复杂格式时容易漏掉的边界情况
比如要输出「2024年05月20日 星期一」,不能只拼字符串:
now.Format("2006年01月02日") + " " + now.Weekday().String()
问题在于 Weekday().String() 返回英文("Monday"),不是中文。正确方式是查表或用 golang.org/x/text/language + message 包做本地化——但多数服务端场景其实只需英文 weekday,强行中文反而增加依赖和维护成本。
另一个坑:微秒精度。若需毫秒级时间戳,别用 Format("2006-01-02 15:04:05.000"),因为 .000 不是标准 verb;应改用 now.Format("2006-01-02 15:04:05") + fmt.Sprintf(".%03d", now.Nanosecond()/1e6)。
真正需要高度定制(如农历、ISO 周编号、季度)时,time.Format 就不够用了——得自己算,或者引入第三方库如 github.com/leekchan/timeutil。


















