golang中json格式化自定义日期格式

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",如果是字符串,就会出现两个引号

posted @ 2021-12-13 14:09  专职  阅读(1288)  评论(0编辑  收藏  举报