java.time.zone.ZoneRules#nextTransition
未返回欧洲/莫斯科1991年的夏令时更改,我无法获得欧洲/莫斯科1991年的夏令时边界。
欧洲/莫斯科entered daylight saving on 1991-03-31 02:00 but also changed their standard offset,因此偏移量(+03:00)保持不变,而没有Java API可用于获取DST开始的边界。
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.zone.ZoneOffsetTransition;
public class TimeUtilTest {
public static void main(String[] args) {
ZoneId tz = ZoneId.of("Europe/Moscow");
ZonedDateTime yearBegin = ZonedDateTime.of(1991, 1, 1, 0, 0, 0, 0, tz);
ZoneOffsetTransition nextTransition = tz.getRules().nextTransition(yearBegin.toInstant());
System.out.println("year begin isDST=" + tz.getRules().isDaylightSavings(yearBegin.toInstant()));
System.out.println("next transition before is " + nextTransition.getDateTimeBefore() + " isDST=" + tz.getRules()
.isDaylightSavings(nextTransition.getInstant().minusNanos(1)));
System.out.println("next transition after is " + nextTransition.getDateTimeAfter() + " isDST=" + tz.getRules()
.isDaylightSavings(nextTransition.getInstant().plusNanos(1)));
}
}
它在下面返回
year begin isDST=false
next transition before is 1991-09-29T03:00 isDST=true
next transition after is 1991-09-29T02:00 isDST=false
您可以在其中看到isDST在过渡之前发生了意外更改。
答案 0 :(得分:2)
您的观察是正确的。
确认1991年3月更改的一种方法是:在timeanddate.com的“时区和时钟更改”页面上(请参阅底部的链接),从下拉列表中选择1990-1999。我引用:
Year Date & Time Abbreviation Time Change Offset After
1991 søn 31. mar, kl. 02.00 MSK → EEST No offset (DST start, TZ change) UTC+3h
Java区域规则以过渡(间隙(时钟指针朝前)或重叠(时钟向后))建模。由于1991年3月在莫斯科均未发生过,区划规则无法真正模拟过渡,因此显然已选择将其忽略。也许我们可能想象彼此之间存在间隙和重叠并相互平衡,但是我也不认为这会起作用。
Java确实知道有关更改。尝试例如
ZoneRules moscowRules = tz.getRules();
Instant justBeforeChange = ZonedDateTime.of(1991, 3, 31, 1, 59, 59, 999_999_999, tz).toInstant();
System.out.println(moscowRules.getStandardOffset(justBeforeChange));
System.out.println(moscowRules.isDaylightSavings(justBeforeChange));
Instant onChange = ZonedDateTime.of(1991, 3, 31, 2, 0, 0, 0, tz).toInstant();
System.out.println(moscowRules.getStandardOffset(onChange));
System.out.println(moscowRules.isDaylightSavings(onChange));
此打印:
+03:00 false +02:00 true
不过,您也很正确,无法直接查询ZoneRules
对象有关此更改何时发生的信息。如果需要这样做,二进制搜索会将其范围缩小到1991-03-30T23:00:00Z,与1991-03-31T02:00:00 + 03:00相同。
在您的问题中,我没有真正看到清晰的问题,也不确定您从答案中得出的确切结果。