Convert time based on timezone using java.time

5.9k views Asked by At

How to change the time based on timezone in LocalDateTime, here i have built a date with Time zone as EST, now i need to find the UTC of the corresponding time. please help me how to solve this

String str = "16Jun2015_153556";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMMyyyy_HHmmss");
formatter.withZone(ZoneId.of("EST5EDT"));
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
2

There are 2 answers

0
Meno Hochschild On BEST ANSWER

This answer might be somehow more structured than the correct answer of Jon Skeet. In my comment above I have also pointed out not to overlook the immutable nature of DateTimeFormatter so please always assign the result of any method prefixed by "with...()" to a variable of same type.

// parsing your string input
// NO!!! timezone is needed in this step because LocalDateTime is just without timezone
String str = "16Jun2015_153556";
DateTimeFormatter formatter = 
    DateTimeFormatter.ofPattern("ddMMMuuuu_HHmmss", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(str, formatter);

System.out.println(ldt); // your input as java.time-object: 2015-06-16T15:35:56

Then you assign your local date-time to the EST-zone. It is safer to use the IANA-notation "America/New_York" than to use the outdated form "EST5EDT" (which is only supporting fixed dst rules without any history of historical raw offsets).

ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/New_York"));

Finally you transform the intermediate global timestamp back to a local date-time at the offset UTC+00 preserving the same physical time:

LocalDateTime utc = zdt.withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
System.out.println(utc); // 2015-06-16T19:35:56
0
Jon Skeet On

You shouldn't think about "changing the time zone" of a LocalDateTime - a LocalDateTime doesn't have a time zone. Instead, you should build a ZonedDateTime from a LocalDateTime and a time zone (ZoneId). First remove the formatter.withZone call, then use:

ZonedId zone = ZoneId.of("EST5EDT"); // Or preferrably "America/New_York"
ZonedDateTime zoned = ZonedDateTime.of(dateTime, zone);

Then you could convert that to an instant, or perhaps use:

ZonedDateTime utc = zoned.withZoneSameInstant(ZoneOffset.UTC);

So for example:

import java.time.*;
import java.time.format.*;

public class Test {
    public static void main(String[] args) {
        String str = "16Jun2015_153556";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMMyyyy_HHmmss");
        ZoneId zone = ZoneId.of("America/New_York");
        LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
        ZonedDateTime zoned = ZonedDateTime.of(dateTime, zone);

        // Both of these print 2015-06-16T19:35:56Z
        System.out.println(zoned.toInstant()); 
        System.out.println(zoned.withZoneSameInstant(ZoneOffset.UTC));
    }
}