web 服务时区问题

198 天前
 layxy

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

1137 次点击
所在节点    程序员
15 条回复
XiLingHost
198 天前
统一传时间戳啊,然后展示让前端做
ysc3839
198 天前
“比如用户是东八区,服务器按 0 时区存,展示时就差了 8 小时”
为什么会呢?你前面不是说“由前端根据访问者所在时区进行格式化”吗?
ho121
198 天前
一般是按照服务器时间。
展示也要转换时区再展示的啊。
WhateverYouLike
198 天前
2 楼加一
ratazzi
198 天前
创建、更新等时间都是以服务器为准,必须要客户传的比如预约、达到时间等之类的才会用客户的
ETiV
198 天前
奇异博士告诉我们:不要玩弄时间

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

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

时间戳跟 2038 有啥关系?

2038 那是 32 位的问题,你可以用 64 啊。。
julyclyde
197 天前
@XueXianqi 用 utc 和用 unix timestamp 不是同一个概念
而且 unix timestamp 也有 64 位的版本
layxy
195 天前
@ysc3839 额,这块其实没问题,之前没搞明白这块
XueXianqi
195 天前
@julyclyde 感谢,受教了~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/984664

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX