不包含时区貌似不会成功呢
楼上的回答说的很对,不知道题主问题解决了没有。我也测试了一下,随便把一些过程写在这里。
首先,要支持 JSON 的编解码,就必须要实现两个接口,分别是 json.Marshaler(组包) 和 json.Unmashaler(解包)。
两个接口的定义如下:
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
type Unmarshaler interface {
UnmarshalJSON([]byte) error
}
第一种方案,为什么必须是 RFC 3339 格式。
time.Time 已经实现了这两个接口,可以进入到 time/time.go 找到源码实现。而之所以字段必须是 RFC 3999,因为 time.Time 实现的 UnmarshalJSON 方法就是按这个格式解析的。
time.Time 的 UnmarshalJSON 的源码实现如下:
func (t *Time) UnmarshalJSON(data []byte) error {
// Ignore null, like in the main JSON package.
if string(data) == "null" {
return nil
}
// Fractional seconds are handled implicitly by Parse.
var err error
*t, err = Parse(`"`+RFC3339+`"`, string(data))
return err
}
非常简单。
关于什么是 RFC 3999 格式,题主可以参考这篇文章,互联网上的日期和时间。
假设,现在需要一个支持自定义格式的时间类型,Go 还是非常灵活的,基于 time.Time 重新定义即可,在这个基础上再实现 json.Unmarshaler 接口。
type CTime time.Time
// UnmarshalJSON is joson.Unmarshaler
func (ct *CustomTime) UnmarshalJSON(data []byte) error {
// Ignore null, like in the main JSON package.
if string(data) == "null" {
return nil
}
// Fractional seconds are handled implicitly by Parse.
var err error
t, _ := time.ParseInLocation(`"2006-01-02T15:04:05"`, string(data), time.Local)
*ct = CustomTime(t)
return err
}
和之前的 time.Time 实现基本一样,只是解析的格式不一样了。这里就可以不包含时区了,因为已经固定时区为 time.Local,即按当前时区解析。
如果想做的更灵活点,可以用 for range 把每个时间格式测试一下,通过判断 Parse 返回的 err 确定是否解析成功。当然,这种方法不推荐。
这种方式的缺点是 fmt.Printf 打印的时候,时间不够直观,打印的底层的数据,可以自己试下就知道。当然,这应该是可以解决的。
还有另外一种方式,定义一个新的时间类型结构体,里面只有一个 time.Time 类型成员。
type CustomTime struct {
Time time.Time
}
func (ct *CustomTime) UnmarshalJSON(data []byte) error {
// Ignore null, like in the main JSON package.
if string(data) == "null" {
return nil
}
// Fractional seconds are handled implicitly by Parse.
var err error
ct.Time, err = time.ParseInLocation(`"2006-01-02T15:04:05"`, string(data), time.Local)
return err
}
代码都差不多。这种方式再使用 fmt.Printf 打印,效果就好了很多。
2 回答2.4k 阅读✓ 已解决
1 回答2.4k 阅读✓ 已解决
2 回答1.7k 阅读✓ 已解决
1 回答1.2k 阅读✓ 已解决
1 回答1.4k 阅读✓ 已解决
2 回答1.2k 阅读
1 回答1.8k 阅读
必须包含,文档里面有https://golang.org/pkg/time/#Time.UnmarshalJSON,时间必须符合RFC 3339格式。
要自定义Unmarshal,需要实现
json.Unmarshaler
接口。看这里https://stackoverflow.com/questions/25087960/json-unmarshal-time-that-isnt-in-rfc-3339-format