守候你守候我

我也测试了一下,随便把一些过程写在这里。首先,要支持JSON的编解码,就必须要实现两个接口,分别是json.Marshaler(组包)和json.Unmashaler(解包)。两个接口的定义如下:typeMarshalerinterface{MarshalJSON()([]byte,error)}typeUnmarshalerinterface{UnmarshalJSON([]byte)error}第一种方案,为什么必须是RFC3339格式。time.Time已经实现了这两个接口,可以进入到time/time.go找到源码实现。而之所以字段必须是RFC3999,因为time.Time实现的UnmarshalJSON方法就是按这个格式解析的。time.Time的UnmarshalJSON的源码实现如下:func(t*Time)UnmarshalJSON(data[]byte)error{//Ignorenull,likeinthemainJSONpackage.ifstring(data)=="null"{returnnil}//FractionalsecondsarehandledimplicitlybyParse.varerrerror*t,err=Parse(`"`+RFC3339+`"`,string(data))returnerr}非常简单。关于什么是RFC3999格式,题主可以参考这篇文章,互联网上的日期和时间。假设,现在需要一个支持自定义格式的时间类型,Go还是非常灵活的,基于time.Time重新定义即可,在这个基础上再实现json.Unmarshaler接口。typeCTimetime.Time//UnmarshalJSONisjoson.Unmarshalerfunc(ct*CustomTime)UnmarshalJSON(data[]byte)error{//Ignorenull,likeinthemainJSONpackage.ifstring(data)=="null"{returnnil}//FractionalsecondsarehandledimplicitlybyParse.varerrerrort,_:=time.ParseInLocation(`"2006-01-02T15:04:05"`,string(data),time.Local)*ct=CustomTime(t)returnerr}和之前的time.Time实现基本一样,只是解析的格式不一样了。这里就可以不包含时区了,因为已经固定时区为time.Local,即按当前时区解析。如果想做的更灵活点,可以用forrange把每个时间格式测试一下,通过判断Parse返回的err确定是否解析成功。当然,这种方法不推荐。这种方式的缺点是fmt.Printf打印的时候,时间不够直观,打印的底层的数据,可以自己试下就知道。当然,这应该是可以解决的。还有另外一种方式,定义一个新的时间类型结构体,里面只有一个time.Time类型成员。typeCustomTimestruct{Timetime.Time}func(ct*CustomTime)UnmarshalJSON(data[]byte)error{//Ignorenull,likeinthemainJSONpackage.ifstring(data)=="null"{returnnil}//FractionalsecondsarehandledimplicitlybyParse.varerrerrorct.Time,err=time.ParseInLocation(`"2006-01-02T15:04:05"`,string(data),time.Local)returnerr}代码都差不多。这种方式再使用fmt.Printf打印,效果就好了很多。
0 0