为了账号安全,请及时绑定邮箱和手机立即绑定

将时间从 DB 转换为自定义时间失败

将时间从 DB 转换为自定义时间失败

Go
扬帆大鱼 2022-06-01 16:36:46
我需要从数据库中读取日期,将其转换为某个时间戳并将其转换为 JSON。我有以下代码:package usagesimport (    "fmt"    "time")type SpecialOffer struct {    PublishedDate   jsonTime    `gorm:"column:publishing_date" json:"published_date"`    ExpirationDate  jsonTime    `gorm:"column:expiration_date" json:"expiration_date"`}type jsonTime struct {    time.Time}func (tt jsonTime) MarshalJSON() ([]byte, error) {    jsonTime := fmt.Sprintf("\"%s\"", tt.Format("20060102"))    return []byte(jsonTime), nil}当我像这样运行它时,我收到以下错误:sql: Scan error on column index 8, name "publishing_date": unsupported Scan, storing driver.Value type time.Time into type *usages.trvTime 而且数据有误:{"published_date":"00010101","expiration_date":"00010101"}如果我将SpecialOffer结构更改为 use time.Time,它返回正确,但显然格式错误:{"published_date":"2020-03-12T00:00:00Z","expiration_date":"2020-06-12T00:00:00Z"}我究竟做错了什么?
查看完整描述

1 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

您应该实现sql.Scanner和driver.Valuer接口。


像这样的东西:


func (j *jsonTime) Scan(src interface{}) error {

    if t, ok := src.(time.Time); ok {

        j.Time = t

    }

    return nil

}


func (j jsonTime) Value() (driver.Value, error) {

    return j.Time, nil

}

这是必要的,因为和其他一些 go ORMdatabase/sql使用的包gorm(如果不是全部)只为少数类型提供开箱即用的支持。


大多数支持的类型是语言的基本内置类型,如string, int,bool等。通过扩展它还支持任何自定义用户定义类型,其基础类型是上述基本类型之一,然后支持[]byte类型和相关sql.RawBytes类型,以及最后,该time.Time类型也支持 ootb。


您可能想要写入或从数据库读取的任何其他类型都需要实现上述两个接口。在将列的值解码为一种受支持的类型后sql.Scanner,会自动调用'Scan方法(这就是为什么您需要键入 assert 反对而不是反对,比如说)。's方法在驱动程序将其编码为对目标列有效的格式之前自动调用(这就是为什么您可以直接返回而不是自己进行编码)。time.Time[]bytedriver.ValuerValuetime.Time


请记住,


type jsonTime struct {

    time.Time

}

甚至


type jsonTime time.Time

声明了一个不等于的新类型,这就是为什么它没有被包拾取。time.Timedatabase/sql


查看完整回答
反对 回复 2022-06-01
  • 1 回答
  • 0 关注
  • 187 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号