[个人]关于跨时区方面的问题和实践
1、时区背景
1.1、为什么有时区:
世界上不同的地区有不同的时间,这是因为地球是一个球体,它的自转速度是不同的,所以当太阳从一个地区升起时,它在其他地区仍然是黑夜。为了解决这个问题,我们把地球分成了24个时区,每个时区都有一个标准时间。这样,当太阳从一个地区升起时,我们可以根据这个地区的时区来确定其他地区的时间。
实际上,常常1个国家或1个省份同时跨着2个或更多时区,为了照顾到行政上的方便,常将1个国家或1个省份划在一起。所以时区并不严格按南北直线来划分,而是按自然条件来划分。例如,中国幅员宽广,差不多跨5个时区,但为了使用方便简单,实际上在只用东八时区的标准时即北京时间为准(GMT+8)。
1.2、时区划分方法:
地球是自西向东自转,东边比西边先看到太阳,东边的时间也比西边的早。东边时刻与西边时刻的差值不仅要以时计,而且还要以分和秒来计算,这给人们带来不便。
为了克服时间上的混乱,1884年在华盛顿召开的一次国际经度会议(又称国际子午线会议)上,规定将全球划分为24个时区(东、西各12个时区)。规定英国(格林尼治天文台旧址)为中时区(零时区)、东1—12区,西1—12区。每个时区横跨经度15度,时间正好是1小时。最后的东、西第12区各跨经度7.5度,以东、西经180度为界。每个时区的中央经线上的时间就是这个时区内统一采用的时间,称为区时,相邻两个时区的时间相差1小时。
例如,中国东8区的时间总比泰国东7区的时间早1小时,而比日本东9区的时间晚1小时。因此,出国旅行的人,必须随时调整自己的手表,才能和当地时间相一致。凡向西走,每过一个时区,就要把表拨慢1小时(比如2点拨到1点);凡向东走,每过一个时区,就要把表拨快1小时(比如1点拨到2点)。并且规定英国(格林尼治天文台旧址)为本初子午线,即零度经线。
2、客户的时区问题
2.1、时区问题中的不变量和变量:
不变量:时间戳,时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起从0开始至现在的总秒数(1秒=1000ms,每秒加1000),这个时间戳全球是一致的
变量:不同时区,时间戳转换后的显示的时间不一样,从上面不变量的描述中我们知道时间戳为0的时间在格林威治时区的显示和我们北京时间时区的显示年月日时分秒上可能存在偏差,如下图所示时间戳一致的情况下北京时间是2023年11月13日18:42分,在不同时区可能是GMT-12:00时区的2023年11月12日22点-24点,也可能是GMT+14:00时区的2023年11月14日00:43分,显示上可能就是前一天或者后一天(下面截图仅举例子用)
2.2、造成此类问题的前提与影响:
(1)前提:APP内时间未与依赖服务器时间保持同一时区格式,跟随设备时区变动
影响:假如服务器是北京时间,设备时区在美国,手机时钟与APP内显示的时间一致,但是服务器接口返回的非时间戳字符串年月日时分秒文本可能差几个小时可能跨天
(2)前提:APP内时间与依赖服务器时间保持同一时区格式,不跟随设备时区变动
影响:假如服务器是北京时间,设备时区在美国,手机时钟已经显示晚上20点了,但是页面上的显示时间可能还是早上8点
(2)前提:我们项目中后端的考勤日都是按照北京时间的0-24点划分的
影响:考勤日北京时间的0-24点不等于国外客户的0-24点,例如美国的考勤日0-24点,相当于中国的前一天的中午12点到第二天的中午12点,有可能会造成打卡班次和打卡记录的显示不全,后端的转换改动也会过大
3、我们项目中的处理方式
3.1、之前保持以北京时间为标准的方式
在我们的项目中我们是以北京时间为标准的,一般的上班情况是早8-10点晚17-21点左右,如果是在国内上班,使用上是没有问题的,即使你是跨天班次,年月日时分秒都保持一致的,国人也都能看的明白(除非手动改自己手机设备时区,把自己改乱了),但是随着我们国外的客户越来越多,假如我去外国出差了,我打开手机的打卡页,自动获取的时区是美国时区GMT-5,时钟显示凌晨4:22分,中间打卡按钮显示17:22分,我打个卡后,下班打卡也显示17:22,这种显示不一给了国外的客户一种大大的疑惑感,还得咨询管理员等得知APP显示的全是北京时间,正常记得自己的打卡时间,从北京时间换算成国外时间正常打就可以了,维护了系统和APP的国人显示逻辑,给国外打卡客户带来了转换的麻烦
同时进入打卡记录页和我的考勤页,国外时区的客户也是比较懵逼的,示例可看下面几个图
3.2、目前项目中的处理方式
因为时间戳的数值是全球统一的数值,所以我们后端部分接口采用了返回字段值是时间戳的形式,前端和移动端上再读取手机设备的时区把这个时间戳转换为年月日时分秒的格式显示,那就会得到使用者使用手机设备时区相应的绝对正确的时间年月日时分秒显示,但是以前后端返回的例如“2023-11-13 17:49”等之类字符串文字,因为是北京时间的时间格式,我们前端和移动端需要相应的把它根据北京时间转换成时间戳再根据手机设备时区处理成例如“2023-11-13 04:49”
打卡页全部转换为了设备时区的相应时间显示,但是打卡记录页和我的考勤页暂时不能够全部转换成,因为可能存在考勤日的不相等情况,我在2.2(3)中已经举例说过了,我们在打卡记录页的每个打卡记录上标示了是否跨天的显示,在我的考勤页,因为考勤日期全是接口返回,改动会较大暂时也没有改动,所以这个使用场景不多的我的考勤页面,在非北京时区的手机设备时区上会显示“(GMT+8)”的提示,实际效果如下图
3.3、两种方式的对比
分别从3.1的三张图与3.2的三张图进行对比,前端和移动端根据时区的变化内部进行了处理和转换,减少了用户的理解门槛同时兼顾了北京时间时区的客户,暂时够用,但是由于根源北京时间考勤日的概念,处理的依旧不完美
4、总结
时区问题是一个根据时区变换转换标准和“落地随俗”的问题,所以经常听到电视等地方说倒时差这个行为,所以通过时间戳进行自适应转换是一个比较优的解法,后端也应该减少类似年月日时分秒这样的字符串字段值,而考勤日这个概念也需要设置班次的管理员根据自己员工所在地区的时区进行区别设置,这样的体验会好一些
版权声明:
作者:lichengxin
链接:https://www.techfm.club/p/95369.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论