How to list the timezone offset, timezone ID, and long name in Joda Time / Java 8?

The following approach worked.

import java.util.Set;
import java.util.TimeZone;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

Set<String> zoneIds = DateTimeZone.getAvailableIDs();
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("ZZ");

for (String zoneId : zoneIds) {
    String offset = dateTimeFormatter.withZone(DateTimeZone.forID(zoneId)).print(0);
    String longName = TimeZone.getTimeZone(zoneId).getDisplayName();

    System.out.println("(" + offset + ") " + zoneId + ", " + longName);
}

There could also be other and probably better ways that I'm right now unaware of.


Or

import java.util.Set;
import org.joda.time.DateTimeUtils;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

Set<String> zoneIds = DateTimeZone.getAvailableIDs();
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("ZZ");

for (String zoneId : zoneIds) {
    String offset = dateTimeFormatter.withZone(DateTimeZone.forID(zoneId)).print(0);
    String longName = DateTimeZone.forID(zoneId).getName(DateTimeUtils.currentTimeMillis());

    System.out.println("(" + offset + ") " + zoneId + ", " + longName);
}

For Greenwich Mean Time (Etc/GMT+0, for example), it would display, for example +00:00 instead of displaying GMT+00:00 as in the first case.

If the name is not available for the locale, then this method (public final String getName(long instant)) returns a string in the format [+-]hh:mm.

An appropriate Locale can also be used, if needed using the overloaded method,

public String getName(long instant, Locale locale)

Short names, for example UTC for Coordinated Universal Time can be displayed as follows.

import java.util.Set;
import org.joda.time.DateTimeUtils;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

Set<String> zoneIds = DateTimeZone.getAvailableIDs();
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("ZZ");

for (String zoneId : zoneIds) {
    String offset = dateTimeFormatter.withZone(DateTimeZone.forID(zoneId)).print(0);
    String shortName = DateTimeZone.forID(zoneId).getShortName(DateTimeUtils.currentTimeMillis());

    System.out.println("(" + offset + ") " + zoneId + ", " + shortName);
}

With an appropriate Locale, if needed using the overloaded method,

public String getShortName(long instant, Locale locale)

Update :

Using the Java Time API in Java SE 8 in which this is further simplified.

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

Set<String> zoneIds = ZoneId.getAvailableZoneIds();

for (String zoneId : zoneIds) {
    ZoneId zone = ZoneId.of(zoneId);
    ZonedDateTime zonedDateTime = ZonedDateTime.now(zone);

    ZoneOffset offset = zonedDateTime.getOffset();
    String longName = zone.getDisplayName(TextStyle.FULL, Locale.ENGLISH);

    System.out.println("(" + offset + ") " + zoneId + ", " + longName);
}

The display name has various styles available in java.time.format.TextStyle. For example, abbreviations can be displayed using TextStyle.SHORT.

zone.getDisplayName(TextStyle.FULL, Locale.ENGLISH) will display long names like "India Time". This is however, not a full name unlike Joda Time.

The following will display a full name of the given name like "India Standard Time" (wherever applicable).

DateTimeFormatter pattern = DateTimeFormatter.ofPattern("zzzz");
String longName = pattern.format(ZonedDateTime.now(ZoneId.of(zoneId)));

The following will display a zone-offset of the given zone like GMT+05:30 (note the capitalization of the pattern).

DateTimeFormatter pattern = DateTimeFormatter.ofPattern("ZZZZ");
String longName = pattern.format(ZonedDateTime.now(ZoneId.of(zoneId)));

The following is for displaying abbreviations.

DateTimeFormatter pattern = DateTimeFormatter.ofPattern("zzz");
String longName = pattern.format(ZonedDateTime.now(ZoneId.of(zoneId)));

Capital ZZZ for zone-offset like +0530, +0000.

https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html