154

golang gorm中格式化时间的问题

 4 years ago
source link: https://www.tuicool.com/articles/yYFf2i7
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文原文地址: golang gorm中格式化时间的问题 欢迎到访我的博客。

最近在开发项目时遇到了发现一个问题,

gorm虽然可以自动帮你维护 created_at、updated_at、deleted_at这些关键时间字段。但是其原理与弊端需要了解一下。

1.使用方法

通过自定义一个localtime的结构,来控制时间的格式

package utils
import (
	"time"
	//"strconv"
	"fmt"
	"database/sql/driver"
	"strconv"
)
type LocalTime struct {
	time.Time
}
func (t LocalTime) MarshalJSON() ([]byte, error) {
	//格式化秒
	seconds := t.Unix()
	return []byte(strconv.FormatInt(seconds, 10)), nil
}
func (t LocalTime) Value() (driver.Value, error) {
	var zeroTime time.Time
	if t.Time.UnixNano() == zeroTime.UnixNano() {
		return nil, nil
	}
	return t.Time, nil
}
func (t *LocalTime) Scan(v interface{}) error {
	value, ok := v.(time.Time)
	if ok {
		*t = LocalTime{Time: value}
		return nil
	}
	return fmt.Errorf("can not convert %v to timestamp", v)
}

此时dao的字段结构为

type TestDao struct{
         Id              uint             `gorm:"primary_key,AUTO_INCREMENT" json:"id"`
	CreatedAt       LocalTime  `json:"-"`
	UpdatedAt       LocalTime  `json:"update_at"`
	DeletedAt       *LocalTime `json:"-"`
}

2.实现原理

其实现方式其实是通过在save变更时,通过callback功能,将其定义为当前时间。文章可参考  传送门

这样你就可以通过自定义的LocalTime来控制时间格式。

3.弊端与建议

因为在程序运行时,createAt这类字段的类型还是 LocalTime,所以如果你想自己给其复制,是不太容易做到的。

例如,你想在程序运行时改一下其createAt的时间。你做不到! 因为它的类型是LocalTime,而你的时间要么是时间戳,要么是一个字符串,类型不匹配。。。是不是很尴尬???

所以建议这类保留字段还是不要在程序运行时去修改。只用它作为记录或标识即可。如果真的需要更改时间,还是自己维护字段的内容吧。例如用int存时间戳或string存字符串。然后每次变更时,去修改它的值。

当然也可以将这工作自己封装成一个callback函数,这样你就能够随意控制这个字段了。可参考上文传送门中的内容。

所以,想吐槽的是,gorm对时间格式化的这种实现方式,太不人性化了!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK