假夏令时过渡
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。
有没有办法在 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。