go 的time.Time,在json序列化是默認 2006-01-02T15:04:05Z07:00 的格式,十分不便,
encoding/json包在序列化和反序列化的時候分別調用encode.go 下的Marshaler接口的MarshalJSON方法和decode.go下的Unmarshaler接口的UnmarshalJSON方法,只要類型分別實現這兩個接口即可
這里我需要序列化的時候轉為日期格式,反序列化顯示為時間戳格式
點擊查看代碼
package main
import (
"errors"
"fmt"
"time"
)
type TimeStamp int64
const CUS_TIME_FORMAT = "2006-01-02 15:04:05"
func main() {
// 時間戳轉字符串日期
ts := TimeStamp(time.Now().Unix())
b, _ := ts.MarshalJSON()
fmt.Printf("%T:%v\n", string(b), string(b)) // string:2021-12-13 14:00:43
// 字符串日期轉時間戳類型(或time.Time類型)
var t = new(TimeStamp)
err := t.UnmarshalJSON(b)
if err != nil {
fmt.Println(err)
}
fmt.Println(*t) // 1639403415
fmt.Printf("%T:%v\n", time.Unix(int64(*t), 0), time.Unix(int64(*t), 0))
// time.Time:2021-12-13 22:00:43 +0800 CST
}
// 時間戳轉換成日期字符串
func (ts TimeStamp) MarshalJSON()([]byte,error){
t := time.Unix(int64(ts),0)
if y := t.Year(); y < 0 || y >= 10000 {
return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
}
b := make([]byte, 0, len(CUS_TIME_FORMAT)+2)
//b = append(b, '"')
b = t.AppendFormat(b, CUS_TIME_FORMAT)
//b = append(b, '"')
return b, nil
}
func (ts *TimeStamp) UnmarshalJSON(data []byte) error{
if string(data) == "null" {
return nil
}
//parseTime, err := time.Parse(`"` + CUS_TIME_FORMAT + `"`, string(data))
parseTime, err := time.Parse(CUS_TIME_FORMAT, string(data))
if err!=nil{
return err
}
*ts = TimeStamp(parseTime.Unix())
return nil
}
需要注意的是在UnmarshalJSON方法中,string(data) 的字符格式為""2006-01-02 15:04:05""這樣的格式,原因是根據RFC4627 json標准,序列化后的在傳輸中都是字符串格式,在data 里面就已經包含json的字符串的 " 如果是數字1,string(data)解析的數據是"1",如果是字符串,就會出現兩個引號