处理夏令时转化业务
夏令时转化
夏令时,(Daylight Saving Time:DST),也叫夏时制,又称“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间调快一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。各个采纳夏时制的国家具体规定不同。全世界有近110个国家每年要实行夏令时。
1986年4月,中国中央有关部门发出“在全国范围内实行夏时制的通知”,具体做法是:每年从四月中旬第一个星期日的凌晨2时整(北京时间),将时钟拨快一小时,即将表针由2时拨至3时,夏令时开始;到九月中旬第一个星期日的凌晨2时整(北京夏令时),再将时钟拨回一小时,即将表针由2时拨至1时,夏令时结束。从1986年到1991年的六个年度,除1986年因是实行夏时制的第一年,从5月4日开始到9月14日结束外,其它年份均按规定的时段施行。在夏令时开始和结束前几天,新闻媒体均刊登有关部门的通告。1992年起,夏令时暂停实行。
简单的说,夏令时就是一天23小时制,比平时快一小时的时间。
虽然在我国夏令时已经不再使用,但是在国外一些地区还是普遍使用夏令时控制各州标准时间的。
所以对有海外市场的APP来说,夏令时转化是必须需要考虑的事情。
时间转化
既然知道了夏令时的本质,那就简单了。
本质上就是将时间+1,
那么对于代码来说,就可以更简单的处理
在Java中
输出:
2022-03-15T10:20Z[Europe/London]
2022-07-15T10:20+01:00[Europe/London]
2022-11-15T10:20Z[Europe/London]
其实可以发现,现在很多语言中的日期类。
都对使用了国际夏令时的地区做了自动转化,所以在转化时,我们只需要将对应的用户地区 「Europe/London」 录进去就可以实现自动转化夏令时的功能
如果是用户强行选择夏令时转化,那么我们也可以强行将时间的时区 offset +1 ,即向前拨快了1小时。
开始结束
因为每个地区对于夏令时的开始结束时间不同,即每个用户存在设置不同夏令时的开始时间和结束时间。
那么我们需要去动态的自动维护其夏令时影响的时间变化
当时间进入夏令时开始时间时,时间+1,结束时回到标准
方案1:
定时任务,凌晨的时候执行一次,查询今天:会启动夏令时的用户,和结束夏令时的用户;
然后将一天分成每片一小时的24片,将对应的开始时间/结束时间,放到查询到的家庭的对应时间片上;
那么在时间片任务启动时,只需要将待处理数据进行倒计时操作;
执行时,由业务方去重新设置用户的所有时间字段值。
对于倒计时方案的设计,可参考定时任务的设计:
- 第三方插件延时
- 延时队列
- 延时线程
- 逐秒判断
- ....
依次执行完这24个任务,这样夏令时的时区转化误差,最多为 01 -59,一小时左右的误差
方案2:
设计一个时间轮,当前时间片上去查询下一个时间片需要进行夏令时新时间维护的数据,并且存入到下一个时间片中;
所以当前时间片做两个事,一是执行上一个时间片传过来的需要处理的数据,二是生成下一个时间片需要处理的数据;
相比于第一个方案的明显优势:
- 具有一定灾难恢复性,数据存储动态化
- 使用更少的线程控制
缺点:
- 生成数据不好做有效控制
- 中间环不可缺时,一步错,步步皆错