Java: 本地标准时间到即时

Java: Local Standard Time to Instant

this 这样的服务明确指出

All times are specified in Local Standard Time (LST). Add 1 hour to adjust for Daylight Saving Time where and when it is observed.

给定一个 LocalDateTime 对象 ldt,创建一个瞬间就像 Instant.of(ldt,zoneId)。但是,如果我提供 ZoneId,那么 Instant 将假设已经进行了夏令时 (DST) 调整,而 ldt 是针对 DST 的,但事实并非如此. 使 Instant 的构造函数应用 "standard" 偏移量而不是考虑 DST 的最 Java 方式是什么?

编辑:我的意思是,如果没有硬编码检查给定年份 DST 转换的确切日期?当然,我可以获得偏移量 ZoneOffset offset= ZoneOffset.of(zoneId) 然后从给定的时间戳中减去 offset.getTotalSeconds(),移动到 "reference" 时间。但是仍然将参考调整后的时间戳提供给 Instant 和夏令时一样的问题

编辑:正如下面所建议的,我试过这个:

String str = String.format("%04d-%02d-%02dT%s:00", year, month, day, hourMinutes);
LocalDateTime ldt = LocalDateTime.parse(str);
Instant i1= ldt.toInstant(zoneId.getRules().getOffset(ldt));
Instant key= ldt.toInstant(zoneId.getRules().getStandardOffset(i1));

您可以通过调用 getRules() 然后调用 getStandardOffset().

来获得 ZoneId 的标准偏移量

但是,您需要 Instant。因为有时标准偏移量也会改变...

因此,一种方法是首先使用 LocalDateTime 处的偏移量将 LocalDateTime 转换为 Instant。然后我们得到那一刻的标准偏移量,并用它来得到我们想要的实际 Instant

LocalDateTime ldt = ...;
Instant i = ldt.toInstant(someZoneId.getRules().getOffset(ldt));
Instant i2 = ldt.toInstant(someZoneId.getRules().getStandardOffset(i));
System.out.println(i2);

认为 如果标准偏移量和 DST 偏移量同时发生变化,这对某些特定的当地时间不起作用,因为第一个瞬间 i 是用过渡前的偏移量计算的。您可以通过执行以下操作使用转换后的偏移量计算 i

Instant i;
ZoneOffsetTransition transition = someZoneId.getRules().getTransition(ldt)
if (transition == null) {
    i = ldt.toInstant(someZoneId.getRules().getOffset(ldt));
} else {
    i = ldt.toInstant(transition.getOffsetAfter());
}

更新:

但即便如此,对于某些真正的极端情况,这仍会产生错误的结果。问题是 java.time 没有提供一种在标准偏移量中获取转换的方法。

ZonedDateTime 描述指出:

This class handles conversion from the local time-line of LocalDateTime to the instant time-line of Instant. The difference between the two time-lines is the offset from UTC/Greenwich, represented by a ZoneOffset.

使用区域标识符将 LocalDateTime 对象转换为具有 atZoneZonedDateTime

然后调用继承自ChronoZonedDateTimeclass的默认toInstant方法得到一个Instant对象