HOUR_OF_DAY为值0和1

时间:2017-04-28 15:40:19

标签: java timezone

我对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()));

输出:

0 4/28/17 12:27 AM
1: 4/28/17 1:27 AM
2: 4/28/17 2:27 AM

现在有点神奇了:

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()));

输出:

0: 4/28/17 1:31 AM
1: 4/28/17 1:31 AM
2: 4/28/17 2:31 AM

有人可以解释为什么值0和1的HOUR_OF_DAY在特定TimeZone的相同值上设置小时?

3 个答案:

答案 0 :(得分:7)

你的机器有一个旧版本的时区数据,其中埃及会在2017年4月28日当地时间午夜推出时钟。所以12:31 am将不存在,Java是向前跳过一小时而不是 1

2016年7月5日,IANA时区数据2016f发布,随着非洲/开罗时区的变化,从那时起不遵守DST。 (这是一个非常晚的公告,因为下一个更改已经是2016年7月8日。)

您可以在http://nodatime.github.io/tzvalidate/的不同版本的IANA数据中查看每个IANA时区的所有转换。 (免责声明:我构建了该页面。我启动了tzvalidate项目,以验证不同的日期/时间库以相同的方式理解时区数据。)

1 我认为API应该强制你说出你想要在那种情况下发生什么,但我不会进入所有那个&# 39;这里的java.util.Calendar错了......

答案 1 :(得分:2)

几年前,该时区计划在2017年4月28日晚上进行夏令时转换:凌晨00:00,时钟将向前移动一小时。因此,午夜和凌晨1点之间的时间因转换而无效。

然而,这种过渡并未在实践中发生,因为它被取消了(过去几年埃及似乎已经取消并恢复了几次DST。)

总之,您可能正在使用旧版本的Java,它具有过时的时区数据库。

答案 2 :(得分:0)

你是对的。问题是28日的时间转换。今天一切正常:)