go语言time.time默认仅支持rfc 3339格式json编解码,需自定义类型实现json.marshaler/unmarshaler接口以支持“2024-05-20”等多格式;通过封装time.time、按优先级尝试多种布局解析、统一utc时区处理及空值显式报错来确保健壮性。

Go语言默认的time.Time在JSON序列化/反序列化时只支持RFC 3339格式(如"2024-05-20T14:23:15Z"),但实际业务中常遇到自定义日期格式,比如"2024-05-20"、"20240520"或"2024-05-20 14:23:15"。要正确处理这些格式,不能依赖默认行为,需自定义类型并实现json.Marshaler和json.Unmarshaler接口。
定义支持自定义格式的日期类型
最常用做法是封装time.Time,并指定解析格式。例如处理"2006-01-02"格式的日期:
- 新建一个类型(如
CustomDate),底层用time.Time - 实现
UnmarshalJSON:接收字节切片,尝试按预设格式解析;支持多种格式时可依次尝试 - 实现
MarshalJSON:按统一格式格式化输出,避免歧义
支持多格式解析(兼容性更强)
现实数据来源多样,单格式容易失败。可在UnmarshalJSON中按优先级尝试多个布局:
- 先试
"2006-01-02"(标准年月日) - 再试
"20060102"(无分隔符) - 再试
"2006-01-02 15:04:05"(带时间) - 全部失败则返回错误,便于定位问题
注意:布局字符串必须严格匹配Go的参考时间"Mon Jan 2 15:04:05 MST 2006",不能写成"yyyy-MM-dd"等其他风格。
嵌入到结构体中使用
将自定义类型作为结构体字段,JSON解析时自动调用其方法:
- 结构体字段声明为
CreatedAt CustomDate `json:"created_at"` - 调用
json.Unmarshal(data, &obj)时,会自动进入CustomDate.UnmarshalJSON - 导出字段名保持小写+下划线风格,与API约定一致
无需额外注册或配置,零侵入集成。
注意时区与零值处理
日期字符串不含时区信息时,默认按本地时区解析,可能引发跨环境差异:
- 建议统一使用
time.UTC解析,避免夏令时或本地偏移干扰 - 空字符串、
null或非法值应明确返回错误,而不是静默转为零时间(0001-01-01) - 若业务允许空值,可改用
*CustomDate指针类型,null对应nil
不复杂但容易忽略。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











