gorm 格式化时间字段

存在问题

在使用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"
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值