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
对象转换为具有 atZone
的 ZonedDateTime
。
然后调用继承自ChronoZonedDateTime
class的默认toInstant
方法得到一个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
对象转换为具有 atZone
的 ZonedDateTime
。
然后调用继承自ChronoZonedDateTime
class的默认toInstant
方法得到一个Instant
对象