Как правильно форматировать время между разными часовыми поясами? - PullRequest
0 голосов
/ 30 мая 2018

Я хочу отформатировать время как 19:19:00 в разные часовые пояса.Если я использую SimpleDateFormat, это всегда учитывает начало эпохи: 1970.01.01.

Некоторые часовые пояса имеют разные смещения в начале эпохи и сейчас.Например, по умолчанию смещение от Европы / Киева сейчас составляет UTC + 0200, но в 1970 году это было UTC + 0300.Это означает, что если я запускаю свой сервер в Европе / Киеве, клиент, который будет входить в систему в Европе / Берлине (UTC + 0100), увидит три часа, а не два.

Я могу решить эту проблему, написав специальный форматер дляjava.sql.Time.Но я хочу спросить, может быть, есть какой-то общий подход или инструменты / библиотеки Java, которые могут его решить.

Другое решение может быть с использованием joda-time:

TimeZone.setDefault(TimeZone.getTimeZone("Europe/Kiev"));
DateTimeZone.setDefault(DateTimeZone.forID("Europe/Kiev"));

DateTimeFormat.forPattern("HH:mm:ss.SSS")
   .withZone(DateTimeZone.forID("Europe/Berlin"))
   .print(Time.valueOf("19:00:00").getTime());

Ответы [ 3 ]

0 голосов
/ 30 мая 2018

Вы не можете отформатировать просто время в разных часовых поясах.Вам нужна дата.

Если вы хотите предположить, что датой этого времени является сегодня, вы можете попробовать этот код:

ZoneId originalZone = ZoneId.of("Europe/Kiev");
ZoneId targetZone = ZoneId.of("Europe/Berlin");
LocalTime originalTime = LocalTime.parse("19:19:00");
LocalTime convertedTime = LocalDate.now(originalZone)
                            .atTime(originalTime)
                            .atZone(originalZone)
                            .withZoneSameInstant(targetZone)
                            .toLocalTime();
System.out.println(convertedTime);
0 голосов
/ 30 мая 2018
    ZoneId originalZone = ZoneId.of("Europe/Kiev");
    ZoneId targetZone = ZoneId.of("Europe/Berlin");
    LocalDate assumedDate = LocalDate.now(originalZone);
    String formattedTime = assumedDate.atTime(LocalTime.parse("19:19:00"))
            .atZone(originalZone)
            .withZoneSameInstant(targetZone)
            .format(DateTimeFormatter.ofPattern("HH:mm:ss"));
    System.out.println(formattedTime);

Сегодня напечатано:

18: 19: 00

Когда вы знаете дату, вы, конечно, должны использовать ее вместо сегодняшнего дня.В случае с Киевом и Берлином, я думаю, они следуют одним и тем же правилам для летнего времени (DST), поэтому точная дата может не иметь значения.Если преобразование между зонами, которые не используют одни и те же переходы, или между часовым поясом, который использует летнее время, и тем, которое не использует, это внезапно имеет решающее значение.И кто знает, в какой из этих двух стран политики изменят правила в следующем году?Лучше быть в безопасности.

Ссылка: Учебное пособие по Oracle: Дата и время , объясняющее, как использовать java.time.

0 голосов
/ 30 мая 2018

Является ли java.time.instant альтернативой для вас?Он обрабатывает все метки времени внутренне как время UTC.

Один из способов разобрать его по строке - Instant.parse("2018-05-30T19:00:00")

Если вы хотите иметь время для определенного часового пояса, вы можете получить его с помощьюmyInstant.atZone("Zone")

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...