gormはgo言語でSQLを扱うためのORMパッケージ。
sqliteを扱うときに時刻で想定外の挙動となったため、調査した。
※sqliteは時刻型に対応しておらず、文字列型として扱う。そこに由来する問題だと思う。
問題
localTimeやフォーマットのずれが出てくるため、単純に time.Now() を使ってinsert や select させると、想定通りに動作しなかった。
対処方針
unixtimeに揃えたり、timeのフォーマット(文字列)を意識して揃えたりすることでおそらく正常に動作する。
対策1 unixtimeに統一する
CreatedAt int64
などに揃える。
これがシンプルで確実そうではあるのだが、 time.Time
のまま使いたいときはちょっと不満が残る。
対策2 文字列フォーマットを意識して操作する
timeFormat = "2006-01-02 15:04:05.000-07:00"
を利用して、insertもselectも統一する。
gormでsqliteに書き込むと、上記のフォーマットの文字列になる。
そこで、文字列のフォーマットを全部手動で統一してやるときちんと動く模様。
// UTC miliseconds に統一する例
const timeFormat = "2006-01-02 15:04:05.000-07:00"
func formatTime(t time.Time) string {
t = t.UTC().Round(time.Millisecond)
return t.Format(timeFormat)
}
// queryも以下のようにやる
db.Where("created_at > ?",formatTime(time.Now()) .Find(&users))