Как преобразовать UTC DateTime в другой часовой пояс, используя библиотеку Java 8? - PullRequest
0 голосов
/ 09 января 2019
final Timestamp rawDateTime = Timestamp.valueOf("2031-04-25 18:30:00");
final ZoneId zoneId = ZoneId.of("Asia/Calcutta");
final ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(
    Instant.ofEpochMilli(rawDateTime.getTime()), zoneId); 
// here we are getting output as 2031-04-25T18:30+05:30[Asia/Calcutta]

final ZonedDateTime zonedDateTime1 = 
ZonedDateTime.of(rawDateTime.toLocalDateTime(), zoneId);
// here we are getting output as 2031-04-25T18:30+05:30[Asia/Calcutta]

Но я хочу получить преобразованное время в виде 2031-04-26 00: 00: 00 + 5: 30, так как моя метка времени находится в часовом поясе UTC.

Пожалуйста, помогите.

Ответы [ 3 ]

0 голосов
/ 09 января 2019

Вместо ZonedDateTime с именованными зонами, имеющими (над-) национальные стандарты, такие как экономия времени, используйте OffsetDateTime.

OffsetDateTime utc = OffsetDateTime.parse("2031-04-25T18:30:00Z");
OffsetDateTime asia = utc.withOffsetSameInstant(ZoneOffset.ofHoursMinutes(5, 30));

Разбор по умолчанию для формата ISO.

  • Z означает ноль, UTC, +0: 00.
  • Результирующее форматирование по умолчанию: 2031-04-26T00:00+05:30.

После комментария Оле В.В.

Вышеуказанное особенно подвержено ошибкам, если используется летнее время, как в центральноевропейском времени с различными смещениями +1: 00 и +2: 00.

Instant raw = Instant.parse("2031-04-25T18:30:00Z");
ZonedDateTime zoned = raw.atZone(ZoneId.of("Asia/Calcutta"));
OffsetDateTime offset = OffsetDateTime.from(zoned);
0 голосов
/ 09 января 2019

Использование DateTimeFormatter для форматирования ZonedDateTime:

    final Timestamp rawDateTime = Timestamp.valueOf("2031-04-25 18:30:00");
    final ZoneId zoneId = ZoneId.of("Asia/Calcutta");
    final ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(
            Instant.ofEpochMilli(rawDateTime.getTime()), zoneId);
    // here we are getting output as 2031-04-25T18:30+05:30[Asia/Calcutta]

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[XXX]");
    System.out.println(formatter.format(zonedDateTime));

    final ZonedDateTime zonedDateTime1 =
            ZonedDateTime.of(rawDateTime.toLocalDateTime(), zoneId);
    // here we are getting output as 2031-04-25T18:30+05:30[Asia/Calcutta]
    System.out.println(formatter.format(zonedDateTime1));

Выход:

2031-04-25 23:00:00+05:30
2031-04-25 18:30:00+05:30

Отредактировано: согласно комментарию @Ole V.V. - Местное время даты должно быть преобразовано в zonedatetime перед применением формата:

 final Timestamp rawDateTime = Timestamp.valueOf("2031-04-25 18:30:00");
        LocalDateTime ldt = rawDateTime.toLocalDateTime();
        final ZoneId zoneId = ZoneId.of("Asia/Calcutta");
        ZonedDateTime zdt = ldt.atZone(ZoneId.of("UTC"))
                .withZoneSameInstant(zoneId);


        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[XXX]");
        System.out.println(formatter.format(zdt));

Это даст вывод:

2031-04-26 00:00:00+5:30
0 голосов
/ 09 января 2019

Во-первых, вы не должны использовать Timestamp. Вы можете использовать DateTimeFormatter для разбора на LocalDateTime.

Затем вы переводите зону LocalDateTime в UTC, а затем переходите в зону Калькутты с помощью ZonedDateTime.withZoneSameInstant.

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .append(DateTimeFormatter.ISO_LOCAL_DATE)
    .appendLiteral(' ')
    .append(DateTimeFormatter.ISO_LOCAL_TIME)
    .toFormatter();

LocalDateTime localDateTime = LocalDateTime.parse("2031-04-25 18:30:00", formatter);
ZoneId calcuttaZone = ZoneId.of("Asia/Calcutta");
ZonedDateTime calcuttaZonedDateTime = localDateTime.atZone(ZoneOffset.UTC)
    .withZoneSameInstant(calcuttaZone);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...