非 RFC 3339 时间格式的自定义 JSON 解组
Go 中的encoding/json 包严格遵守 RFC 3339 时间格式,当反序列化 JSON 数据。在处理偏离此标准的时间格式时,这可能会很不方便。
解决方案:实现自定义编组器和解组器
而不是修改现有的 JSON 数据或依赖中间转换步骤,更合适的解决方案是在自定义上实现 json.Marshaler 和 json.Unmarshaler 接口
以下示例演示如何创建处理特定非 RFC 3339 时间格式的反序列化的自定义类型 (CustomTime):
import ( "fmt" "strconv" "strings" "time" "github.com/golang/protobuf/ptypes/timestamp" ) type CustomTime struct { time.Time } const ctLayout = "2006/01/02|15:04:05" func (ct *CustomTime) UnmarshalJSON(b []byte) (err error) { s := strings.Trim(string(b), "\"") if s == "null" { ct.Time = time.Time{} return } ct.Time, err = time.Parse(ctLayout, s) return } func (ct *CustomTime) MarshalJSON() ([]byte, error) { if ct.Time.IsZero() { return []byte("null"), nil } return []byte(fmt.Sprintf("\"%s\"", ct.Time.Format(ctLayout))), nil } var nilTime = (time.Time{}).UnixNano() func (ct *CustomTime) IsSet() bool { return !ct.IsZero() } type Args struct { Time CustomTime } var data = ` {"Time": "2014/08/01|11:27:18"} ` func main() { a := Args{} if err := json.Unmarshal([]byte(data), &a); err != nil { fmt.Println("Error unmarshaling: ", err) return } if !a.Time.IsSet() { fmt.Println("Time not set") } else { fmt.Println(a.Time.String()) } }
注意: CustomTime.IsSet() 方法检查时间字段是否不为零,提供了一种方法来确定时间值是否已实际设置或不是。
通过实现自定义编组器和解组器,您可以灵活地处理可能偏离 RFC 3339 标准的时间格式,从而在 Go 中实现无缝的 JSON 数据反序列化。
以上是在 Go 中解组 JSON 时如何处理非 RFC 3339 时间格式?的详细内容。更多信息请关注PHP中文网其他相关文章!