如何在Java中指定夏令时转换后的时间



使用以下代码:

class Test {
public static void main(String [] args) {
LocalDate date = LocalDate.of(2018, 11, 4);
LocalTime time = LocalTime.of(1, 59);
ZonedDateTime dt = ZonedDateTime.of(date, time, ZoneId.of("America/New_York"));
System.out.println(dt.getHour() + ":" + dt.getMinute() + ":" + dt.getSecond());
dt = dt.plusMinutes(1);
System.out.println(dt.getHour() + ":" + dt.getMinute() + ":" + dt.getSecond());
dt = dt.plusMinutes(59);
System.out.println(dt.getHour() + ":" + dt.getMinute() + ":" + dt.getSecond());
dt = dt.plusMinutes(1);
System.out.println(dt.getHour() + ":" + dt.getMinute() + ":" + dt.getSecond());
}
}

我得到

1:59:0
1:0:0
1:59:0
2:0:0

有没有办法从夏令时之后到达1:00,而不经过夏令时之前的1:00?

使用ofStrict指定所生成的分区日期时间的偏移量。America/New_York在相关时间前后从-04:00更改为-05:00,因此您需要ZoneOffset.ofHours(-5)

ZonedDateTime dt = ZonedDateTime.ofStrict(
LocalDateTime.of(date, time), 
ZoneOffset.ofHours(-5), 
ZoneId.of("America/New_York")
);

如果您无法在中硬编码偏移量,您可以在使用后获得偏移量

var dateTime = LocalDateTime.of(date, time)
var zone = ZoneId.of("America/New_York");
var offsetAfter = zone.getRules()
.getTransition(dateTime)
.getOffsetAfter();
ZonedDateTime dt = ZonedDateTime.ofStrict(
dateTime, 
offsetAfter, 
zone
);

或者,正如Ole V.V.所指出的,你也可以使用更短的:

ZonedDateTime dt = ZonedDateTime.of(
date, time, ZoneId.of("America/New_York")
).withLaterOffsetAtOverlap();

遵守夏令时的时区的问题是这些时间不明确。";America/New_York";区域有两个时间,都标记为2008-11-04T01:00。从技术上讲,其中一个是美国东部时间01:00,另一个是东部时间01:00EST,但并不是很多软件都能让你这样区分,尤其是因为这样的三个字母时区名称不一定是全球唯一的。

解决方案是指定不具有夏令时的环球时间或相对于环球时间的时间:第一个东部时间01:00为05:00Z,第二个为06:00Z。所以你可以把时间作为其中之一,把区域作为";UTC";(然后将结果转换为"America/New_York"(,或者使用ofStrict指定从UTC的偏移量

最新更新