夏令时 - Java
Daylight Saving Time - Java
我有以下时区 "2021-06-06T06:00+01:00[Europe/London]"
当我在那个时区调用 toInstant()
时,我得到“2021-06-06T05:00”。时钟向前走,为什么它会在早上 5 点返回?我想早上 7 点而不是早上 5 点。
最小可重现示例:
ZonedDateTime zoned = ZonedDateTime.of(
2021, 6, 6, 6, 0, 0, 0, ZoneId.of("Europe/London"));
System.out.println(zoned);
System.out.println(zoned.toInstant());
预期输出:2021-06-06T07:00
观察到的输出:
2021-06-06T06:00+01:00[Europe/London]
2021-06-06T05:00:00Z
2021-06-06T06:00+01:00 =
2021-06-06T05:00+00:00
这就是时区偏移量的定义方式,例如检查 Wikipedia。
+01:00
的时区指示符表示给定时间在 UTC 前 1 小时的时区,这意味着 UTC 中的同一时间是给定时间减 1 小时。
因此 2021-06-06T06:00+01:00
与 2021-06-06T05:00+00:00
是同一时刻,如果没有夏令时,当天会早 1 小时。
ZonedDateTime
.parse( "2021-06-06T06:00+01:00[Europe/London]" )
.toInstant()
.toString()
看到这个code run live at IdeOne.com。
2021-06-06T05:00:00Z
代码 1
ZoneId tzLondon = ZoneId.of("Europe/London");
ZonedDateTime zonedDateTime = ZonedDateTime.of(2021, 6, 6, 6, 0, 0, 0, tzLondon);
Instant instant = zonedDateTime.toInstant();
System.out.println(" zoned: " + zonedDateTime);
System.out.println("instant: " + instant);
输出 1
zoned: 2021-06-06T06:00+01:00[Europe/London]
instant: 2021-06-06T05:00:00Z
分区输出是基于时区Europe/London,在夏令时(DST)期间是GMT+1,这就是为什么它似乎在即时输出后1小时( 05:00 + 1 小时 = 06:00)。但是两个输出代表相同的时间点,只是格式不同。
通常在 Java 中,您不会直接处理 DST 计算,因为 Java 会为您完成。当您从上面获取 ZonedDateTime 并添加几个月时,您可以看到这一点。
代码 2
ZonedDateTime zonedDateTimeAFewMonthsLater = zonedDateTime.plusMonths(5);
Instant instantAFewMonthsLater = zonedDateTimeAFewMonthsLater.toInstant();
System.out.println("A few months later (zoned): " + zonedDateTimeAFewMonthsLater);
System.out.println("A few months later (instant): " + instantAFewMonthsLater);
输出 2
A few months later (zoned): 2021-11-06T06:00Z[Europe/London]
A few months later (instant): 2021-11-06T06:00:00Z
但是,如果您真的很想将 ZonedDateTime
从 06:00 修补到 07:00,这取决于它的 DST 属性,您可以这样做。但是很脏。
代码 3
Duration dstDuration = zonedDateTime.getZone().getRules().getDaylightSavings(instant);
ZonedDateTime dstPatchedZonedDateTime = zonedDateTime.plus(dstDuration);
System.out.println("DST patched: " + dstPatchedZonedDateTime);
输出 3
DST patched: 2021-06-06T07:00+01:00[Europe/London]
我有以下时区 "2021-06-06T06:00+01:00[Europe/London]"
当我在那个时区调用 toInstant()
时,我得到“2021-06-06T05:00”。时钟向前走,为什么它会在早上 5 点返回?我想早上 7 点而不是早上 5 点。
最小可重现示例:
ZonedDateTime zoned = ZonedDateTime.of(
2021, 6, 6, 6, 0, 0, 0, ZoneId.of("Europe/London"));
System.out.println(zoned);
System.out.println(zoned.toInstant());
预期输出:2021-06-06T07:00
观察到的输出:
2021-06-06T06:00+01:00[Europe/London] 2021-06-06T05:00:00Z
2021-06-06T06:00+01:00 =
2021-06-06T05:00+00:00
这就是时区偏移量的定义方式,例如检查 Wikipedia。
+01:00
的时区指示符表示给定时间在 UTC 前 1 小时的时区,这意味着 UTC 中的同一时间是给定时间减 1 小时。
因此 2021-06-06T06:00+01:00
与 2021-06-06T05:00+00:00
是同一时刻,如果没有夏令时,当天会早 1 小时。
ZonedDateTime
.parse( "2021-06-06T06:00+01:00[Europe/London]" )
.toInstant()
.toString()
看到这个code run live at IdeOne.com。
2021-06-06T05:00:00Z
代码 1
ZoneId tzLondon = ZoneId.of("Europe/London");
ZonedDateTime zonedDateTime = ZonedDateTime.of(2021, 6, 6, 6, 0, 0, 0, tzLondon);
Instant instant = zonedDateTime.toInstant();
System.out.println(" zoned: " + zonedDateTime);
System.out.println("instant: " + instant);
输出 1
zoned: 2021-06-06T06:00+01:00[Europe/London]
instant: 2021-06-06T05:00:00Z
分区输出是基于时区Europe/London,在夏令时(DST)期间是GMT+1,这就是为什么它似乎在即时输出后1小时( 05:00 + 1 小时 = 06:00)。但是两个输出代表相同的时间点,只是格式不同。
通常在 Java 中,您不会直接处理 DST 计算,因为 Java 会为您完成。当您从上面获取 ZonedDateTime 并添加几个月时,您可以看到这一点。
代码 2
ZonedDateTime zonedDateTimeAFewMonthsLater = zonedDateTime.plusMonths(5);
Instant instantAFewMonthsLater = zonedDateTimeAFewMonthsLater.toInstant();
System.out.println("A few months later (zoned): " + zonedDateTimeAFewMonthsLater);
System.out.println("A few months later (instant): " + instantAFewMonthsLater);
输出 2
A few months later (zoned): 2021-11-06T06:00Z[Europe/London]
A few months later (instant): 2021-11-06T06:00:00Z
但是,如果您真的很想将 ZonedDateTime
从 06:00 修补到 07:00,这取决于它的 DST 属性,您可以这样做。但是很脏。
代码 3
Duration dstDuration = zonedDateTime.getZone().getRules().getDaylightSavings(instant);
ZonedDateTime dstPatchedZonedDateTime = zonedDateTime.plus(dstDuration);
System.out.println("DST patched: " + dstPatchedZonedDateTime);
输出 3
DST patched: 2021-06-06T07:00+01:00[Europe/London]