Trying to use JSR 310 to convert milliseconds datetime values between timezones. Dealing with milliseconds values is required, to work with legacy APIs. In my case, it's between local and UTC/GMT, but I would expect it to be the exact same code independent of exactly which source and destination timezones are involved. Here is my little test program. It is configured such that it iterates over the hours right around the last local DST change. The output is wrong, and so I assume UTCtoLocalMillis is wrong, but possibly there is also a problem with my test methodology. What I mean by wrong output, is that for my timezone, hours should be substracted to get UTC, but the code actually adds hours. Secondly, the point at which DST hits is also off by one hour.
I first fetch the local timezone, but then reset it to UTC, such that the Date().toString() will not perform any conversion when creating the output.
What I want is to create a method that takes a time in milliseconds, and a source ZoneID, and a target ZoneID, and returns the converted milliseconds, using the new 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())));
}
}
}