假夏令时过渡

Fake Daylight Saving transition

有没有办法在 Joda-Time 中配置夏令时转换时间?

例如,加利福尼亚州的 spring 过渡将于 3 月 11 日 2:00 上午开始。

我想配置 Joda-Time(我的应用程序正在使用),以便在特定时间开始转换(例如 2/21 下午 4 点),这样我就可以在我的应用程序中测试一些逻辑,具体取决于当前时间的夏令时。

您可以扩展 org.joda.time.DateTimeZone:

public class FakeTimeZone extends DateTimeZone {

    private DateTime dstStart;

    private DateTimeZone zone;

    protected FakeTimeZone(String id) {
        super(id);
        this.zone = DateTimeZone.forID(id);
        // DST starts at 21/Feb/2018, at 4 PM 
        this.dstStart = new DateTime(2018, 2, 21, 16, 0, 0, 0, zone);
    }

    @Override
    public String getNameKey(long instant) {
        return this.getID();
    }

    @Override
    public int getOffset(long instant) {
        // check if it's in DST
        if (dstStart.getMillis() <= instant) {
            // DST, offset is 1 hour ahead the standard - value must be in milliseconds
            return this.zone.getStandardOffset(instant) + 3600000;
        }
        return this.zone.getStandardOffset(instant);
    }

    @Override
    public int getStandardOffset(long instant) {
        return this.zone.getStandardOffset(instant);
    }

    @Override
    public boolean isFixed() {
        return false;
    }

    @Override
    public long nextTransition(long instant) {
        if (instant < dstStart.getMillis()) {
            return dstStart.getMillis();
        }
        return instant;
    }

    @Override
    public long previousTransition(long instant) {
        if (instant > dstStart.getMillis()) {
            return dstStart.getMillis();
        }
        return instant;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof FakeTimeZone) {
            return getID().equals(((FakeTimeZone) obj).getID());
        }
        return false;
    }
}

它使用与您在构造函数中传递的时区相同的偏移量,唯一的区别是 DST 转换 - 在这种情况下,我只使用一个并忽略其余部分 - 但你可以更改上面的代码和制定更复杂的逻辑来考虑所有其他转换 + 您的自定义转换。

那你就这样用吧:

// 1 hour before DST starts
DateTime d = new DateTime(2018, 2, 21, 15, 0, 0, 0, new FakeTimeZone("America/Los_Angeles"));

// This prints 2018-02-21T15:00:00.000-08:00 (standard offset)
System.out.println(d);

// 1 hour later, DST is in effect, it prints 2018-02-21T17:00:00.000-07:00
System.out.println(d.plusHours(1));

请注意,第一个日期是下午 3 点(DST 开始前一小时),因此偏移量是标准的 (-08:00)。

然后,1 小时后,原本应该是下午 4 点,但由于夏令时开始,它被转移到下午 5 点,偏移量变为 -07:00