时区与夏令时 - ZonedDateTime

124 阅读1分钟

ZoneId与夏令时

ZoneId已经包含了是否有夏令时。所以只要指定ZoneId,时间的计算就会自动将夏令时考虑进去。

// Australia/Sydney包含夏令时,会在2025-04-06凌晨3点回调到2点
ZoneId zoneId = ZoneId.of("Australia/Sydney");
ZonedDateTime startDate = LocalDateTime.of(2025, 4, 5, 22, 0, 0).atZone(zoneId);
ZonedDateTime endDate = LocalDateTime.of(2025, 4, 6, 3, 0, 0).atZone(zoneId);
Duration duration = Duration.between(startDate, endDate);
System.out.println("间隔小时数:" + duration.getSeconds() / 3600);
// 间隔小时数:6
// Australia/Brisbane不包含夏令时
ZoneId zoneId = ZoneId.of("Australia/Brisbane");
ZonedDateTime startDate = LocalDateTime.of(2025, 4, 5, 22, 0, 0).atZone(zoneId);
ZonedDateTime endDate = LocalDateTime.of(2025, 4, 6, 3, 0, 0).atZone(zoneId);
Duration duration = Duration.between(startDate, endDate);
System.out.println("间隔小时数:" + duration.getSeconds() / 3600);
// 间隔小时数:5

夏令时结束时,时钟回拨期间数据的表示

Australia/Sydney时区在2025年4月6时凌晨3点时会发生时钟回拨,这一天将会出现两个02:30。

ZoneId zoneId = ZoneId.of("Australia/Sydney");
ZonedDateTime time1 = LocalDateTime.of(2025, 4, 6, 2, 30, 0).atZone(zoneId);
ZonedDateTime time2 = time1.plusHours(1);
System.out.println(time1);
// 2025-04-06T02:30+11:00[Australia/Sydney]
System.out.println(time2);
// 2025-04-06T02:30+10:00[Australia/Sydney]

夏令时规则改变时,JDK的升级方案

方案一: 安装最新JDK 方案二: 使用TZUpdater工具