Golang gorm 时间数据类型转换

Rus*_*mov 5 postgresql time go 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"`
}
Run Code Online (Sandbox Code Playgroud)

问题:

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

解析时间 ""10:00:00"" 为 ""2006-01-02T15:04:05Z07:00"":无法将 "0:00"" 解析为 "2006""}。

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

附加信息

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

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

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)
);
Run Code Online (Sandbox Code Playgroud)

Eze*_*uns 8

虽然 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"
}
Run Code Online (Sandbox Code Playgroud)

您可以像这样使用它:

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),
}
Run Code Online (Sandbox Code Playgroud)

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


Von*_*onC 0

正如《 Go中使用GORM和Postgresql时如何节省数据库时间?》中提到的

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

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

time.Parse("2006-01-02 3:04PM", "1970-01-01 9:00PM")
Run Code Online (Sandbox Code Playgroud)