gorm 格式化时间字段

gorm 格式化时间字段,第1张

存在问题

在使用gorm开发时,如果未对时间字段进行处理,结构体内属性类型为time.Time

type TimeTest struct {
	Id int `json:"id" gorm:"primaryKey"`
	CreateTime time.Time `json:"create_time" grom:"autoCreateTime"`
	UpdateTime time.Time `json:"update_time"`
	Value string `json:"value"`
}

问题一:读取到的时间往往这样:"2021-06-15T10:14:02.973528+08:00",带着时区和毫秒,当不需要时区和毫秒时,如何格式化时间?
问题二:insert一条数据到time_test表时,update_time字段是不赋值的,那么,插入数据库后就会这样:0001-01-01 00:00:00.000000 +00:00,系统赋了一个默认值,当不想插入默认值时如何处理?

解决办法

前提:需要了解GORM的自定义数据类型
官方地址:https://gorm.io/zh_CN/docs/data_types.html

定义一个自定义数据类型

type LocalTime time.Time

虽然该数据类型实际类型为time.Time,但是不具备time.Time的内置方法,需要重写MarshalJSON方法来实现数据解析

func (t *LocalTime) MarshalJSON() ([]byte, error) {
	tTime := time.Time(*t)
	return []byte(fmt.Sprintf("\"%v\"", tTime.Format("2006-01-02 15:04:05"))), nil
}

注意:go的格式化时间的规定时间字符串必须为2006-01-02 15:04:05 ,这是go的诞生时间,不能更改为其他时间
(这个时间字符串与java的"yyyy-MM-dd HH:mm:ss")同作用

上一步骤就解决了问题一读取数据时将将时间数据格式化,下面通过实现Scanner和Valuer接口解决问题二

    func (t LocalTime) Value() (driver.Value, error) {
   		var zeroTime time.Time
   		tlt := time.Time(t)
   		//判断给定时间是否和默认零时间的时间戳相同
   		if tlt.UnixNano() == zeroTime.UnixNano() {
   			return nil, nil
   		}
   		return tlt, nil
   }
   
   func (t *LocalTime) Scan(v interface{}) error {
   		if value, ok := v.(time.Time); ok {
   			*t = LocalTime(value)
   			return nil
   		}
   		return fmt.Errorf("can not convert %v to timestamp", v)
   }

Value方法即在存储时调用,将该方法的返回值进行存储,该方法可以实现数据存储前对数据进行相关 *** 作
Scan方法可以实现在数据查询出来之前对数据进行相关 *** 作

最后,在含有时间字段的结构体使用LocalTime替换time.Time即可完成配置
type TimeTest struct {
	Id int `json:"id" gorm:"primaryKey"`
	CreateTime *LocalTime `json:"create_time" grom:"autoCreateTime"`
	UpdateTime *LocalTime `json:"update_time"`
	Value string `json:"value"`
}

输出结果如下:
{
    "id": 80,
    "create_time": "2021-07-25 13:31:03",
    "update_time": null,
    "value": "postgres"
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/996407.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存