当前位置: 首页 > 科技观察

听干货讲项目的多时区处理

时间:2023-03-21 01:37:07 科技观察

为什么要讲这个问题?很多时候在项目的开发中,我可能没有接触过太多的时区。大部分项目部署在中国,同时只为国内用户提供服务。出国后,项目中很多时候都和当地时间不一样,对用户很不友好。例如,近几年在线教育非常火爆。像一些外教,教孩子英语,如何保证双方在特定的时间进入课堂就变得很普遍。业界在为多个时区的用户提供服务时如何处理时间?在描述行业中的加工之前,我们先了解几个概念。时间戳是指从北京时间1970年1月1日00:00:00(北京时间1970年1月1日08:00:00)到现在的总秒数,用有符号的32位整数表示。GMT:GreenwichMeanTime格林威治标准时间。这是根据英国格林威治天文台的观测结果得出的时间。这是英国格林威治的当地时间。这个地方的当地时间曾经被认为是世界标准时间。UT:UniversalTime世界时间。从原子钟计算的时间。UTC:CoordinatedUniversalTime协调世界时。因为地球自转越来越慢,每年都会比前一年多零点几秒。每隔几年,协调世界时组织就会在世界时上加1秒(会有闰秒即61s,一般不处理),这样基于原子钟的世界时也不算太远来自基于天文学(人类感知)的GMT。并将生成的时间称为UTC,这是当今使用的通用时间。GMT和UTC的维度不同,但是取值是一样的,UTC=GTM+0(时区)我们都知道时间可以用GMT或者UTC来表示,时间戳是根据具体的格林威治时间来的,它地球上传1秒,世界上任何地方都是1秒,所以同时,全局值是一样的。可以看看java例子,发现不同时区的时间戳确实是相等的//获取不同时区的时间来计算时间戳1),ZoneOffset.ofHours(7));OffsetDateTimeoffsetDateTime8=OffsetDateTime.of(localDateTime,ZoneOffset.ofHours(8));System.out.println(offsetDateTime7.toEpochSecond()==offsetDateTime8.toEpochSecond());//true所以,业界对于时区的处理,基本上都是根据时间戳来处理的。前后端配合,保证用户看到的是当地时间。对于这种问题,后端需要注意服务器是否会部署在不同的时区。建议将获取系统时间的操作改为获取统一时区的时间,然后转换成时间戳存储;前端最重要的是在请求中将时区传递给后端。一般可以在请求头中加入获取系统的时区,将时区传给后端。后端根据时区将数据库中的时间戳转换成对应时区的时间,比如+8。下图最后,推荐使用java8时间类进行处理。java8中有几个核心类:ZoneId和ZoneOffset,主要表示时区和偏移量。Instant表示时间戳。Duration和Period代表时间差。前者代表时间差异,后者代表日期差异。LocalDate,LocalTime,LocalDateTime表示日期,时间,日期+时间ZonedDateTime,OffsetDateTime时间带时区信息