我对java时区有一个棘手的问题(至少对我而言).我将从一个按预期工作的示例开始:
TimeZone tz = TimeZone.getDefault();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
simpleDateFormat.setTimeZone(tz);
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(tz);
calendar.set(Calendar.HOUR_OF_DAY, 0);
System.out.println("0: " + simpleDateFormat.format(calendar.getTime()));
calendar.set(Calendar.HOUR_OF_DAY, 1);
System.out.println("1: " + simpleDateFormat.format(calendar.getTime()));
calendar.set(Calendar.HOUR_OF_DAY, 2);
System.out.println("2: " + simpleDateFormat.format(calendar.getTime()));
Run Code Online (Sandbox Code Playgroud)
输出:
0 4/28/17 12:27 AM
1: 4/28/17 1:27 AM
2: 4/28/17 2:27 AM
Run Code Online (Sandbox Code Playgroud)
而现在有点神奇:
TimeZone tz = TimeZone.getTimeZone("Africa/Cairo");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
simpleDateFormat.setTimeZone(tz);
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(tz);
calendar.set(Calendar.HOUR_OF_DAY, 0);
System.out.println("0: " + simpleDateFormat.format(calendar.getTime()));
calendar.set(Calendar.HOUR_OF_DAY, 1);
System.out.println("1: " + simpleDateFormat.format(calendar.getTime()));
calendar.set(Calendar.HOUR_OF_DAY, 2);
System.out.println("2: " + simpleDateFormat.format(calendar.getTime()));
Run Code Online (Sandbox Code Playgroud)
输出:
0: 4/28/17 1:31 AM
1: 4/28/17 1:31 AM
2: 4/28/17 2:31 AM
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下为什么HOUR_OF_DAY值0和1为特定TimeZone的相同值设置小时?
你的机器有一个旧版本的时区数据,其中埃及会在2017年4月28日当地时间午夜推出时钟.因此,上午12:31不存在,Java正在向前跳过一小时而是1.
2016年7月5日,IANA时区数据2016f随着非洲/开罗时区的变化而发布,从那时起不再遵守DST.(这是一个非常晚的公告,因为下一个变化将是2016年7月8日.)
您可以在不同版本的IANA数据中查看每个IANA时区的所有转换,网址为http://nodatime.github.io/tzvalidate/.(免责声明:我构建了该页面.我启动了tzvalidate项目,以验证不同的日期/时间库以相同的方式理解时区数据.)
1我认为API应该强制你说出你想要在那种情况下发生的事情,但我不会在这里讨论所有错误的java.util.Calendar事情......