我正在尝试在 golang 中测试我的数据库(Postgres)模型。问题是当我从数据库检索时,具有 time.Time 类型的字段值不匹配。这是代码:
a := myStruct{aTime: time.Now().UTC(), ...}
res, err := db.Exec("INSERT INTO my_table VALUES ($1, $2, ...) RETURNING id", a.aTime, ...)
...
// some logic for setting id in struct a
...
row := db.QueryRow("SELECT * FROM my_table WHERE id = $1", a.id)
var test *myStruct
row.Scan(test)
reflect.DeepEqual(a, test) // returns False
fmt.Printf("%v\n%v", a, test)
// {2020-02-25 12:37:16.906605805 +0000 UTC ...}
// {2020-02-25 12:37:16.906606 +0000 UTC ...}
Run Code Online (Sandbox Code Playgroud)
数据库中的时间字段类型为timestamp with time zone。
我也尝试了以下方法:
a.aTime.Equal(test.aTime) // returns false
a.aTime = a.aTime.Round(time.Second)
test.aTime = test.aTime.Round(time.Second)
a.aTime.Equal(test.aTime) // returns true
Run Code Online (Sandbox Code Playgroud)
但仍然 Reflect.DeepEqual 返回 false。问题是时间字段,因为当我执行以下操作时,reflect.DeepEqual 变为 true
a.aTime = test.aTime
Run Code Online (Sandbox Code Playgroud)
有谁知道如何解决这一问题?
这些时间不相等:
// {2020-02-25 12:37:16.906605805 +0000 UTC ...}
// {2020-02-25 12:37:16.906606 +0000 UTC ...}
Run Code Online (Sandbox Code Playgroud)
DB 值具有(四舍五入的)微秒精度 - go 的时间具有纳秒精度。
我建议在将时间添加到数据库之前将其四舍五入到您的数据库和您的需求支持的精度水平,例如
a.Atime = a.aTime.Round(time.Microsecond) // round to nearest micro (per Markus comment)
res, err := db.Exec("INSERT INTO my_table VALUES ($1, $2, ...) RETURNING id", a.aTime, ...)
Run Code Online (Sandbox Code Playgroud)
另外,要比较时间相等性,请使用time.Equal():
Equal 报告 t 和 u 是否代表同一时刻。即使两个时间位于不同的位置,它们也可以相等。例如,6:00 +0200 和 4:00 UTC 相等。请参阅有关 Time 类型的文档,了解对 Time 值使用 == 的缺陷;大多数代码应该使用 Equal 来代替。
| 归档时间: |
|
| 查看次数: |
5832 次 |
| 最近记录: |