不包含時區(qū)貌似不會成功呢
大佬們遇到過這個問題嗎?golang time Unmarshal 必須包含時區(qū)嗎?
紅糖糍粑
2019-10-25 21:18:59
TA貢獻1831條經驗 獲得超9個贊
樓上的回答說的很對,不知道題主問題解決了沒有。我也測試了一下,隨便把一些過程寫在這里。首先,要支持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實現基本一樣,只是解析的格式不一樣了。這里就可以不包含時區(qū)了,因為已經固定時區(qū)為time.Local,即按當前時區(qū)解析。如果想做的更靈活點,可以用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打印,效果就好了很多。
舉報