How do I convert datetime between time zones?

The ZonedDateTime class is part of the Java Date-Time Package (java.time.*), released in Java 8 to address the shortcomings of the old date-time classes such as java.util.Date, java.util.Calendar, and java.util.SimpleDateFormat.

Some of the key features are:

  • It represents a date-time with a timezone in the ISO-8601 calendar system, such as ‘2007-12-03T10:15:30+01:00 Europe/Paris’.
  • It provides a lot of methods to play with year, month, day, hour, minute, second and nanosecond fields of the datetime.
  • It’s an immutable class, which is good for multithreaded environments.
  • It provides a fluent interface, which allows method calls to be chained.

Using Java java.time package (which is part of Java 8 and later), you can convert dates between time zones like this:

package org.kodejava.datetime;

import java.time.*;

public class ZonedDateTimeExample {
    public static void main(String[] args) {

        // Create a ZonedDateTime instance for the current date/time
        // in the current timezone
        ZonedDateTime now = ZonedDateTime.now();

        // Create a ZonedDateTime instance for the current date/time
        // in a different timezone
        ZonedDateTime nowInJakarta = now.withZoneSameInstant(ZoneId.of("Asia/Jakarta"));

        // Print the current date/time in the current timezone
        System.out.println("Current date/time: " + now);

        // Print the current date/time in the different timezone
        System.out.println("Current date/time in Jakarta: " + nowInJakarta);
    }
}

Output:

Current date/time: 2024-01-20T21:33:31.236022700+08:00[Asia/Makassar]
Current date/time in Jakarta: 2024-01-20T20:33:31.236022700+07:00[Asia/Jakarta]

The withZoneSameInstant method is used to adjust the date and time based on the timezone. It can be used to convert a datetime value to the datetime in another timezone.

This program will create a ZonedDateTime object representing the current date and time, and then create another ZonedDateTime object that represents the current date and time in Jakarta. Finally, it will print both dates to the console.

How do I convert java.util.TimeZone to java.time.ZoneId?

The following code snippet will show you how to convert the old java.util.TimeZone to java.time.ZoneId introduced in Java 8. In the first line of our main() method we get the default timezone using the TimeZone.getDefault() and convert it to ZoneId by calling the toZoneId() method. In the second example we create the TimeZone object by calling the getTimeZone() and pass the string of timezone id. To convert it to ZoneId we call the toZoneId() method.

package org.kodejava.datetime;

import java.time.ZoneId;
import java.util.TimeZone;

public class TimeZoneToZoneId {
    public static void main(String[] args) {
        ZoneId zoneId = TimeZone.getDefault().toZoneId();
        System.out.println("zoneId = " + zoneId);

        TimeZone timeZoneUsPacific = TimeZone.getTimeZone("US/Pacific");
        ZoneId zoneIdUsPacific = timeZoneUsPacific.toZoneId();
        System.out.println("zoneIdUsPacific = " + zoneIdUsPacific);
    }
}

This snippet prints the following output:

zoneId = Asia/Shanghai
zoneIdUsPacific = US/Pacific

To convert the other way around you can do it like the following code snippet. Below we convert the ZoneId to TimeZone by using the TimeZone.getTimeZone() method and pass the ZoneId.systemDefault() which return the system default timezone. Or we can create ZoneId using the ZoneId.of() method and specify the timezone id and then pass it to the getTimeZone() method of the TimeZone class.

package org.kodejava.datetime;

import java.time.ZoneId;
import java.util.TimeZone;

public class ZoneIdToTimeZone {
    public static void main(String[] args) {
        TimeZone timeZone = TimeZone.getTimeZone(ZoneId.systemDefault());
        System.out.println("timeZone = " + timeZone.getDisplayName());

        TimeZone timeZoneUsPacific = TimeZone.getTimeZone(ZoneId.of("US/Pacific"));
        System.out.println("timeZoneUsPacific = " + timeZoneUsPacific.getDisplayName());
    }
}

And here are the output of the code snippet above:

timeZone = China Standard Time
timeZoneUsPacific = Pacific Standard Time

How do I get a list of all TimeZones Ids using Java 8?

To retrieve a list of all available time zones ids we can call the java.time.ZoneId static method getAvailableZoneIds(). This method return a Set of string of all zone ids. The format of the zone id are “{area}/{city}”. You can use these ids of string to create the ZoneId object using the ZoneId.of() static method.

package org.kodejava.datetime;

import java.time.ZoneId;
import java.time.format.TextStyle;
import java.util.Locale;
import java.util.Set;

public class GetAllTimeZoneIds {
    public static void main(String[] args) {
        Set<String> zoneIds = ZoneId.getAvailableZoneIds();
        for (String id : zoneIds) {
            ZoneId zoneId = ZoneId.of(id);
            System.out.println("id          = " + id);
            System.out.println("displayName = " +
                    zoneId.getDisplayName(TextStyle.FULL, Locale.US));
        }
    }
}

Here are some zone IDs printed out to the console:

id          = Asia/Aden
displayName = Arabian Time
id          = America/Cuiaba
displayName = Amazon Time
id          = Etc/GMT+9
displayName = GMT-9:00
id          = Etc/GMT+8
displayName = GMT-8:00
id          = Africa/Nairobi
displayName = Eastern Africa Time
...
...
...
id          = Europe/Nicosia
displayName = Eastern European Time
id          = Pacific/Guadalcanal
displayName = Solomon Is. Time
id          = Europe/Athens
displayName = Eastern European Time
id          = US/Pacific
displayName = Pacific Time
id          = Europe/Monaco
displayName = Central European Time

How do I convert string to Date in GMT timezone?

The following code snippet convert a string representation of a date into a java.util.Date object and the timezone is set to GMT. To parse the string so that the result is in GMT you must set the TimeZone of the DateFormat object into GMT.

package org.kodejava.joda;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class WithTimezoneStringToDate {
    public static void main(String[] args) {
        // Create a DateFormat and set the timezone to GMT.
        DateFormat df = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z");
        df.setTimeZone(TimeZone.getTimeZone("GMT"));

        try {
            // Convert string into Date
            Date today = df.parse("Fri, 29 Oct 2021 00:00:00 GMT+08:00");
            System.out.println("Today = " + df.format(today));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

The code snippet above print the following output:

Today = Thu, 28 Oct 2021 16:00:00 GMT