java.time.zone.ZoneRules#nextTransition
没有返回1991年欧洲/莫斯科的DST更改,我无法获得1991年欧洲/莫斯科的DST边界。
Europe/Moscow 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在过渡之前发生了意外更改。
最佳答案
您的观察是正确的。
确认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));
打印:
但是,您也正确的是,没有任何方法可以直接查询
ZoneRules
对象有关此更改的发生时间。如果需要这样做,二进制搜索会将其范围缩小到1991-03-30T23:00:00Z,与1991-03-31T02:00:00 + 03:00相同。我在您的问题中确实没有看到明确的问题,也不确定您从一个答案中得到的确切期望。
关联