Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert any Date time to UTC using ZonedDateTime or Java 8

I am trying to convert date 06-12-2015 02:10:10 PM from default zone to UTC using ZonedDateTime.

LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
ZonedDateTime utc = ZonedDateTime.of(localDateTime, ZoneOffset.UTC);

but utc returns 2015-12-06T14:10:10Z instead of 06-12-2015 09:10:10 AM

How can I convert date from default zone to UTC? The answer given here convert current time to UTC.

like image 531
Bilal Shah Avatar asked Dec 06 '15 09:12

Bilal Shah


2 Answers

You can use ZonedDateTime.ofInstant(Instant, ZoneId) where the second parameter is UTC (the instant knows the local offset). Something like,

String source = "06-12-2015 02:10:10 PM";
String pattern = "MM-dd-yyyy hh:mm:ss a";
DateFormat sdf = new SimpleDateFormat(pattern);
try {
    Date date = sdf.parse(source);
    ZonedDateTime zdt = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("UTC"));
    System.out.println(zdt.format(DateTimeFormatter.ofPattern(pattern)));
} catch (ParseException e) {
    e.printStackTrace();
}

And I get (corresponding to my local zone offset)

06-12-2015 06:10:10 PM
like image 62
Elliott Frisch Avatar answered Oct 03 '22 09:10

Elliott Frisch


06-12-2015 02:10:10 PM in Pakistan = 06-12-2015 09:10:10 AM in UTC

There are many ways to do it.

  1. Parse to LocalDateTime ➡️ Combine it with your timezone to get ZonedDateTime ➡️ Convert to Instant ➡️ Convert to ZonedDateTime using Instant#atZone and UTC timezone.
import java.time.Instant;
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) {
        String strDateTime = "06-12-2015 02:10:10 PM";

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-uuuu hh:mm:ss a", Locale.ENGLISH);

        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);

        // Using ZoneId.of("Asia/Karachi") for the demo. Change it to
        // ZoneId.systemDefault()
        Instant instant = ldt.atZone(ZoneId.of("Asia/Karachi")).toInstant();

        ZonedDateTime zdtUtc = instant.atZone(ZoneId.of("Etc/UTC"));

        System.out.println(zdtUtc.format(dtf)); // 06-12-2015 09:10:10 AM
    }
}
  1. Parse to LocalDateTime ➡️ Combine it with your timezone to get ZonedDateTime ➡️ Convert to Instant ➡️ Convert to ZonedDateTime using ZonedDateTime#ofInstant and UTC timezone.
import java.time.Instant;
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) {
        String strDateTime = "06-12-2015 02:10:10 PM";

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-uuuu hh:mm:ss a", Locale.ENGLISH);

        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);

        // Using ZoneId.of("Asia/Karachi") for the demo. Change it to
        // ZoneId.systemDefault()
        Instant instant = ldt.atZone(ZoneId.of("Asia/Karachi")).toInstant();

        ZonedDateTime zdtUtc = ZonedDateTime.ofInstant(instant, ZoneId.of("Etc/UTC"));

        System.out.println(zdtUtc.format(dtf)); // 06-12-2015 09:10:10 AM
    }
}
  1. Using ZonedDateTime#withZoneSameInstant:
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) {
        String strDateTime = "06-12-2015 02:10:10 PM";

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM-dd-uuuu hh:mm:ss a", Locale.ENGLISH);

        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);

        // Using ZoneId.of("Asia/Karachi") for the demo. Change it to
        // ZoneId.systemDefault()
        ZonedDateTime zdtPak = ldt.atZone(ZoneId.of("Asia/Karachi"));

        ZonedDateTime zdtUtc = zdtPak.withZoneSameInstant(ZoneId.of("Etc/UTC"));

        System.out.println(zdtUtc.format(dtf)); // 06-12-2015 09:10:10 AM
    }
}
  1. Using DateTimeFormatter#withZone and ZonedDateTime#withZoneSameInstant:
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) {
        String strDateTime = "06-12-2015 02:10:10 PM";

        // Using ZoneId.of("Asia/Karachi") for the demo. Change it to
        // ZoneId.systemDefault()
        DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("M-d-u h:m:s a", Locale.ENGLISH)
                                        .withZone(ZoneId.of("Asia/Karachi"));

        ZonedDateTime zdtPak = ZonedDateTime.parse(strDateTime, dtfInput);

        ZonedDateTime zdtUtc = zdtPak.withZoneSameInstant(ZoneId.of("Etc/UTC"));

        DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("MM-dd-uuuu hh:mm:ss a", Locale.ENGLISH);
        System.out.println(zdtUtc.format(dtfOutput)); // 06-12-2015 09:10:10 AM
    }
}

Learn more about 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.

like image 33
Arvind Kumar Avinash Avatar answered Oct 03 '22 07:10

Arvind Kumar Avinash