Go 的 time.Format 输出空字符串或 panic 是因 layout 字符串错误;必须用固定模板“2006-01-02 15:04:05”,错一位、空格、大小写或时区处理不当均导致异常。

Go 里 time.Format 为什么总输出空字符串或 panic?
因为没传对 layout 字符串——Go 的时间格式化不用 "yyyy-MM-dd HH:mm:ss" 这种常见写法,而是用一个固定的时间值 "2006-01-02 15:04:05" 作模板。错一个数字、多一个空格、大小写不对(比如 "Mon" → "mon"),Format 就会静默返回空字符串,不报错也不提示。
-
time.Now().Format("2006-01-02 15:04:05")✅ 正确 -
time.Now().Format("YYYY-MM-DD HH:mm:ss")❌ 空字符串 -
time.Now().Format("2006-01-02 3:04:05 PM")✅ 可以,但注意3不带前导零,15才带 - 中文 weekday(如“星期一”)不支持直接 layout,得用
Weekday().String()拼接
时区没处理好,Format 输出时间和你预期差 8 小时?
Go 的 time.Time 默认带时区信息,time.Now() 返回的是本地时区时间;但如果你从字符串解析(time.Parse),默认按 UTC 解析,再 Format 就容易错位。
- 确认当前时间的时区:
t.Location().String(),常见是Local或UTC - 想强制转为北京时间:
t.In(time.FixedZone("CST", 8*60*60)) - 解析字符串时指定时区更稳妥:
time.ParseInLocation(layout, s, time.Local) - Web API 常用 RFC3339(
"2006-01-02T15:04:05Z07:00"),它自带时区偏移,Format出来也带偏移,别硬套无偏移 layout
性能敏感场景下,反复调用 Format 有没有隐患?
Format 是纯内存操作,单次开销极小,但高频调用(比如每毫秒日志打点)仍可能成为微小瓶颈,尤其 layout 字符串长、含多个子模板时。
- 避免在循环里拼接 layout:
t.Format("log-" + dateLayout),字符串拼接+解析 layout 都有额外成本 - layout 字符串建议定义为 const:
const logLayout = "2006-01-02 15:04:05.000",编译期确定,运行时零解析 - 如果只取年月日,用
t.Year(), t.Month(), t.Day()字段访问比Format("2006-01-02")略快,但差异通常可忽略,优先选可读性 - 注意:
time.Time是值类型,传参或赋值不涉及堆分配,不必为“避免拷贝”做额外优化
跨平台解析时间字符串,Parse 和 Format 配合出错怎么办?
Windows 下某些 locale 设置会让 time.Parse 对英文缩写(如 "Jan")失败,而 Linux 下正常——根本原因是 Parse 依赖系统 locale,但 Format 不依赖。
立即学习“go语言免费学习笔记(深入)”;
- 统一用
ParseInLocation并显式传time.UTC或time.Local,绕过系统 locale - 输入字符串带时区信息(如
"2024-04-01T12:00:00+08:00")时,优先用time.RFC3339layout 解析,它标准、稳定、跨平台 - 自定义 layout 解析失败时,检查是否漏了末尾空格、tab 或不可见字符——打印
len(s)和fmt.Printf("%q", s)能快速定位 -
Parse错误返回time.Time{}(零值),不是 panic,务必检查 error,不能只看时间值是否“看起来合理”


















