robelgado
robelgado

Reputation: 133

Convert date from GMT timezone to local time zone -- using ISO_OFFSET_DATE_TIME

I have a date, assumed to be in GMT, which I want to convert to local time zone using the ISO_OFFSET_DATE_TIME formatting.

Basically, I want to go from:

2018-03-13 03:00:00.0

to:

2018-03-13T00:00:00-09:00

Obviously this would change, depending on your local time zone.

Any ideas on how I could do this?

Upvotes: 0

Views: 1505

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79395

Parse the date-time string into LocalDateTime:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s.S", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse("2018-03-13 03:00:00.0", dtf);

Combine this with UTC offset to create an OffsetDateTime:

OffsetDateTime odtUtc = ldt.atOffset(ZoneOffset.UTC);

Create its copy with offset set as -09:00 while keeping the instant same:

OffsetDateTime odtUtcMinus9 = odtUtc.withOffsetSameInstant(ZoneOffset.of("+09:00"));

Demo:

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s.S", Locale.ENGLISH);
        LocalDateTime ldt = LocalDateTime.parse("2018-03-13 03:00:00.0", dtf);
        System.out.println(ldt); // 2018-03-13T03:00

        OffsetDateTime odtUtc = ldt.atOffset(ZoneOffset.UTC);
        System.out.println(odtUtc); // 2018-03-13T03:00Z

        OffsetDateTime odtUtcMinus9 = odtUtc.withOffsetSameInstant(ZoneOffset.of("+09:00"));
        System.out.println(odtUtcMinus9); // 2018-03-13T12:00+09:00
    }
}

Note that the timezone offset is a fixed thing i.e. it is independent of the DST. If you are looking for an automatic adjustment of timezone offset as per the DST, use ZonedDateTime. The methods are very much similar to what we have used in the last demo.

Demo:

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s.S", Locale.ENGLISH);
        LocalDateTime ldt = LocalDateTime.parse("2018-03-13 03:00:00.0", dtf);
        System.out.println(ldt); // 2018-03-13T03:00

        ZonedDateTime zdtUtc = ldt.atZone(ZoneId.of("Etc/UTC"));
        System.out.println(zdtUtc); // 2018-03-13T03:00Z[Etc/UTC]

        ZonedDateTime zdtAmericaAdak = zdtUtc.withZoneSameInstant(ZoneId.of("America/Adak"));
        System.out.println(zdtAmericaAdak); // 2018-03-12T18:00-09:00[America/Adak]

        // A custom format
        DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSXXX", Locale.ENGLISH);
        String formatted = dtfOutput.format(zdtAmericaAdak);
        System.out.println(formatted); // 2018-03-12 18:00:00.000-09:00
    }
}   

Learn more about java.time, the modern date-time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Upvotes: 1

Lee Marlow
Lee Marlow

Reputation: 143

You can leverage ZonedDateTime for this. You just need to read in the date as UTC and convert it as needed. You might get something like this:

String readPattern = "yyyy-MM-dd HH:mm:ss.S";
DateTimeFormatter readDateTimeFormatter = DateTimeFormatter.ofPattern(readPattern).withZone(ZoneOffset.UTC);
LocalDateTime utcLocalDateTime = LocalDateTime.parse("2018-03-13 03:00:00.0", readDateTimeFormatter);
ZonedDateTime localZonedDateTime = utcLocalDateTime.atOffset(ZoneOffset.UTC).atZoneSameInstant(ZoneId.systemDefault());
String writePattern = "yyyy-MM-dd HH:mm:ssXXX";
DateTimeFormatter writeDateTimeFormatter = DateTimeFormatter.ofPattern(writePattern);
System.out.println(writeDateTimeFormatter.format(localZonedDateTime));

For more info, see:

Upvotes: 2

Related Questions