go 自定义UnmarshalJSON序列化时间

33 min read
package model

import (
	"database/sql/driver"
	"fmt"
	"gorm.io/gorm"
	"strings"
	"time"
)

// BaseModel 基础类型
type BaseModel struct {
	CreatedAt XTime          `json:"created_at"`
	UpdatedAt XTime          `json:"-" gorm:"embedded"`
	DeletedAt gorm.DeletedAt `json:"-"`
}

type XTime struct {
	time.Time
}

// UnmarshalJSON 2. 为 Xtime 重写 MarshaJSON 和 UnmarshalJSON 方法,在此方法中实现自定义格式的转换;
func (t *XTime) UnmarshalJSON(data []byte) error {
	if string(data) == "null" {
		return nil
	}
	var err error
	//前端接收的时间字符串
	str := string(data)
	//去除接收的str收尾多余的"
	timeStr := strings.Trim(str, "\"")
	t1, err := time.Parse("2006-01-02", timeStr)
	*t = XTime{t1}
	return err
}

func (t XTime) MarshalJSON() ([]byte, error) {
	output := fmt.Sprintf("\"%s\"", t.Format("2006-01-02"))
	return []byte(output), nil
}

// Value 3. 为 Time 实现 Value 方法,写入数据库时会调用该方法将自定义时间类型转换并写入数据库;
func (t XTime) Value() (driver.Value, error) {
	var zeroTime time.Time
	if t.Time.UnixNano() == zeroTime.UnixNano() {
		return nil, nil
	}
	return t.Time, nil
}

// Scan 4. 为 Xtime 实现 Scan 方法,读取数据库时会调用该方法将时间数据转换成自定义时间类型;
func (t *XTime) Scan(v interface{}) error {
	value, ok := v.(time.Time)
	if ok {
		*t = XTime{Time: value}
		return nil
	}
	return fmt.Errorf("can not convert %v to timestamp", v)
}