Spring boot 2.x 项目如何兼容不同时区的客户?

350 天前
 coderstory

目前有个 spring boot 2.7.15 的项目,已经开发了很多的功能。突然来了一个需求,存在美国的客户,如果是美国的客户打开的页面,时间数据都需要转换成美国客户的当地时区对应的时间,客户插入的数据对于在中国的客户而言,需要转换成 CST 时区的时间。

也就是一个系统兼容多个时区的客户,时间需要都需要基于客户的时区处理掉。

目前主要涉及的场景挺多的,比如 mysql 的数据查询和查询,查询的话用户给的时间筛选条件都得处理,查询结果中的时间类型的值需要处理,java 代码中的 LocalDate.now()之类的时间创建操作也要处理。表单提交的时间值都需要处理。。。

整理一下,大概有如下场景需要处理 1.各种接口请求参数 这个可以 AOP 拦截 全部处理掉 2.java 代码中的时间创建 3.数据库中的时间创建 比如使用了 insert values (now()) 这种函数 或者时间字段设置了默认值 4.数据库查询返回了时间值 5.调用外部接口返回的值中的时间 ....

需求目前只是大致的分析了一点,不知道各位大佬是否经历过这样的需求?给一点点经验吧

4420 次点击
所在节点    Java
21 条回复
crazyweeds
350 天前
国际化项目,用时间戳吧。
psx2019
350 天前
永远只存绝对时间戳,时区什么的是前端需要考虑的问题.
shengchen11
350 天前
都用时间戳,前端处理时区
Kyle18Tang
349 天前
如果代码中都是用的 LocalDateTime ,那么请求响应使用 ISO-8601 的时间格式。统一在序列化反序列化的时候转成数据库时区。
ragnaroks
349 天前
要个工期改成时间戳,前端格式化
uselessVisitor
349 天前
中间加这种破坏性的需求就很烦啊,最方便的就是改成时间戳,刷数据一劳永逸。不然为了这个需求会引入很多屎山
lsry
349 天前
数据库存带时区的时间,前端根据时区转换成对应时间就好
yjxjn
349 天前
上面说的带时区其实不太好,最好的方法就是在数据库里改成时间戳,而且是 UTC+0 时区,前端根据 user 浏览器来转换时间。+8 还是+9 的。
clf
349 天前
原则上,数据统一时区,无论服务器部署在哪里,后端和数据库都采用统一的时区处理。前端展示的时候才做国际化。

(所以最好用时间戳
cslive
349 天前
时间戳,前端根据不同时区转换
realkaiway
349 天前
后端就存 UTC+0 的格式,清晰且直白,2023-12-11T22:00:00.000+00:00,前端用 dayjs 等封装一个工具类,带时间的提交统一转 utc ,展示的话则根据客户端的时区转 local
BBCCBB
349 天前
时间全都存 utc0 时间/时间戳, 前端自己转.
cnhongwei
349 天前
已有数据没有?如果没有的话,系统不变,将默认时区设置为 UTC ,后端如果使用 LocalDateTime 之类的,都不用修改,其它的都是前端的事了。如果已有数据,能停机修改最简单,如果不能的话,怎么热更新就很麻烦了。
zjyl1994
349 天前
DB 里存时间戳,然后过滤数据的时候前端的条件也都处理成时间戳再发过来查。
前端展示的时候按照 Local 时区格式化就好了
OnlySeePost
349 天前
数据库里存俩个,一个时区,一个当地时间。不能直接用 utc 时间。原因:冬/夏令时转换。比如 cet 时区,冬天是 utc+1 ,夏天是 utc+2 ,你要是冬天存个 cet 时间 9 点,那么数据库里就是 8 点,到了夏天,时区转化一下,就成了 10 点。
tramm
349 天前
1.时间戳
2.Header 中加时区信息,springboot 接收,返回都处理下.
vczyh
349 天前
建议改造一下,应用和数据库不动,但是和客户端交换的时间必须使用时间戳或者 https://en.wikipedia.org/wiki/ISO_8601
huangcjmail
349 天前
@OnlySeePost #15 你说的这个问题不存在吧,美东时间就是存在冬令时夏令时转换的。至少 Java 使用工具类去转换的时候,我只用传一个时间戳进去,它自己能识别到的。不管冬令时夏令时都是正确的。
ikas
348 天前
无非就是后台服务端,db 统一时区,出入参转换携带时区统一转换
api 出入参一般要么是使用带时区的格式,utc 时间戳,要么是额外参数传递时区,比如 cookie,header,query 参数

spring 内置的国际化 LocaleContextResolver,基于它统一转换出入参
wokerrrrrrrrr
348 天前
我的实践是这样的:
1.后端 java 代码统一使用 java8 的 Instant 时间类
2.数据库 mysql 统一用 bigint 存储时间戳
然后剩下的就是各种转换的事儿了,根据前端需要,既可以返回时间戳,也可以返回带时区的时间格式字符串( ISO 标准那种)。
前端具体展示什么时区,从返回数据里再转就行了

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

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

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

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

© 2021 V2EX