客户端、服务器、数据库之间的时区转换

简介: 做国外的项目经常会遇到时区转换的问题,这里简单针对遇到的时区问题做个记录,也希望对大家有所帮助,少走弯路。(本文设计开发语言为java)

背景


做国外的项目经常会遇到时区转换的问题,这里简单针对遇到的时区问题做个记录,也希望对大家有所帮助,少走弯路。(本文设计开发语言为java)


时区的概念


先说下时区的概念 初中地理好的同学应该还记得,由于地球不停地自西向东旋转,使得昼夜半球和晨昏线也不断自东向西移动。


image.gif


为了照顾到各地区的使用方便,又使其他地方的人容易将本地的时间换算到别的地方时间上去。有关国际会议决定将地球表面按经线从东到西,划成一个个区域(时区),全球一共分为24个时区(东12区+西12区),相邻时区时间相差1个小时。


规定英国(格林尼治天文台旧址)所在区域为零时区,往东分别为东1区、东2区……东11区、东12区,往西分别为西1区、西2区……西11区、西12区,东12区和西12区重合(所属同一个时区)。


16.png


我们国家由于地域广袤辽阔,横跨了5个时区(东5、东6、东7、东8、东9),但建国以后,全国统一采用首都北京所处的东8区的时间。


虽然全世界一共划分了24个时区,同一个时间点,每个时区钟表上显示的时间各不同,但是它们仅仅是同一时刻在不同地区展示的形式,它们代表的仍然是一个时刻/瞬间。


跑题结束,开始正文。



跨境电商下单场景涉及的时区转换


先以跨境电商系统中的下单场景举个栗子,如果该电商系统的【数据库服务器】部署在英国伦敦,【应用服务器】部署在德国柏林,北京时间2020-06-01 10:00:00 有位北京的用户在通过浏览器在该网站上买了一个儿童节礼物。


这个过程就涉及到了时区转换的问题,一般刚给电脑安装操作系统的时候,都会让选择电脑所在时区,系统就是以时区来显示时间的。上面下单的例子涉及到三个设备:客户端(电脑浏览器/手机App)、网站web服务器、网站数据库服务器,都配置了对应的时区,假设这三种设备配置的时区就是所在地区的时区。


在【客户端→web服务器】、【web服务器→数据库】、【数据库→web服务器】、【web服务器→客户端】这几个过程都涉及到了时区的转换。如果不考虑时区转换,北京的用户在2020-06-01 10:00:00下单,web服务器处理的时候认为订单时间是在2020-06-01 03:00:00,然后传给数据库的订单时间也是2020-06-01 03:00:00,数据库保存的时候会保存成2020-06-01 03:00:00。当北京的用户查询订单的时候,数据库返回给应用服务器的订单时间为2020-06-01 03:00:00,最后应用服务器返回给用户的订单时间(用户看到的时间)也就是2020-06-01 03:00:00,如下图:



0.png


但实际上对用户来说是在2020-06-01 10:00:00下的单,应该是这样:

1.png


要解决这个问题,可以通过在客户端和web服务器、web服务器和数据库两两交互的时候添加”时区协议“来自动转换时区。


假如服务端应用是用SpringBoot实现的,可以在配置文件中配置

spring.jackson.time-zone = Asia/Shanghai(注意没有Asia/Beijing哈),这样应用服务器接收到客户端传来的时间后会把这个时间当成是东8区的时间转换成服务器所在时区的时间,也就是会把2020-06-01 10:00:00(UTC+8)转换成2020-06-01 03:00:00(UTC+1)。同样当客户端查询时,服务端会把当前时区的时间2020-06-01 03:00:00(UTC+1)转换成客户端所在时区的时间2020-06-01 10:00:00(UTC+8)。


假如服务端是用JDBC和MySQL交互,可以在MySQL连接中配置 serverTimezone=Europe/London,这样当应用服务器向Mysql发起持久化数据的请求时,会把服务器所在时区的时间2020-06-01 03:00:00(UTC+1)转换成数据库所在时区的时间2020-06-01 02:00:00(UTC)。同样当应用服务器查询数据的时候,会把数据库所在时区的时间2020-06-01 02:00:00(UTC)转换成服务器所在时区的时间2020-06-01 03:00:00(UTC+1)。


题外话


1、修改时区


一般浏览器的时区是默认获取的当前计算机系统的时区;应用服务器中获取的时区默认为当前计算机系统时区,可以在项目启动时设置(java -Duser.timezone=Asia/Shanghai -jar xxx.jar),也可以通过java.util.TimeZone动态设置;数据库时区默认也是取当前计算机系统时区,可以通过命令set global time_zone修改时区,可也以通过修改配置文件等其他方式。


2、Java中Date的时区无关性


Date类中有个fastTime变量,用来存储当前时刻的毫秒数。Date默认构造函数用System.currentTimeMillis()来为这个毫秒数赋值。


如果此刻在北京、柏林、伦敦同时执行如下语句:Date date = new Date();,那这三个date对象里存的毫秒数是相同的吗?答案是这3个Date里的毫秒数是完全一样的。


确切的说,Date对象里存的是自格林威治时间( GMT)1970年1月1日0点至Date对象所表示时刻所经过的毫秒数。所以,如果某一时刻遍布于世界各地的程序员同时执行new Date语句,这些Date对象所存的毫秒数是完全一样的。也就是说,Date里存放的毫秒数是与时区无关的。


目录
打赏
0
0
0
0
6
分享
相关文章
服务器数据恢复—云服务器上mysql数据库数据恢复案例
某ECS网站服务器,linux操作系统+mysql数据库。mysql数据库采用innodb作为默认存储引擎。 在执行数据库版本更新测试时,操作人员误误将在本来应该在测试库执行的sql脚本在生产库上执行,导致生产库上部分表被truncate,还有部分表中少量数据被delete。
64 25
[Git] 深入理解 Git 的客户端与服务器角色
Git 的核心设计理念是分布式,每个仓库既可以是客户端也可以是服务器。通过 GitHub 远程仓库和本地仓库的协作,Git 实现了高效的版本管理和代码协作。GitHub 作为远程裸仓库,存储项目的完整版本历史并支持多客户端协作;本地仓库则通过 `.git` 文件夹独立管理版本历史,可在离线状态下进行提交、回滚等操作,并通过 `git pull` 和 `git push` 与远程仓库同步。这种分布式特性使得 Git 在代码协作中具备强大的灵活性和可靠性。
69 18
[Git] 深入理解 Git 的客户端与服务器角色
如何解决 MySQL 数据库服务器 CPU 飙升的情况
大家好,我是 V 哥。当 MySQL 数据库服务器 CPU 飙升时,如何快速定位和解决问题至关重要。本文整理了一套实用的排查和优化套路,包括使用系统监控工具、分析慢查询日志、优化 SQL 查询、调整 MySQL 配置参数、优化数据库架构及检查硬件资源等步骤。通过一个电商业务系统的案例,详细展示了从问题发现到解决的全过程,帮助你有效降低 CPU 使用率,提升系统性能。关注 V 哥,掌握更多技术干货。
ChatMCP:基于 MCP 协议开发的 AI 聊天客户端,支持多语言和自动化安装 MCP 服务器
ChatMCP 是一款基于模型上下文协议(MCP)的 AI 聊天客户端,支持多语言和自动化安装。它能够与多种大型语言模型(LLM)如 OpenAI、Claude 和 OLLama 等进行交互,具备自动化安装 MCP 服务器、SSE 传输支持、自动选择服务器、聊天记录管理等功能。
427 15
ChatMCP:基于 MCP 协议开发的 AI 聊天客户端,支持多语言和自动化安装 MCP 服务器
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
76 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
GBase 数据库 加密客户端---数据库用户口令非明文存放需求的实现
GBase 数据库 加密客户端---数据库用户口令非明文存放需求的实现
服务器数据恢复—华为S5300存储Oracle数据库恢复案例
服务器存储数据恢复环境: 华为S5300存储中有12块FC硬盘,其中11块硬盘作为数据盘组建了一组RAID5阵列,剩下的1块硬盘作为热备盘使用。基于RAID的LUN分配给linux操作系统使用,存放的数据主要是Oracle数据库。 服务器存储故障: RAID5阵列中1块硬盘出现故障离线,热备盘自动激活开始同步数据,在同步数据的过程中又一块硬盘离线,RAID5阵列瘫痪,上层LUN无法使用。
Docker Compose V2 安装常用数据库MySQL+Mongo
以上内容涵盖了使用 Docker Compose 安装和管理 MySQL 和 MongoDB 的详细步骤,希望对您有所帮助。
161 42

热门文章

最新文章