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时间字符串解析:
- 定义自定义时间类型
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 }
- 修改结构体字段类型
将原结构体中的time.Time替换为自定义的CustomTime:
type httpResponse struct { SomeField1 string `json:"somefield1"` SomeField2 string `json:"somefield2"` Timestamp1 CustomTime `json:"Timestamp1"` Timestamp2 CustomTime `json:"Timestamp2"` }
- 类型转换(如需使用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
相关产品推荐
相关产品推荐

