V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
layxy
V2EX  ›  程序员

web 服务时区问题

  •  
  •   layxy · 186 天前 · 1122 次点击
    这是一个创建于 186 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有个 web 服务时区问题,后端服务和数据库都统一使用 utc+0 时区,由前端根据访问者所在时区进行格式化,现在问题是用户新增数据时,应该让前端传创建时间还是使用服务器时间,如果使用服务器时间,则创建的数据时间和展示给用户的时间可能不一致(比如用户是东八区,服务器按 0 时区存,展示时就差了 8 小时),如果让前端传创建时间,这个创建时间不可靠,用户可能通过非法手段修改,想咨询大佬有没有很好的解决时区的办法

    第 1 条附言  ·  184 天前
    至于服务器时间和客户端时间这个我之前理解有问题,以服务器 utc 时区为准就可以,前端会自动根据用户所在时区转换就可以,现在有个其他问题就是服务器使用 utc 时区后,日志里打印的时间应该怎么处理,比如用户在西八区,客诉给了一个西八区的时间,而运营人员在东八区,他在浏览器查询的时候使用西八区客诉的时间应该是有问题的,开发去排查也很不方便
    15 条回复    2023-10-26 11:07:07 +08:00
    XiLingHost
        1
    XiLingHost  
       186 天前
    统一传时间戳啊,然后展示让前端做
    ysc3839
        2
    ysc3839  
       186 天前 via Android   ❤️ 2
    “比如用户是东八区,服务器按 0 时区存,展示时就差了 8 小时”
    为什么会呢?你前面不是说“由前端根据访问者所在时区进行格式化”吗?
    ho121
        3
    ho121  
       186 天前 via Android
    一般是按照服务器时间。
    展示也要转换时区再展示的啊。
    WhateverYouLike
        4
    WhateverYouLike  
       186 天前 via Android
    2 楼加一
    ratazzi
        5
    ratazzi  
       186 天前
    创建、更新等时间都是以服务器为准,必须要客户传的比如预约、达到时间等之类的才会用客户的
    ETiV
        6
    ETiV  
       186 天前 via iPhone   ❤️ 1
    奇异博士告诉我们:不要玩弄时间

    1. 确定服务器开了 ntp 同步服务。明令禁止人肉修改时间
    2. 数据库里存 int64 数值形式的时间戳(你自己考虑秒、毫秒、微秒这类精度需求)
    3. 应用业务根据时间戳自行转换成 human-readable 的时间字面量(带时区),浏览器 JS 有个 toLocaleString 很好用
    4. 永远不要使用客户端提交的时间,极有可能存在客户端时间不准确、甚至故意改时间来达成一些目的的情况
    Mithril
        7
    Mithril  
       186 天前
    你存 UTC ,从数据库里读出 UTC 你也要按客户时区转换一下啊,怎么可能差 8 小时。

    本质上你数据库应该保存的是 instantaneous time ,而你展示给客户的应该是 calendar time ,这个转换应该在前端完成。

    比如说你客户 A 从-8 生成了一个数据,存在数据库里的应该是+0 ,而展示给+8 的客户 B 应该就是+8 。如果你关心数据生成的时区,那应该用另一个 field 去保存,或者你存成 datetimeoffset 。

    至于 instantaneous time 和 calendar time 的区别,这里有个很好的解释你可以参考一下:
    https://stackoverflow.com/questions/4331189/datetime-vs-datetimeoffset
    baobao1270
        8
    baobao1270  
       186 天前
    @ETiV 4 不太同意

    对于非标准的 locale (比如我这种用 zh-US 的)会出问题
    XueXianqi
        9
    XueXianqi  
       186 天前
    @XiLingHost 那到 2038 年之后呢
    ShuWei
        10
    ShuWei  
       186 天前
    这个可以分情况讨论,第一种是业务字段的时间,比如用户预约一个什么时候的服务,这个完全可以跟客户端约定一个带时区信息的时间格式就好了,比如 RFC3339 ,另一种是非业务字段的时间,比如数据库存的数据创建时间、最后更新时间之类的,就服务器自动生成即可
    XiLingHost
        11
    XiLingHost  
       186 天前
    @XueXianqi 用 u64 呗
    flyqie
        12
    flyqie  
       185 天前 via Android
    @XueXianqi #9

    时间戳跟 2038 有啥关系?

    2038 那是 32 位的问题,你可以用 64 啊。。
    julyclyde
        13
    julyclyde  
       185 天前
    @XueXianqi 用 utc 和用 unix timestamp 不是同一个概念
    而且 unix timestamp 也有 64 位的版本
    layxy
        14
    layxy  
    OP
       184 天前
    @ysc3839 额,这块其实没问题,之前没搞明白这块
    XueXianqi
        15
    XueXianqi  
       184 天前
    @julyclyde 感谢,受教了~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2895 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 07:33 · PVG 15:33 · LAX 00:33 · JFK 03:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.