метка времени страны в местном формате TZD - PullRequest
0 голосов
/ 03 мая 2018

У меня есть отметка времени и страны эпохи. Я хочу преобразовать эту временную метку в указанную местную временную метку страны с регионом часового пояса в формате перехода на летнее время (TZD), как показано ниже

yyyy-mm-ddThh:MM:ssTZD
e.g. 2018-02-25T22:36:23+0100

Timestamp : 1525370235
Country : NLD (ISO alpha-3 code)

Как мне добиться этого на Java?

Обновление 1 :

Я использую этот вид преобразования, но не уверен, что он правильный или неправильный. Может кто-нибудь, дайте мне знать, это основной способ сделать преобразование

Locale locale = new Locale("NLD");
Date date = new Date(1525381190 * 1000L);
    SimpleDateFormat dateFormatCN = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ", locale);

 //Output : 2018-05-03T01:59:50-0700

Ответы [ 2 ]

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

это основной способ сделать преобразование

Нет, это не так. Я вижу следующие проблемы.

  • Все это невозможно, потому что многие страны охватывают несколько часовых поясов. Это означает, что из кода страны вы не можете знать, какой часовой пояс выбрать. Поскольку местное время зависит от часового пояса, в этих случаях вы не можете распечатать правильное время. Страны, которые охватывают более одного часового пояса, включают, но не ограничиваются Канадой, США, Мексикой, Гренландией, Бразилией, Эквадором, Россией, Индонезией, Кирибати - и даже Нидерландами, страной вашего примера. Обратите внимание, что некоторые из стран с наибольшим населением находятся в списке, поэтому, если ваши данные представляют население мира, вы можете чаще сталкиваться с этой проблемой. Пожалуйста, посмотрите этот список: Список часовых поясов по стране .
  • Язык и часовой пояс - две разные вещи, и, тем не менее, обе они более или менее связаны с местами, никак не связанными напрямую. Таким образом, получение правильного языка не поможет вам. Вы также можете видеть, что ваш распечатанный документ имеет смещение UTC -0700, где правильное смещение для Амстердама летом было бы + 0200.
  • new Locale("NLD") не предоставит вам действительный язык для Нидерландов. Аргументом для конструктора Locale(String) является языковой тег, такой как nl для голландского или en для английского. Трехбуквенный код страны не будет работать.
  • Поэтому, если вы хотите выполнить только часть работы, о которой вы спрашиваете, вам потребуется доступ к некоторой базе данных или базам данных, которые могут преобразовывать код страны в страну и страну в часовые пояса. Я не знаю хорошего выбора здесь, но я ожидаю, что некоторые такие базы данных доступны.

java.time

Наконец, не используйте SimpleDateFormat и Date. Эти классы давно устарели и плохо разработаны. Современный правильный способ форматирования значения метки времени для материковой части Нидерландов:

    ZoneId zone = ZoneId.of("Europe/Amsterdam");
    String nldTime = Instant.ofEpochSecond(1_525_370_235L)
            .atZone(zone)
            .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
    System.out.println(nldTime);

Это печатает:

2018-05-03T19: 57: 15 + 02: 00

Если вам нужно смещение без двоеточия, как в +0200, используйте DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXX").

Если вместо Амстердама вы хотели провести время в карибских муниципалитетах Нидерландов, используйте часовой пояс Америка / Кралендейк. Тогда результат будет 2018-05-03T13:57:15-04:00.

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

Нет фактического часового пояса Oracle в формате ISO https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3.

Итак, я хотел бы предложить вам провести сопоставление между зонами ISO и часовыми поясами Oracle https://www.mkyong.com/java/java-display-list-of-timezone-with-gmt/

Итак, мое решение вашего вопроса выглядит так:

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

public class IsoToOracleDate {

static Map<String, String> timezones = new HashMap<String, String>(){{
   put("NLD","Europe/Amsterdam");
   put("RUS","Europe/Moscow");
   put("USA","America/New_York");
}};

public static void main(String[] args) {
    String zone = timezones.get("NLD");
    ZoneId zoneId = ZoneId.of(zone);
    long epochMilli = 1525370235 * 1000L;
    LocalDateTime dt = Instant.ofEpochMilli(epochMilli).atZone(zoneId).toLocalDateTime();
    ZonedDateTime zdt = ZonedDateTime.of(dt, zoneId);
    System.out.println(zdt.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
}
}

Выходы:

2018-05-03T19: 57: 15 + 02: 00

У вас есть отображение часовых поясов в переменной timezones .

Создание ZoneId (оракула) из сопоставления ZoneId zoneId = ZoneId.of (zone);

Создать LocalDateTime dt из epochMilli в соответствии с вашей зоной и преобразовать его в ZonedDateTime zdt .

Затем просто отформатируйте zdt с предопределенным форматом DateTimeFormatter.ISO_OFFSET_DATE_TIME

...