问题:
币商需求中,qa发现在页面中的时间,都比实际的时间延后了8小时:
解决方式:
修改数据库时间字段的默认值,由now() 改为 timezone('UTC'::text, now())

问题得到解决:

原理探究:
参照资料:http://www.postgres.cn/docs/9.4/datatype-datetime.html

资料中的两句话,可以解释最初的问题:
“timestamp类型等于timestamp without time zone 类型”
“如果一个文本已被确定是timestamp without time zone,PostgreSQL 将悄悄忽略任何文本中指出的时区。”
分析:
now()会根据当前会话中使用的时区,返回为带有时区的时间字符串:


应用服务与数据库的会话,应该是使用了北京时区,而"悄悄忽略任何文本中指出的时区"后,将北京时间作为无时区时间,存入了时间字段。
结合目前在用的orm框架gitlab.p1staff.com/common/postgres/pgv6试验:
查询时:timestamp字段,返回的内容为不带时区时间字符串,orm会作为UTC时间来转换为time.Time类型
gitlab.p1staff.com/common/pg@v6.15.4+incompatible/types/time.go:23

到此,时间字段已经达成了 在应用中,将北京时间作为UTC时间了。
改为 timezone('UTC'::text, now())后,默认时间不受会话中使用时区影响,返回不带时区的UTC时间字符串。让时间字段正确存储UTC时间。

扩展探究:
对timestamp字段进行范围查询时,会不会有时区问题?确保字段存的是UTC时间,就不会。orm拼接time.Time类型数据时,会处理成UTC时间字符串。
gitlab.p1staff.com/common/pg@v6.15.4+incompatible/types/time.go:47


虽然拼的字符串有时区,但timestamp字段会"悄悄忽略任何文本中指出的时区"
网友评论