Golang Go语言中求助广大V友,golang PostgreSQL时间字段差8个时区怎么办?

发布于 1周前 作者 sinazl 来自 Go语言

PostgreSQL 大家用的什么字段保存 时间类型

我用的是 timestamp,不带时区,go 对应的类型是 time.Time ,驱动用的是 github.com/jackc/pgx/v5, 存的时候用的是当前时区(+8 ),但是 pgx 是按照 UTC 取的,导致时间差 8 个时区,按照网上在 DSN 中添加 TimeZone 参数 貌似没啥用

我想到的两种方式:

  • 存取都采用 UTC 时间(这个应该没啥问题,就是直接查库的时候,需要大脑自动+8)
  • 取出来之后,自己修正一下(感觉有点麻烦,每次都要手动改)

求大佬给个小小建议!


Golang Go语言中求助广大V友,golang PostgreSQL时间字段差8个时区怎么办?

更多关于Golang Go语言中求助广大V友,golang PostgreSQL时间字段差8个时区怎么办?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

14 回复

存取都采用 utc 时间不是标准做法吗?难道还得考虑你自己人肉查库时方便检索吗。。。
一般都是 utc 存取,客户端去做时区匹配
因为如果你的程序是跨国使用,你服务器是没法知道用户时区的

更多关于Golang Go语言中求助广大V友,golang PostgreSQL时间字段差8个时区怎么办?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


哦,原来如此,感谢

无论如何在 pg 还是建议用 timestamptz 让数据库自己转换 UTC

pg 设置时区,没几个项目是跨国的。

来自 mysql ,我直接存 64 位 int ,出错的可能性最小

只要统一就行,所以推荐 utc

没看到实际数据,但是按照 UTC 取,差 8 个时区应该就对啊,2023-09-01T15:00:00Z 就等于 2023-09-01T23:00:00+08:00

问题就在于, 我的数据库时区是 Asia/Shanghai , 像 created_at 这种字段,使用数据库的默认值,就是当前时区的值, 然后用程序插入的字段使用的是 UTC ,就会出现 , 刚学个毛皮,不知道怎么弄合适了

上一个没截全, 正常 expire 应该和 created_at 相差 5 分钟,这一下就差了 8 小时 5 分钟了。https://imgur.com/Pc9QiQC

同意#3
1. 没有存量负担时,坚持用 timestamp with timezone 类型
2. 自己用客户端人肉查询处理问题时,可以先 set timezone 指定时区
3. 如果涉及到索引,可以针对业务上常用的时区做基于函数的索引,或者用触发器弄一个索引列

这不是项目跨不跨国的问题,而是 timestamp without timezone 的读写是直接吞掉时区的,指不定哪个环节配置不对或者哪个库处理不对就不可控了,用 with timezone ,跟外部交换时根据客户端的时区做转换,内部存储则用 UTC ,这是确定的

感谢,又学到了好多知识

摘自 python datetime 的文档 https://docs.python.org/3/library/datetime.html

Date and time objects may be categorized as “aware” or “naive” depending on whether or not they include timezone information.

With sufficient knowledge of applicable algorithmic and political time adjustments, such as time zone and daylight saving time information, an aware object can locate itself relative to other aware objects. An aware object represents a specific moment in time that is not open to interpretation.

A naive object does not contain enough information to unambiguously locate itself relative to other date/time objects. Whether a naive object represents Coordinated Universal Time (UTC), local time, or time in some other timezone is purely up to the program, just like it is up to the program whether a particular number represents metres, miles, or mass. Naive objects are easy to understand and to work with, at the cost of ignoring some aspects of reality.

使用 timestamp with timezone 保存的就是 aware object ,不需要外部依赖就能保证信息的完整性。个人建议均使用 timestamp with timezone 。

在Go语言中处理PostgreSQL时间字段时区差异的问题,通常涉及到正确设置时区以及在Go和数据库之间正确转换时间数据。以下是一些解决步骤和建议:

  1. 确认PostgreSQL时区设置: 确保PostgreSQL数据库的时区设置正确。你可以通过SQL查询SHOW TIME ZONE;来检查当前时区设置。如果需要,可以使用SET TIME ZONE 'your_timezone';来更改会话时区。

  2. Go语言时区处理: Go语言使用time.Locationtime.Time类型来处理时区。你可以通过time.LoadLocation("your_timezone")来加载特定的时区。

  3. 时间字段读取与转换: 当从PostgreSQL读取时间字段时,确保在Go中正确解析和转换时区。例如,使用pq驱动读取时间字段后,可以将其转换为指定时区的时间。

  4. 使用time.Parse和time.Format: 如果时间数据以字符串形式存在,使用time.Parse来解析时间字符串,并使用time.Format在需要时格式化时间。

  5. ORM框架时区设置: 如果你使用ORM框架(如GORM),检查框架文档以了解如何配置时区设置。

  6. 测试与验证: 在应用更改后,确保进行充分的测试以验证时区差异问题是否已解决。

通过上述步骤,你应该能够解决Go语言中与PostgreSQL时间字段时区差异相关的问题。如果问题依旧存在,建议检查具体的代码实现或寻求更详细的帮助。

回到顶部