問題
在使用 gorm 的過程當中, 處理時間戳字段時遇到問題。寫時間戳到數據庫時沒法寫入。mysql
經過查閱資料最終問題得以解決,特此總結sql
設置數據庫的 dsn
parseTime = "True"
loc = "Local"
數據庫
設置自定義 Time 類型
package types import ( "database/sql/driver" "fmt" "time" ) // Time is alias type for time.Time type Time time.Time const ( timeFormart = "2006-01-02 15:04:05" zone = "Asia/Shanghai" ) // UnmarshalJSON implements json unmarshal interface. func (t *Time) UnmarshalJSON(data []byte) (err error) { now, err := time.ParseInLocation(`"`+timeFormart+`"`, string(data), time.Local) *t = Time(now) return } // MarshalJSON implements json marshal interface. func (t Time) MarshalJSON() ([]byte, error) { b := make([]byte, 0, len(timeFormart)+2) b = append(b, '"') b = time.Time(t).AppendFormat(b, timeFormart) b = append(b, '"') return b, nil } func (t Time) String() string { return time.Time(t).Format(timeFormart) } func (t Time) local() time.Time { loc, _ := time.LoadLocation(zone) return time.Time(t).In(loc) } // Value ... func (t Time) Value() (driver.Value, error) { var zeroTime time.Time var ti = time.Time(t) if ti.UnixNano() == zeroTime.UnixNano() { return nil, nil } return ti, nil } // Scan valueof time.Time 注意是指針類型 method func (t *Time) Scan(v interface{}) error { value, ok := v.(time.Time) if ok { *t = Time(value) return nil } return fmt.Errorf("can not convert %v to timestamp", v) }
這樣程序中全部的時間值都使用types.Time
類型就能夠準確進行時間戳變量的讀寫操做。json
原理
其實就是自定義數據庫數據類型,在 sql driver 中實現自定義類型須要實現 Scanner
和Valuer
接口app
Scanner
type Scanner interface { Scan(src interface{}) error }
Valuer
type Valuer interface { // Value returns a driver Value. Value() (Value, error) }
unmarshal
和marshal
自定義 json 轉換格式spa
參考
https://reading.developerlearning.cn/discuss/2019-06-19-gorm-mysql-timestamp/指針