You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决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:

  1. 安装库:
go get gopkg.in/guregu/null.v4
  1. 替换结构体中的类型:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:31:25