原来是夏令时到了!
过去一周,发生的大事还真是一大堆,毛子和沙特原油谈判谈崩了,全球油价暴跌,美国开启过山车模式,新冠疫情全球爆发…. 当然,最让我神伤的却是一个小事,美国在3月8日开始夏令时了!
What,夏令时是什么鬼!夏令时是为了节约能源,人为规定的一个时间标准,英文叫Dailight Saving Time(DST),在夏令时,时间被人为的调快了一小时,其目的是为了充分利用太阳光照,减少照明用电;在冬天,又会把时间恢复到标准时间。
美国夏令时一般在3月第二个周日的凌晨2点(当地时间)开始,将时钟调到3点,俗称”Spring Forward 1 Hour”;在11月第一个周日的凌晨2点(当地时间)结束夏令时,将时钟调到1点,调慢一个小时,俗称”Fall Back 1 Hour”。
夏令时,表示为了节约能源,人为规定时间的意思。也叫夏时制,夏时令(Daylight Saving Time:DST),又称“日光节约时制”和“夏令时间”,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间调快一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。各个采纳夏时制的国家具体规定不同。目前全世界有近110个国家每年要实行夏令时。
也就是说,这个月的8号缺少了2点(2:00:00~2:59:59)这个时间段,直接跳到了的3点,而且时区从GMT-8切换到了GMT-7。下面我们通过一个程序,来观察下3月7号和8号48个小时的时间变化:
package cc.databus.puggo.rpc;
import org.junit.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class TestDST {
// 对应冬令时下的美西时间
private static final TimeZone GMT_8m = TimeZone.getTimeZone("GMT-8");
// 对应北京时间
private static final TimeZone GMT_8p = TimeZone.getTimeZone("GMT+8");
// 美西时间
private static final TimeZone LOS_ANGL = TimeZone.getTimeZone("America/Los_Angeles");
@Test
public void test() throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
sdf.setTimeZone(LOS_ANGL);
Date base = sdf.parse("2020-03-09 00:00:00");
Calendar calendar = Calendar.getInstance(LOS_ANGL);
calendar.setTime(base);
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ZZZ");
for (int i = 0; i < 48; i++) {
calendar.add(Calendar.HOUR_OF_DAY, -1);
Date time = calendar.getTime();
sdf.setTimeZone(LOS_ANGL);
String lsAngelTime = sdf.format(time);
sdf.setTimeZone(GMT_8m);
String gmtMinus8Time = sdf.format(time);
sdf.setTimeZone(GMT_8p);
String gmtPlus8Time = sdf.format(time);
System.out.println(String.format("中国时间: %s\t时区-8: %s\t美西: %s", gmtPlus8Time, gmtMinus8Time, lsAngelTime));
}
}
}
输出如下:
对于开发,尤其涉及国际项目的时候,一定要关注时令的变化,评估好在时令切换期间存在的问题和风险。总结下这次在冬令时切夏令时,我们遇到的问题:
- 在2020-03-08,产生了一个空的数据分区,也就是2点的分区;
- 有一断计算日期分区的代码,是基于某一天的0点,依次天数-1,然而,由于时区的切换,导致8号的分区无法产生;
- 一天的起始时间定位到了前一天的23点