Nekomajin42
Nekomajin42

Reputation: 692

Java ZonedDateTime does not adjust UTC to local zone

This piece of code:

String dateString = "20210811T021500Z";
String dateFormat = "yyyyMMdd'T'HHmmss'Z'";

System.out.println(LocalDateTime.parse(dateString, dateFormat).toString());
System.out.println(LocalDateTime.parse(dateString, dateFormat).atZone(ZoneId.of("Europe/Budapest")).toString());
System.out.println(ZonedDateTime.of(LocalDateTime.parse(dateString, dateFormat), ZoneId.of("Europe/Budapest")).toString());

Outputs this:

2021-08-11T02:15
2021-08-11T02:15+02:00[Europe/Budapest]
2021-08-11T02:15+02:00[Europe/Budapest]

How can I print the adjusted time? I expect the result to be 2021-08-11T04:15.

Upvotes: 1

Views: 840

Answers (1)

Sweeper
Sweeper

Reputation: 274835

You should not parse your date to a LocalDateTime. A LocalDateTime has no information about timezones, but for your calculation here, you absolutely need to know that the input date is in UTC, in order to compute the time difference from Europe/Budapest.

Parse the date to a ZonedDateTime instead:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX");
ZonedDateTime zdt = ZonedDateTime.parse(dateString, formatter);
// zdt = 2021-08-11T02:15Z

Notice how the Z in the date string is not parsed literally as 'Z', but rather X - the zone offset. If you parsed it literally then there would be no timezone information in your date string.

Then, you can your desired output by calling withZoneSameInstant:

System.out.println(
    zdt.withZoneSameInstant(ZoneId.of("Europe/Budapest"))
); // 2021-08-11T04:15+02:00[Europe/Budapest]

Alternatively, you can give the zone to the formatter:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX")
    .withZone(ZoneId.of("Europe/Budapest"));
ZonedDateTime zdt = ZonedDateTime.parse(dateString, formatter);
System.out.println(zdt);
2021-08-11T04:15+02:00[Europe/Budapest]

Upvotes: 7

Related Questions