今天偶然间发现一个问题,基于go-pg框架插入数据时,时间值自动减了1天。
目录
背景
现象与场景还原
问题解决与总结
背景
结构体中包含时间列类型,列类型是Date,对应的结构体类型是time.Time,此时对此对象做插入操作(经验证,不论批量插入还是单条均有此问题),就会出现该现象,插入的是2023-06-09,而db中插入进去的是2023-06-08。
现象与场景还原
复杂业务就不贴了,这里就以比较典型的案例说明。
由于实际场景的数据是真实的time.Time,但同样的我们直接造一个time.Time类型的数据也能说明,极简代码如下:
构造一个6月9日0时整的时间类型,然后进行插入,此时去DB查看:
、
可以看到问题复现了,9日变成了8日。
接着,将hour和min参数都改为1,也就是不设置整点了,我们直接用一个9日1点的时间插入看看,结果还是一样,插入后变为2023-06-08。
接着,将hour参数改为8,也就是用一个9日8点的时间插入,结果是2023-06-09,这次正确(有点曙光了)。
以上三次验证所用的时间点实际都是9日的并不是8日的,结果前两次插入还都变为了8日,难道是哪里时区设置的不对?
有的童鞋说了,会不会是pg的时区值设置的不对?查一下时区看看:
时区没问题,那看看现在时间是否正常,select now(); 的结果也正常,与当前时间一模一样。
那会不会是time.Date最后面的时区参数设置的不对?
问题的焦点往往就在一念之间,就是这里的问题,实际上改为time.Local也一样的现象,但改为time.UTC,再插入居然对了。
因此原因就确定了,实际来源于转换成time.Time时转换的参数不正确,时区问题导致了这样的现象,和orm框架没有关系。
问题解决与总结
待插入的Time数据检查一下看看是否有此问题,有则改之。
下面结论已经过验证:
(1)该问题在date类型的列上出现,也就是当类型为日期时可以用上述办法解决。
(2)但如果是timestamptz类型的列(时间),插入前转换时不可用UTC,可以用time.Local或fix8小时的办法,如插入的是2023-06-09 00:01:05,前者在插入后时间会变为8点05而不是1点05,后面两个是正常的。
这次没想到居然踩了这样一个坑,共勉!