前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >客户端、服务器、数据库之间的时区转换

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

作者头像
DannyHoo
发布2022-04-02 10:54:27
4.7K0
发布2022-04-02 10:54:27
举报
文章被收录于专栏:Danny的专栏Danny的专栏

背景

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

时区的概念

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

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

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

在这里插入图片描述
在这里插入图片描述

我们国家由于地域广袤辽阔,横跨了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,如下图:

在这里插入图片描述
在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

要解决这个问题,可以通过在客户端和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里存放的毫秒数是与时区无关的。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 时区的概念
  • 跨境电商下单场景涉及的时区转换
  • 题外话
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档