V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
lilei2023
V2EX  ›  Go 编程语言

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

  •  
  •   lilei2023 · 2023-09-01 14:12:22 +08:00 · 1475 次点击
    这是一个创建于 449 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    我想到的两种方式:

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

    求大佬给个小小建议!

    13 条回复    2023-09-01 17:07:33 +08:00
    StoneHuLu
        1
    StoneHuLu  
       2023-09-01 14:22:30 +08:00
    存取都采用 utc 时间不是标准做法吗?难道还得考虑你自己人肉查库时方便检索吗。。。
    一般都是 utc 存取,客户端去做时区匹配
    因为如果你的程序是跨国使用,你服务器是没法知道用户时区的
    lilei2023
        2
    lilei2023  
    OP
       2023-09-01 14:26:36 +08:00
    @StoneHuLu 哦,原来如此,感谢
    moen
        3
    moen  
       2023-09-01 14:58:57 +08:00
    无论如何在 pg 还是建议用 timestamptz 让数据库自己转换 UTC
    lasuar
        4
    lasuar  
       2023-09-01 15:05:31 +08:00
    pg 设置时区,没几个项目是跨国的。
    dcsuibian
        5
    dcsuibian  
       2023-09-01 15:08:23 +08:00 via Android
    来自 mysql ,我直接存 64 位 int ,出错的可能性最小
    opengps
        6
    opengps  
       2023-09-01 15:25:23 +08:00
    只要统一就行,所以推荐 utc
    bv
        7
    bv  
       2023-09-01 15:26:52 +08:00
    没看到实际数据,但是按照 UTC 取,差 8 个时区应该就对啊,2023-09-01T15:00:00Z 就等于 2023-09-01T23:00:00+08:00
    lilei2023
        8
    lilei2023  
    OP
       2023-09-01 16:20:01 +08:00
    @bv 问题就在于, 我的数据库时区是 Asia/Shanghai , 像 created_at 这种字段,使用数据库的默认值,就是当前时区的值, 然后用程序插入的字段使用的是 UTC ,就会出现 , 刚学个毛皮,不知道怎么弄合适了
    lilei2023
        9
    lilei2023  
    OP
       2023-09-01 16:23:25 +08:00
    @lilei2023 上一个没截全, 正常 expire 应该和 created_at 相差 5 分钟,这一下就差了 8 小时 5 分钟了。https://imgur.com/Pc9QiQC
    lilei2023
        10
    lilei2023  
    OP
       2023-09-01 16:25:46 +08:00
    @lilei2023 [img][/img]
    adoal
        11
    adoal  
       2023-09-01 16:39:49 +08:00
    同意#3
    1. 没有存量负担时,坚持用 timestamp with timezone 类型
    2. 自己用客户端人肉查询处理问题时,可以先 set timezone 指定时区
    3. 如果涉及到索引,可以针对业务上常用的时区做基于函数的索引,或者用触发器弄一个索引列

    这不是项目跨不跨国的问题,而是 timestamp without timezone 的读写是直接吞掉时区的,指不定哪个环节配置不对或者哪个库处理不对就不可控了,用 with timezone ,跟外部交换时根据客户端的时区做转换,内部存储则用 UTC ,这是确定的
    lilei2023
        12
    lilei2023  
    OP
       2023-09-01 16:44:18 +08:00
    @adoal 感谢,又学到了好多知识
    DivineRapierH
        13
    DivineRapierH  
       2023-09-01 17:07:33 +08:00
    摘自 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 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1601 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 16:59 · PVG 00:59 · LAX 08:59 · JFK 11:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.