Как преобразовать DateTime в формате ISO 8601 в другой часовой пояс в Java? - PullRequest
0 голосов
/ 07 июня 2018

Моя текущая дата:
Дата: 2018-06-06T16: 30: 00Z (ISO 8601 в UTC)
ИЛИ
Дата iso: 2018-06-06T11: 30: 00-05: 00 (ISO 8601)
ИЛИ
Дата эпохи: 1528302600000 (метка времени эпохи / Unix)

Я хочу преобразоватьвышеуказанный DateTime для некоторых других часовых поясов (например, GMT + 5: 30).И я не уверен, какой формат времени я получу сверху три.Так может у меня есть универсальный метод, который может преобразовать вышеупомянутый код в другой часовой пояс, возвращающий java.util.Date в Java 8?

Я сделал что-то подобное, но это не сработало

public Date convertDateToLocalTZ(Date iso8601, ZoneId toZoneId) {
    Date dateTime = null;
    if (iso8601 != null && toZoneId != null) {
        Instant instant = iso8601.toInstant();
        LocalDateTime localDateTime = instant.atZone(toZoneId).toLocalDateTime();
        dateTime = Date.from(localDateTime.atZone(toZoneId).toInstant());
        return dateTime;
    }
    return dateTime;
}

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

В Java 8+ вы должны использовать новый API java.time.

Ваше начальное время UTC должно быть смоделировано как мгновенное.Используйте DateTimeFormatter для анализа строки, такой как 2018-06-07T22:21:00Z, если необходимо, или получите текущий Instant с помощью Instant.now.

. Затем вы можете использовать Instant.atZone или Instant.withOffset для преобразования в ZonedDateTime, соответственно.OffsetDateTime с желаемым временным сдвигом.ZonedDateTime помогает вам получить дату / время в заданном регионе / стране, в то время как OffsetDateTime делает чисто числовой сдвиг времени, независимый от местоположения и летнего времени.

0 голосов
/ 07 июня 2018

Поскольку вопрос помечен java-8, используйте java.time API.


ОБНОВЛЕНИЕ : Для версии 4 вопроса, где было добавлено 2018-06-06T11:30:00-05:00.

Для разбора 1528302600000 вы анализируете его в long, а затем используете Instant.ofEpochMilli().

Для разбора формата, подобного 2018-06-06T11:30:00-05:00, выможно использовать OffsetDateTime или ZonedDateTime.Оба могут также анализировать 2018-06-06T16:30:00Z.

Чтобы изменить часовой пояс конкретно на конкретное смещение, например GMT+5:30, используйте ZoneOffset, например, ZoneOffset.of("+05:30")или ZoneId, например ZoneId.of("GMT+05:30").
Примечание 1: GMT+5:30 недопустимо.
Примечание 2: Чтобы перейти на часовой пояс региона с учетом перехода на летнее время, используйте, например, ZoneId.of("Asia/Kolkata").

Чтобы проанализировать все 3 формата ввода и даже поддерживать расширенный формат, например 2018-06-06T11:30-05:00[America/Chicago], используйтеZonedDateTime, со специальной обработкой для номера эпохи.

public static ZonedDateTime parseToZone(String text, ZoneId zone) {
    if (text.indexOf('-') == -1)
        return Instant.ofEpochMilli(Long.parseLong(text)).atZone(zone);
    return ZonedDateTime.parse(text).withZoneSameInstant(zone);
}

Затем вызывающий абонент может решить, следует ли использовать только смещение, а не полный часовой пояс, преобразовав его в OffsetDateTime, используя toOffsetDateTime().

Тест

ZoneId india = ZoneId.of("Asia/Kolkata");

System.out.println(parseToZone("2018-06-06T16:30:00Z", india));
System.out.println(parseToZone("2018-06-06T11:30:00-05:00", india));
System.out.println(parseToZone("1528302600000", india));

System.out.println(parseToZone("1528302600000", india).toOffsetDateTime());

Выход

2018-06-06T22:00+05:30[Asia/Kolkata]
2018-06-06T22:00+05:30[Asia/Kolkata]
2018-06-06T22:00+05:30[Asia/Kolkata]
2018-06-06T22:00+05:30

Оригинальный ответ

Используйте метод parse() с 2018-06-06T16:30:00Z.
Используйте метод ofEpochMilli() с 1528302600000.
Затем используйте atZone() для конвертации в нужный часовой пояс.

Демо

Instant instant1 = Instant.parse("2018-06-06T16:30:00Z");
Instant instant2 = Instant.ofEpochMilli(1528302600000L);

ZoneId india = ZoneId.of("Asia/Kolkata");
ZonedDateTime date1 = instant1.atZone(india);
ZonedDateTime date2 = instant2.atZone(india);

System.out.println(instant1);
System.out.println(instant2);
System.out.println(date1);
System.out.println(date2);

Вывод

2018-06-06T16:30:00Z
2018-06-06T16:30:00Z
2018-06-06T22:00+05:30[Asia/Kolkata]
2018-06-06T22:00+05:30[Asia/Kolkata]

Чтобы напечатать результат в человеческом формате, используйте DateTimeFormatter.

DateTimeFormatter indiaFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
                                                    .withLocale(Locale.forLanguageTag("en-IN"));
DateTimeFormatter hindiFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
                                                    .withLocale(Locale.forLanguageTag("hi-IN"));
System.out.println(date1.format(indiaFormatter));
System.out.println(date1.format(hindiFormatter));

Выход

6 June 2018 at 10:00:00 PM IST
6 जून 2018 को 10:00:00 अपराह्न IST
...