go - 将时间从 DB 转换为自定义时间失败
问题描述
我需要从数据库中读取日期,将其转换为某个时间戳并将其转换为 JSON。
我有以下代码:
package usages
import (
"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"}
我究竟做错了什么?
解决方案
您应该实现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
[]byte
driver.Valuer
Value
time.Time
请记住,
type jsonTime struct {
time.Time
}
甚至
type jsonTime time.Time
声明了一个不等于的新类型,这就是为什么它没有被包拾取。time.Time
database/sql
推荐阅读
- bash - 当我通过将脚本放在 /usr/local/bin 中全局使用脚本时,Bash 脚本标志参数不起作用
- jenkins - Azure Devops 存储库上的多分支管道选项?
- python-3.x - 我需要锁定我的标题,以便没有人可以编辑这些列,但我想使用 xlsxwriter 启用自动过滤器
- javascript - 有没有办法将 SVG 元素放在具有绝对位置的 HTML div 上方?
- python - 如何从python中的for循环逐列将数据写入csv?
- ios - 如何在 Swift 中使用 Firebase 处理离线注销?
- android - 如何在我的颤振应用程序中将圆形指示器小部件作为小部件制作为点?
- angular - 我们如何创建一个可以在多个 angular7 应用程序之间共享的公共节点模块文件夹
- c++ - 错误:缩小“18446744069414584320ull”从“long long unsigned int”到“int”的转换{} [-Wnarrowing]
- c++ - 如何启用递归函数以避免堆栈溢出?