TimeZone.setDefault(TimeZone.getTimeZone("BET"));
Locale.setDefault(Locale.ENGLISH);
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS zzzz");
Date d0 = sdf1.parse("2037-10-17 23:00:00.000");
Date d1 = sdf1.parse("2037-10-17 23:00:00.001");
Date d2 = sdf1.parse("2037-10-17 23:59:59.999");
Date d3 = sdf1.parse("2037-10-18 00:00:00.000");
Date d4 = sdf1.parse("2037-10-18 00:00:00.001");
Date d5 = sdf1.parse("2037-10-18 00:59:59.999");
Date d6 = sdf1.parse("2037-10-18 01:00:00.000");
Date d7 = sdf1.parse("2037-10-18 01:00:00.001");
Date d8 = sdf1.parse("2037-10-18 01:59:59.999");
Date d9 = sdf1.parse("2037-10-18 02:00:00.000");
System.out.println(sdf2.format(d0) + "(" + d0.getTime() + "), dst: " + TimeZone.getDefault().inDaylightTime(d0) + ", offset: " + TimeZone.getDefault().getOffset(d0.getTime()));
System.out.println(sdf2.format(d1) + "(" + d1.getTime() + "), dst: " + TimeZone.getDefault().inDaylightTime(d1) + ", offset: " + TimeZone.getDefault().getOffset(d1.getTime()));
System.out.println(sdf2.format(d2) + "(" + d2.getTime() + "), dst: " + TimeZone.getDefault().inDaylightTime(d2) + ", offset: " + TimeZone.getDefault().getOffset(d2.getTime()));
System.out.println(sdf2.format(d3) + "(" + d3.getTime() + "), dst: " + TimeZone.getDefault().inDaylightTime(d3) + ", offset: " + TimeZone.getDefault().getOffset(d3.getTime()));
System.out.println(sdf2.format(d4) + "(" + d4.getTime() + "), dst: " + TimeZone.getDefault().inDaylightTime(d4) + ", offset: " + TimeZone.getDefault().getOffset(d4.getTime()));
System.out.println(sdf2.format(d5) + "(" + d5.getTime() + "), dst: " + TimeZone.getDefault().inDaylightTime(d5) + ", offset: " + TimeZone.getDefault().getOffset(d5.getTime()));
System.out.println(sdf2.format(d6) + "(" + d6.getTime() + "), dst: " + TimeZone.getDefault().inDaylightTime(d6) + ", offset: " + TimeZone.getDefault().getOffset(d6.getTime()));
System.out.println(sdf2.format(d7) + "(" + d7.getTime() + "), dst: " + TimeZone.getDefault().inDaylightTime(d7) + ", offset: " + TimeZone.getDefault().getOffset(d7.getTime()));
System.out.println(sdf2.format(d8) + "(" + d8.getTime() + "), dst: " + TimeZone.getDefault().inDaylightTime(d8) + ", offset: " + TimeZone.getDefault().getOffset(d8.getTime()));
System.out.println(sdf2.format(d9) + "(" + d9.getTime() + "), dst: " + TimeZone.getDefault().inDaylightTime(d9) + ", offset: " + TimeZone.getDefault().getOffset(d9.getTime()));
输出
2037-10-17 23:00:00.000 Brasilia Time(2139444000000), dst: false, offset: -10800000
2037-10-17 23:00:00.001 Brasilia Time(2139444000001), dst: false, offset: -10800000
2037-10-17 23:59:59.999 Brasilia Time(2139447599999), dst: false, offset: -10800000
2037-10-18 01:00:00.000 Brasilia Summer Time(2139447600000), dst: true, offset: -7200000
2037-10-18 00:00:00.001 Brasilia Time(2139447600001), dst: true, offset: -10800000
2037-10-18 00:59:59.999 Brasilia Time(2139451199999), dst: true, offset: -10800000
2037-10-18 01:00:00.000 Brasilia Summer Time(2139447600000), dst: true, offset: -7200000
2037-10-18 00:00:00.001 Brasilia Time(2139447600001), dst: true, offset: -10800000
2037-10-18 00:59:59.999 Brasilia Time(2139451199999), dst: true, offset: -10800000
2037-10-18 02:00:00.000 Brasilia Summer Time(2139451200000), dst: true, offset: -7200000
该代码打印出“巴西利亚时间2037-10-18 00:00:000”附近的日期时间,结果表明“巴西利亚时间2037-10-18 00:00:000”应为“ 2037-10-” 18 01:00:00.000巴西利亚夏令时”,表示巴西利亚当时已进入夏令时。
我的问题是,为什么在“ 2037-10-18 00:00:00.001巴西利亚时间”和“ 2037-10-18 00:59:59.999巴西利亚时间”之间,时区偏移仍使用标准时间偏移。这是JDK时区数据的错误还是该时区实际上是以这种方式工作。
我的代码使用offset来确定两个日期之间是否存在dst过渡。显然,“ 2037-10-18 01:00:00.000巴西利亚夏令时”和“ 2037-10-18 00:59:59.999巴西利亚时间”这两个日期在这里不起作用。
我可以更改为使用“ TimeZone.getDefault()。inDaylightTime(Date date)”来确定是否存在过渡,但是我仍然想知道这是否是JDK的错误。
我试图用调试器逐步检查代码,这似乎是时区和开关本身的问题:BRT到BRST在午夜从00:00:00切换到01:00:00,这意味着实际上在这两个小时之间不存在。
从我的调试中,问题似乎GregorianCalendar#computeTime()
尤其在以下几行中:
millis -= zoneOffsets[0] + zoneOffsets[1];
从该行开始millis
的时间是从分析日期算起的自纪元以来的时间,并且该时间与00:00:00
(213946800000)和01:00:00
(2139440400000)不同。在两种情况下zoneOffsets[0]
均为-10800000,这是UTC的原始偏移量。
区别在于zoneOffsets[1]
:为00:00:00
0,但为01:00:00
3600000,即1小时。造成这种情况的原因似乎是内部调用,inDaylightTime( new Date(millis) )
其对00:00:00
(dst前)返回false,但对于01:00:00
(dst的第一个小时)返回true 。因此,最终时间将是相同的,因为您总是添加10800000毫秒,但从较高的值中减去3600000毫秒,即较高的值是3600000毫秒:)
最后,您将获得Date
相同的毫秒时间。
再次格式化日期时,似乎格式化程序将对照时区检查毫秒时间,并且每一次对应于00:00:00,000 - 59:59:59,999
,即在两个时区中都可能被假定为dstOffset
0而不是3600000,因此时区不同被打印。
编辑:比较时01:00:00.000
,01:00:00.001
似乎有一个错误,ZoneInfo.getOffsets(time, offsets, type)
其中前者返回dst偏移量为360000 ,后者返回0,而在格式化程序中填充日历字段时,两者都将假定为dst。
编辑2:更改解析器格式以接受时区快捷方式时,您可以观察到相同的行为,即00:00:00.000 BRT
和01:00:00.000 BRST
被解析为2139447600000并再次格式化为01:00:00.000 BRST
while00:00:00.001 BRT
和01:00:00.001 BRST
被解析为2139447600001并被格式化为00:00:00.001 BRT
-这本身是正确的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句