java 1.6夏令时
我正在开发一个重要的应用程序,它关注夏令时的变化。java 1.6夏令时,java,date,timezone,dst,Java,Date,Timezone,Dst,我正在开发一个重要的应用程序,它关注夏令时的变化。 我试图通过比较跨越夏令时更改的日期来手动模拟运行时可能发生的情况,因此我进行了以下测试。 我现在的位置是意大利,所以今年从CEST(中欧夏季时间)到CET(中欧时间)的变化发生在10月25日。 我使用了,我的时区是欧洲/罗马 这是我做的测试: Calendar before = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome DST")); //CEST before.set(Cal
我试图通过比较跨越夏令时更改的日期来手动模拟运行时可能发生的情况,因此我进行了以下测试。 我现在的位置是意大利,所以今年从CEST(中欧夏季时间)到CET(中欧时间)的变化发生在10月25日。
我使用了,我的时区是
欧洲/罗马
这是我做的测试:
Calendar before = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome DST")); //CEST
before.set(Calendar.DAY_OF_MONTH, 25);
before.set(Calendar.MONTH, Calendar.OCTOBER);
before.set(Calendar.HOUR_OF_DAY, 2);
before.set(Calendar.MINUTE, 30);
before.set(Calendar.SECOND, 0);
before.set(Calendar.MILLISECOND, 0);
System.out.println(before.getTime());
Calendar after = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome")); //CET
after.set(Calendar.DAY_OF_MONTH, 25);
after.set(Calendar.MONTH, Calendar.OCTOBER);
after.set(Calendar.HOUR_OF_DAY, 2);
after.set(Calendar.MINUTE, 30);
after.set(Calendar.SECOND, 0);
after.set(Calendar.MILLISECOND, 0);
System.out.println(after.getTime());
System.out.println(before.compareTo(after));
输出为:
BEFORE DST CHANGE: Sun Oct 25 03:30:00 CET 2015
AFTER DST CHANGE: Sun Oct 25 02:30:00 CET 2015
before.compareTo(after): 1
比较结果是错误的,即2:30 CEST在2:30 CET之后,但恰恰相反
我不知道这是否是真正的测试。有没有办法解决这个问题?
我也尝试了joda time,但结果是一样的。
提前感谢。您的问题是
getTimeZone(timeZoneId)
无法识别“欧洲/罗马DST”
当它不理解您的输入时。您可以通过getAvailableIDs
查看可用时区ID的列表(在上面的链接中使用下面的getTimeZone
)
应该注意的是CEST
也不在列表中。要模拟CEST
时区,您可以选择以下解决方案之一:
- 我建议您自己使用设置CET和CEST的报价
- 使用相对于GMT定义的时区之一(例如,id为“Etc/GMT+1”)。这将确保您使用的是时区api能够理解的有效时区偏移量
- 在日历实例上设置DST偏移量
Calendar before = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome"));
before.set(Calendar.DST_OFFSET, 3600000);
before.set(Calendar.DAY_OF_MONTH, 25);
before.set(Calendar.MONTH, Calendar.OCTOBER);
before.set(Calendar.HOUR_OF_DAY, 2);
before.set(Calendar.MINUTE, 30);
before.set(Calendar.SECOND, 0);
before.set(Calendar.MILLISECOND, 0);
System.out.println("BEFORE DST CHANGE: " + before.getTime());
Calendar after = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome"));
after.set(Calendar.DAY_OF_MONTH, 25);
after.set(Calendar.MONTH, Calendar.OCTOBER);
after.set(Calendar.HOUR_OF_DAY, 2);
after.set(Calendar.MINUTE, 30);
after.set(Calendar.SECOND, 0);
after.set(Calendar.MILLISECOND, 0);
System.out.println("AFTER DST CHANGE: " + after.getTime());
System.out.println("before.compareTo(after): " + before.compareTo(after));
以及输出:
BEFORE DST CHANGE: Sun Oct 25 02:30:00 CEST 2015
AFTER DST CHANGE: Sun Oct 25 02:30:00 CET 2015
before.compareTo(after): -1
您的问题是
getTimeZone(timeZoneId)
无法识别“欧洲/罗马DST”
当它不理解您的输入时。您可以通过getAvailableIDs
查看可用时区ID的列表(在上面的链接中使用下面的getTimeZone
)
应该注意的是CEST
也不在列表中。要模拟CEST
时区,您可以选择以下解决方案之一:
- 我建议您自己使用设置CET和CEST的报价
- 使用相对于GMT定义的时区之一(例如,id为“Etc/GMT+1”)。这将确保您使用的是时区api能够理解的有效时区偏移量
- 在日历实例上设置DST偏移量
Calendar before = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome"));
before.set(Calendar.DST_OFFSET, 3600000);
before.set(Calendar.DAY_OF_MONTH, 25);
before.set(Calendar.MONTH, Calendar.OCTOBER);
before.set(Calendar.HOUR_OF_DAY, 2);
before.set(Calendar.MINUTE, 30);
before.set(Calendar.SECOND, 0);
before.set(Calendar.MILLISECOND, 0);
System.out.println("BEFORE DST CHANGE: " + before.getTime());
Calendar after = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome"));
after.set(Calendar.DAY_OF_MONTH, 25);
after.set(Calendar.MONTH, Calendar.OCTOBER);
after.set(Calendar.HOUR_OF_DAY, 2);
after.set(Calendar.MINUTE, 30);
after.set(Calendar.SECOND, 0);
after.set(Calendar.MILLISECOND, 0);
System.out.println("AFTER DST CHANGE: " + after.getTime());
System.out.println("before.compareTo(after): " + before.compareTo(after));
以及输出:
BEFORE DST CHANGE: Sun Oct 25 02:30:00 CEST 2015
AFTER DST CHANGE: Sun Oct 25 02:30:00 CET 2015
before.compareTo(after): -1
我的建议是使用数据库中的完整标识符。在您的情况下,您应该使用: 这将确保为该地区使用正确的时区信息,包括需要触发夏令时模式时以及可能的地区异常
不要添加
DST
我的建议是使用。在您的情况下,您应该使用:
这将确保为该地区使用正确的时区信息,包括需要触发夏令时模式时以及可能的地区异常
不要添加DST
by是正确的,应该被接受(单击该大空复选标记图标使其变为绿色)。我将添加一些想法和代码
使用一个好的日期时间库
避免java.util.Date/.Calendard类的混乱。它们是出了名的麻烦,在设计和实现上都有缺陷
这些类已被新的in和更高版本()所取代。这个包裹的灵感来自图书馆。虽然类似,但java.time和Joda-time并不相同。每一个都有另一个所缺乏的特点。您可以使用其中一个或两个
避免使用3-4个字母的时区代码
诸如CET
和CEST
之类的代码既不是标准化的,也不是唯一的。避开它们
使用。其中大多数是“大陆/城市”或“大陆/地区”
您似乎正在使用这些代码来解决问题。将如此繁重的工作留给日期时间库,例如java.time或。时区将UTC的偏移量与DST和其他异常的过去、现在和未来规则集相结合。因此,您可以指定时区名称,并让库计算DST何时生效
DST
截至2015年10月25日凌晨3时。时钟被回滚以重复凌晨2点的时间。所以那天有两次2:30。您可以在下面的示例代码中看到这两个2:30
2015-10-25T02:30+02:00[欧洲/罗马]
2015-10-25T02:30+01:00[欧洲/罗马]
01:00
或02:00
的偏移量才能正确解释
ZoneId zone=ZoneId.of(“欧洲/罗马”);
System.out.println(“----| Local |---------------------------------------------------\n”);
LocalDateTime local_0130=LocalDateTime.of(2015年10月25日、1日、30日);
ZonedDateTime zoned_0130=ZonedDateTime.of(本地_0130,区域);
LocalDateTime local_0230=LocalDateTime.of(2015年10月25日、2日、30日);
ZonedDateTime zoned_0230=ZonedDateTime.of(本地_0230,区域);
LocalDateTime local_0330=LocalDateTime.of(2015年10月25日、3日、30日);
ZonedDateTime zoned_0330=ZonedDateTime.of(本地_0330,区域);
System.out.println(“本地区0130:+local区0130+”:“+zone+”是“+zone区0130”);
System.out.println(“本地区0230:+local区0230+”,“+zone+”是“+zone区0230”);
系统输出打印LN(“本地_0330:+loc