目前有个 spring boot 2.7.15 的项目,已经开发了很多的功能。突然来了一个需求,存在美国的客户,如果是美国的客户打开的页面,时间数据都需要转换成美国客户的当地时区对应的时间,客户插入的数据对于在中国的客户而言,需要转换成 CST 时区的时间。
也就是一个系统兼容多个时区的客户,时间需要都需要基于客户的时区处理掉。
目前主要涉及的场景挺多的,比如 mysql 的数据查询和查询,查询的话用户给的时间筛选条件都得处理,查询结果中的时间类型的值需要处理,java 代码中的 LocalDate.now()之类的时间创建操作也要处理。表单提交的时间值都需要处理。。。
整理一下,大概有如下场景需要处理 1.各种接口请求参数 这个可以 AOP 拦截 全部处理掉 2.java 代码中的时间创建 3.数据库中的时间创建 比如使用了 insert values (now()) 这种函数 或者时间字段设置了默认值 4.数据库查询返回了时间值 5.调用外部接口返回的值中的时间 ....
需求目前只是大致的分析了一点,不知道各位大佬是否经历过这样的需求?给一点点经验吧
1
crazyweeds 2023-12-11 17:40:21 +08:00
国际化项目,用时间戳吧。
|
2
psx2019 2023-12-11 17:40:30 +08:00
永远只存绝对时间戳,时区什么的是前端需要考虑的问题.
|
3
shengchen11 2023-12-11 17:41:18 +08:00
都用时间戳,前端处理时区
|
4
Kyle18Tang 2023-12-11 18:13:15 +08:00
如果代码中都是用的 LocalDateTime ,那么请求响应使用 ISO-8601 的时间格式。统一在序列化反序列化的时候转成数据库时区。
|
5
ragnaroks 2023-12-11 19:58:11 +08:00
要个工期改成时间戳,前端格式化
|
6
uselessVisitor 2023-12-11 20:03:28 +08:00
中间加这种破坏性的需求就很烦啊,最方便的就是改成时间戳,刷数据一劳永逸。不然为了这个需求会引入很多屎山
|
7
lsry 2023-12-11 21:31:16 +08:00
数据库存带时区的时间,前端根据时区转换成对应时间就好
|
8
yjxjn 2023-12-11 21:37:02 +08:00
上面说的带时区其实不太好,最好的方法就是在数据库里改成时间戳,而且是 UTC+0 时区,前端根据 user 浏览器来转换时间。+8 还是+9 的。
|
9
clf 2023-12-11 21:38:10 +08:00
原则上,数据统一时区,无论服务器部署在哪里,后端和数据库都采用统一的时区处理。前端展示的时候才做国际化。
(所以最好用时间戳 |
10
cslive 2023-12-11 21:45:01 +08:00 via Android
时间戳,前端根据不同时区转换
|
11
realkaiway 2023-12-11 21:50:52 +08:00
后端就存 UTC+0 的格式,清晰且直白,2023-12-11T22:00:00.000+00:00,前端用 dayjs 等封装一个工具类,带时间的提交统一转 utc ,展示的话则根据客户端的时区转 local
|
12
BBCCBB 2023-12-11 21:55:04 +08:00
时间全都存 utc0 时间/时间戳, 前端自己转.
|
13
cnhongwei 2023-12-11 22:14:06 +08:00
已有数据没有?如果没有的话,系统不变,将默认时区设置为 UTC ,后端如果使用 LocalDateTime 之类的,都不用修改,其它的都是前端的事了。如果已有数据,能停机修改最简单,如果不能的话,怎么热更新就很麻烦了。
|
14
zjyl1994 2023-12-11 22:28:14 +08:00
DB 里存时间戳,然后过滤数据的时候前端的条件也都处理成时间戳再发过来查。
前端展示的时候按照 Local 时区格式化就好了 |
15
OnlySeePost 2023-12-12 00:49:32 +08:00 via Android
数据库里存俩个,一个时区,一个当地时间。不能直接用 utc 时间。原因:冬/夏令时转换。比如 cet 时区,冬天是 utc+1 ,夏天是 utc+2 ,你要是冬天存个 cet 时间 9 点,那么数据库里就是 8 点,到了夏天,时区转化一下,就成了 10 点。
|
16
tramm 2023-12-12 08:18:27 +08:00
1.时间戳
2.Header 中加时区信息,springboot 接收,返回都处理下. |
17
vczyh 2023-12-12 09:35:26 +08:00
建议改造一下,应用和数据库不动,但是和客户端交换的时间必须使用时间戳或者 https://en.wikipedia.org/wiki/ISO_8601
|
18
huangcjmail 2023-12-12 09:42:16 +08:00
@OnlySeePost #15 你说的这个问题不存在吧,美东时间就是存在冬令时夏令时转换的。至少 Java 使用工具类去转换的时候,我只用传一个时间戳进去,它自己能识别到的。不管冬令时夏令时都是正确的。
|
19
ikas 2023-12-12 20:31:15 +08:00
无非就是后台服务端,db 统一时区,出入参转换携带时区统一转换
api 出入参一般要么是使用带时区的格式,utc 时间戳,要么是额外参数传递时区,比如 cookie,header,query 参数 spring 内置的国际化 LocaleContextResolver,基于它统一转换出入参 |
20
wokerrrrrrrrr 2023-12-13 13:50:48 +08:00
我的实践是这样的:
1.后端 java 代码统一使用 java8 的 Instant 时间类 2.数据库 mysql 统一用 bigint 存储时间戳 然后剩下的就是各种转换的事儿了,根据前端需要,既可以返回时间戳,也可以返回带时区的时间格式字符串( ISO 标准那种)。 前端具体展示什么时区,从返回数据里再转就行了 |
21
wokerrrrrrrrr 2023-12-13 13:52:49 +08:00
@wokerrrrrrrrr 前后端传参约定好用 ISO 标准的时间字符串或者时间戳,时区就错不了
|