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相同。

我在您的问题中确实没有看到明确的问题,也不确定您从一个答案中得到的确切期望。

关联
  • Time Changes in Moscow Over the Years在timeanddate.com上
  • 09-20 04:02