尝试使用 JSR 310 在时区之间转换毫秒日期时间值。需要处理毫秒值,才能使用旧版 API。就我而言,它介于本地和 UTC/GMT 之间,但我希望它是完全相同的代码,而与所涉及的源时区和目标时区无关。这是我的小测试程序。它被配置为在最后一次本地 DST 更改前后的几个小时内进行迭代。输出是错误的,所以我认为 UTCtoLocalMillis 是错误的,但我的测试方法也可能存在问题。我所说的错误输出的意思是,对于我的时区,应该减去小时以获得 UTC,但代码实际上增加了小时。其次,夏令时的时间点也相差一小时。
我首先获取本地时区,然后将其重置为 UTC,这样 Date().toString() 在创建输出时不会执行任何转换。
我想要的是创建一个以毫秒为单位的方法,一个源 ZoneID 和一个目标 ZoneID,并使用新的 JSR 310 API 返回转换后的毫秒数。
public class Test {
static int DAYS_OFFSET_TO_BE_BEFORE_DST_CHANGE = -16;
static TimeZone UTC_TZ = TimeZone.getTimeZone("UTC");
static TimeZone LOCAL_TZ = TimeZone.getDefault();
static ZoneId UTC_ID = ZoneId.of(UTC_TZ.getID());
static ZoneId LOCAL_ZONE_ID = ZoneId.of(LOCAL_TZ.getID());
static long UTCtoLocalMillis(final long utcMillis) {
final Instant instant = Instant.ofEpochMilli(utcMillis);
final ZonedDateTime before
= ZonedDateTime.ofInstant(instant, UTC_ID);
final ZonedDateTime after
= before.withZoneSameLocal(LOCAL_ZONE_ID);
return after.toInstant().toEpochMilli();
}
public static void main(final String[] args) {
TimeZone.setDefault(UTC_TZ);
System.out.println("LOCAL_TZ: " + LOCAL_TZ.getDisplayName());
final Calendar cal = Calendar.getInstance(LOCAL_TZ);
cal.add(Calendar.DATE, DAYS_OFFSET_TO_BE_BEFORE_DST_CHANGE);
final Date start = cal.getTime();
// DST Change: Sunday, 31 March 2013 01:59:59 (local time)
final long oneHour = 3600000L;
for (int i = 0; i < 12; i++) {
final Date date = new Date(start.getTime() + i * oneHour);
System.out.println("UTC: " + date + " toLocal: "
+ new Date(UTCtoLocalMillis(date.getTime())));
}
}
}