How to convert UTC DateTime to another Time Zone using Java 8 library?

六眼飞鱼酱① 提交于 2020-02-05 09:23:19

问题


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]

But I want to get the converted date time as 2031-04-26 00:00:00+5:30 as my timestamp value is in the UTC Timezone.

Please help.


回答1:


First, you should not use Timestamp. You can use DateTimeFormatter to parse into a LocalDateTime.

You then zone that LocalDateTime to UTC before converting to the Calcutta zone with 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);



回答2:


Instead of ZonedDateTime with named zones having (supra-)national standards like day-time-savings, use OffsetDateTime.

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

The default parsing is for the ISO format.

  • Z means zero, UTC, +0:00.
  • The resulting default formatting is 2031-04-26T00:00+05:30.

After comment of Ole V.V.

The above is especially error prone if summer time is involved, like in Central European Time with varying offsets +1:00 and +2:00.

Instant raw = Instant.parse("2031-04-25T18:30:00Z");
ZonedDateTime zoned = raw.atZone(ZoneId.of("Asia/Calcutta"));
OffsetDateTime offset = OffsetDateTime.from(zoned);



回答3:


Using DateTimeFormatter to format 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));

The output:

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

Edited: according to the comment from @Ole V.V. - The local date time has to be converted to the zonedatetime , before applying the format :

 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));

This will give the output:

2031-04-26 00:00:00+5:30


来源:https://stackoverflow.com/questions/54108388/how-to-convert-utc-datetime-to-another-time-zone-using-java-8-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!