Попытка использовать JSR 310 для преобразования значений даты и времени в миллисекундах между часовыми поясами. Для работы с устаревшими API требуется работа со значениями в миллисекундах. В моем случае это между локальным и UTC/GMT, но я ожидаю, что это будет точно такой же код, независимо от того, какие именно часовые пояса источника и назначения задействованы. Вот моя небольшая тестовая программа. Он настроен таким образом, что выполняет итерации в течение нескольких часов непосредственно перед последним локальным изменением летнего времени. Вывод неверный, поэтому я предполагаю, что UTCtoLocalMillis неверен, но, возможно, есть проблема с моей методологией тестирования. Что я имею в виду под неправильным выводом, так это то, что для моего часового пояса часы должны быть вычтены, чтобы получить UTC, но код фактически добавляет часы. Во-вторых, точка перехода на летнее время также смещена на один час.
Сначала я получаю местный часовой пояс, но затем сбрасываю его на UTC, так что Date().toString() не будет выполнять никаких преобразований при создании вывода.
Я хочу создать метод, который принимает время в миллисекундах, исходный ZoneID и целевой ZoneID и возвращает преобразованные миллисекунды, используя новый API JSR 310.
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())));
}
}
}