Golang gorm时间数据类型转换

时间:2017-02-04 07:04:03

标签: postgresql go time go-gorm

情况:

我正在使用 postgres 数据库并具有以下结构:

type Building struct {
ID        int `json:"id,omitempty"`
Name      string `gorm:"size:255" json:"name,omitempty"`
Lon       string `gorm:"size:64" json:"lon,omitempty"`
Lat       string `gorm:"size:64" json:"lat,omitempty"`
StartTime time.Time `gorm:"type:time" json:"start_time,omitempty"`
EndTime   time.Time `gorm:"type:time" json:"end_time,omitempty"`
}

问题:

但是,当我尝试将此结构插入数据库时​​,会发生以下错误:

  

解析时间“”10:00:00“”as“”2006-01-02T15:04:05Z07:00“”:不能   解析“0:00”“as”2006“”}。

可能,它无法将StartTimeEndTime字段识别为时间类型,而是使用时间戳。如何指定这些字段的类型为时间

其他信息

以下代码段显示了我的Building创建:

if err = db.Create(&building).Error; err != nil {
    return database.InsertResult{}, err
}

Building表的SQL代码如下:

DROP TABLE IF EXISTS building CASCADE;
CREATE TABLE building(
  id SERIAL,
  name VARCHAR(255) NOT NULL ,
  lon VARCHAR(31) NOT NULL ,
  lat VARCHAR(31) NOT NULL ,
  start_time TIME NOT NULL ,
  end_time TIME NOT NULL ,
  PRIMARY KEY (id)
);

3 个答案:

答案 0 :(得分:1)

虽然 gorm 不直接支持 TIME 类型,但您始终可以创建自己的类型来实现 sql.Scannerdriver.Valuer 接口,以便能够从数据库中放入和取出时间值。

以下是重用/别名 time.Time,但不使用日、月、年数据的示例实现:

const MyTimeFormat = "15:04:05"

type MyTime time.Time

func NewMyTime(hour, min, sec int) MyTime {
    t := time.Date(0, time.January, 1, hour, min, sec, 0, time.UTC)
    return MyTime(t)
}

func (t *MyTime) Scan(value interface{}) error {
    switch v := value.(type) {
    case []byte:
        return t.UnmarshalText(string(v))
    case string:
        return t.UnmarshalText(v)
    case time.Time:
        *t = MyTime(v)
    case nil:
        *t = MyTime{}
    default:
        return fmt.Errorf("cannot sql.Scan() MyTime from: %#v", v)
    }
    return nil
}

func (t MyTime) Value() (driver.Value, error) {
    return driver.Value(time.Time(t).Format(MyTimeFormat)), nil
}

func (t *MyTime) UnmarshalText(value string) error {
    dd, err := time.Parse(MyTimeFormat, value)
    if err != nil {
        return err
    }
    *t = MyTime(dd)
    return nil
}

func (MyTime) GormDataType() string {
    return "TIME"
}

你可以像这样使用它:

type Building struct {
    ID        int    `json:"id,omitempty"`
    Name      string `gorm:"size:255" json:"name,omitempty"`
    Lon       string `gorm:"size:64" json:"lon,omitempty"`
    Lat       string `gorm:"size:64" json:"lat,omitempty"`
    StartTime MyTime `json:"start_time,omitempty"`
    EndTime   MyTime `json:"end_time,omitempty"`
}

b := Building{
    Name:      "test",
    StartTime: NewMyTime(10, 23, 59),
}

为了获得适当的 JSON 支持,您需要为 json.Marshaler/json.Unmarshaler 添加实现,这留给读者作为练习?

答案 1 :(得分:0)

如“How to save time in the database in Go when using GORM and Postgresql?

中所述
  

目前,GORM不支持timestamp with time zone以外的任何日期/时间类型。

因此您可能需要将时间解析为日期:

time.Parse("2006-01-02 3:04PM", "1970-01-01 9:00PM")

答案 2 :(得分:0)

我遇到了同样的错误。似乎数据库中的列类型与 Gorm 模型不匹配

可能数据库中列的类型是您之前可能设置的文本,然后在 gorm 模型中更改了列类型。