从java.util.TimeZone转换为org.joda.DateTimeZone

时间:2017-04-06 21:40:35

标签: java date timezone jodatime dst

如何在Java中将java.util.TimeZone的实例转换为org.joda.DateTimeZone并保持夏令时?

2 个答案:

答案 0 :(得分:3)

Joda-维护模式时间

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

java.time.ZoneId

java.util.TimeZone的现代替代品是java.time.ZoneId& java.time.ZoneOffset

您应该避免旧的旧日期时间类。但是如果有必要,您可以转换为java.time类型。查看添加到旧类的新方法。您可以在TimeZoneZoneId之间移动。

java.util.TimeZone tz = java.util.TimeZone.getTimeZone( myZoneId );

...和...

java.time.ZoneId z = myLegacyTimeZone.toZoneId();

如果您正在寻找区域的UTC偏移或夏令时(DST)信息,请查看ZoneRules类。搜索Stack Overflow以获取更多有关该问题的讨论和示例,或编辑您的问题以描述有关您的目标的更多信息。

答案 1 :(得分:0)

当你调用DateTimeZone.forTimeZone时,它使用时区ID,Joda使用自己的DST规则创建等效对象 - 它不会从TimeZone对象导入规则。

另一个细节是您正在使用" GMT",这是一个没有DST规则的区域(只需检查DateTimeZone.forID("GMT").isFixed()的值 - 它会返回true,这意味着区域是固定的,AKA没有偏移变化,AKA没有DST)。

您似乎想要一个符合伦敦DST规则的区域(基于您选择DST开始和结束的日期)。如果是这种情况,您可以使用DateTimeZone.forID("Europe/London")创建区域。

但是,如果要创建具有特定DST规则的自定义区域,则必须通过扩展DateTimeZone类来手动执行此操作。 DST区域的一个示例,从2013年3月27日开始,到2013年10月31日结束,均在午夜(您可以根据需要更改值)。

public class CustomTimeZone extends DateTimeZone {

    private DateTime dstStart;

    private DateTime dstEnd;

    protected CustomTimeZone(String id) {
        super(id);
        // DST starts at 27/Mar/2013 and ends at 31/Oct/2013
        this.dstStart = new DateTime(2013, 3, 27, 0, 0, 0, 0, DateTimeZone.UTC);
        this.dstEnd = new DateTime(2013, 10, 30, 23, 0, 0, 0, DateTimeZone.UTC);
    }

    @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 && instant < dstEnd.getMillis()) {
            // DST, offset is 1 hour ahead of UTC - value must be in milliseconds
            return 3600000;
        }
        return 0;
    }

    @Override
    public int getStandardOffset(long instant) {
        // assuming stardard offset is zero (same as UTC)
        return 0;
    }

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

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

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

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

测试此区域:

CustomTimeZone customZone = new CustomTimeZone("Custom");
// date in DST (between March and October)
DateTime d = new DateTime(2013, 4, 20, 0, 0, 0, 0, customZone);
System.out.println(d); // 2013-04-20T00:00:00.000+01:00

// one minute before DST starts - offset is zero ("Z")
d = new DateTime(2013, 3, 26, 23, 59, 0, 0, customZone);
System.out.println(d); // 2013-03-26T23:59:00.000Z
// add 1 minute - DST starts and offset changes to +01:00 (clock moves 1 hour forward to 1 AM)
System.out.println(d.plusMinutes(1)); // 2013-03-27T01:00:00.000+01:00

// one minute before DST ends - offset is +01:00
d = new DateTime(1383173940000L, customZone);
System.out.println(d); // 2013-10-30T23:59:00.000+01:00
// add 1 minute - DST starts and offset changes to zero ("Z") (clock moves 1 hour back to 23 PM)
System.out.println(d.plusMinutes(1)); // 2013-10-30T23:00:00.000Z

我只创建了一个只有一个DST过渡的简单案例,但您可以根据需要使该类变得复杂,存储您需要的所有DST更改并调整开始和结束日期(以及偏移量为因此。