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

Go语言json.NewDecoder.Decode解析time.Time异常问题求助

问题原因

Go标准库encoding/json包默认解析time.Time类型时,仅支持最多三位小数的RFC3339格式时间字符串(对应time.RFC3339常量)。你的Timestamp1值"2013-06-25T18:09:22.123321Z"包含六位小数,超出默认解析精度,导致解析失败,最终得到time.Time的零值0001-01-01 00:00:00 +0000 UTC;而Timestamp2的"2014-03-26T03:59:59.999Z"是三位小数,符合默认规则,所以解析正常。

解决方案

通过自定义时间类型并实现UnmarshalJSON接口,支持任意精度的RFC3339时间字符串解析:

  1. 定义自定义时间类型
import (
    "strings"
    "time"
)

type CustomTime time.Time

// UnmarshalJSON 实现自定义JSON反序列化
func (ct *CustomTime) UnmarshalJSON(b []byte) error {
    // 去除JSON字符串首尾的引号
    timeStr := strings.Trim(string(b), "\"")
    // 使用time.RFC3339Nano解析支持最多9位小数的时间格式
    t, err := time.Parse(time.RFC3339Nano, timeStr)
    if err != nil {
        return err
    }
    *ct = CustomTime(t)
    return nil
}

// 可选:实现MarshalJSON以支持序列化(如果需要将结构体转回JSON)
func (ct CustomTime) MarshalJSON() ([]byte, error) {
    formatted := time.Time(ct).Format(time.RFC3339Nano)
    return []byte(`"` + formatted + `"`), nil
}
  1. 修改结构体字段类型
    将原结构体中的time.Time替换为自定义的CustomTime:
type httpResponse struct {
    SomeField1         string      `json:"somefield1"`
    SomeField2         string      `json:"somefield2"`
    Timestamp1         CustomTime  `json:"Timestamp1"`
    Timestamp2         CustomTime  `json:"Timestamp2"`
}
  1. 类型转换(如需使用time.Time方法)
    当需要对CustomTime调用time.Time的方法时,直接强制转换即可:
// 示例:获取Timestamp1的Unix时间戳
unixTime := time.Time(httpResponse.Timestamp1).Unix()
替代方案

如果不想自定义类型,也可以先将时间字段解析为字符串,再手动转换,不过代码冗余度较高:

type httpResponse struct {
    SomeField1         string    `json:"somefield1"`
    SomeField2         string    `json:"somefield2"`
    Timestamp1Str      string    `json:"Timestamp1"`
    Timestamp2Str      string    `json:"Timestamp2"`
    // 存储解析后的时间
    Timestamp1         time.Time
    Timestamp2         time.Time
}

// 解析后手动转换时间
err = json.NewDecoder(response.Body).Decode(&httpResponse)
if err != nil {
    logger.Info(err.Error())
    return
}
var parseErr error
httpResponse.Timestamp1, parseErr = time.Parse(time.RFC3339Nano, httpResponse.Timestamp1Str)
if parseErr != nil {
    logger.Info(parseErr.Error())
}
httpResponse.Timestamp2, parseErr = time.Parse(time.RFC3339Nano, httpResponse.Timestamp2Str)
if parseErr != nil {
    logger.Info(parseErr.Error())
}

内容的提问来源于stack exchange,提问作者wltz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 17:35:18