如何解决Go语言中sql.NullTime结构体的JSON反序列化问题?
解决Go中sql.NullTime无法反序列化JSON字符串的问题
问题根源
标准库sql.NullTime仅实现了数据库交互相关的序列化/反序列化接口,没有实现json.Unmarshaler和json.Marshaler接口,因此json.Unmarshal无法将JSON中的字符串时间转换为sql.NullTime类型,导致报错。
解决方案
方案1:为sql.NullTime实现JSON序列化/反序列化接口
手动为sql.NullTime添加UnmarshalJSON和MarshalJSON方法,让JSON包能够正确处理字符串与sql.NullTime的转换:
import ( "strings" "time" "database/sql" ) // UnmarshalJSON 实现json.Unmarshaler接口 func (nt *sql.NullTime) UnmarshalJSON(data []byte) error { // 处理JSON中的null值 if string(data) == "null" { nt.Valid = false return nil } // 去除JSON字符串的双引号 timeStr := strings.Trim(string(data), "\"") // 解析时间(根据你的JSON时间格式调整布局,这里是YYYY-MM-DD) parsedTime, err := time.Parse("2006-01-02", timeStr) if err != nil { return err } nt.Time = parsedTime nt.Valid = true return nil } // MarshalJSON 实现json.Marshaler接口(可选,用于序列化回JSON) func (nt sql.NullTime) MarshalJSON() ([]byte, error) { if !nt.Valid { return []byte("null"), nil } // 输出与输入一致的时间格式 return []byte("\"" + nt.Time.Format("2006-01-02") + "\""), nil }
添加上述方法后,原有的反序列化代码无需修改,即可正常解析JSON中的字符串时间。
注意:如果你的JSON时间格式包含时分秒(如
"2023-10-16T14:30:00"),请将time.Parse的布局改为"2006-01-02T15:04:05"或time.RFC3339。
方案2:使用第三方库的NullTime类型
如果不想手动实现接口,可以使用已经封装好JSON序列化逻辑的第三方库,比如gopkg.in/guregu/null.v4:
- 安装库:
go get gopkg.in/guregu/null.v4
- 替换结构体中的类型:
import "gopkg.in/guregu/null.v4" type PayinCount struct { DateShiftStart null.Time `json:"dateShiftStart"` DateShiftEnd null.Time `json:"dateShiftend"` }
该库的null.Time已经实现了JSON和数据库的序列化/反序列化逻辑,直接使用即可。
内容的提问来源于stack exchange,提问作者Keith John Hutchison
相关产品推荐
相关产品推荐

