Question

Time zone ids of Joda Time can simply be displayed with the following segment of code.

Set<String> zoneIds = DateTimeZone.getAvailableIDs();

for(String zoneId:zoneIds) {
    System.out.println(zoneId);
}

But how to display the corresponding timezone offset, timezone ID, and long name so that the list could look something like the following?

(GMT-10:00) Pacific/Honolulu, Hawaii Standard Time
(GMT-10:00) Pacific/Johnston, Hawaii Standard Time
(GMT-10:00) Pacific/Fakaofo, Tokelau Time
(GMT-10:00) HST, Hawaii Standard Time

They are needed to list in a drop-down-box for selection.


The following snippet shows the names but the offset it displays looks wonky.

Set<String> zoneIds = DateTimeZone.getAvailableIDs();

for (String zoneId : zoneIds) {
    int offset = DateTimeZone.forID(zoneId).getOffset(new DateTime());
    String longName = TimeZone.getTimeZone(zoneId).getDisplayName();

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

Out of the long list it displays, a few of them are shown like,

(-36000000) Pacific/Honolulu, Hawaii Standard Time
(-36000000) Pacific/Johnston, Hawaii Standard Time
(-36000000) Pacific/Fakaofo, Tokelau Time
(-36000000) HST, Hawaii Standard Time

The offset should be as shown in this list.

Was it helpful?

Solution

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

OTHER TIPS

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.time.zone.ZoneRules;
import java.util.Locale;
import java.util.TimeZone;

// Europe/Berlin
// Europe/London
// Asia/Kolkata
public class TimeZoneTest {

    public static void main(String[] args) {

        ZonedDateTime timeZone = ZonedDateTime.of(LocalDateTime.of(2020, 8, 06, 05, 45),
                                                   ZoneId.of("Asia/Manila"));

        Instant instant = timeZone.toInstant();
        ZoneRules rules = timeZone.getZone().getRules();
        boolean isDst = rules.isDaylightSavings(instant);
        String dstShortName = DateTimeFormatter.ofPattern("zzz").format(timeZone);
        String dstLongName = DateTimeFormatter.ofPattern("zzzz").format(timeZone);
        TimeZone tz = TimeZone.getTimeZone(timeZone.getZone());

        System.out.println(timeZone.getZone().getId());
        System.out.println(timeZone.getOffset().getTotalSeconds()); //Offset
        System.out.println(rules.getStandardOffset(instant).getTotalSeconds()); //RawOffset
        System.out.println((rules.getDaylightSavings(instant).getSeconds())); //DstSavings
        System.out.println(rules.isDaylightSavings(instant));
        System.out.println(dstShortName);
        System.out.println(dstLongName);
        if (isDst) {
            //Set standard timezone name
            System.out.println(timeZone.getZone().getDisplayName(TextStyle.SHORT, Locale.ENGLISH));
            System.out.println(timeZone.getZone().getDisplayName(TextStyle.FULL, Locale.ENGLISH));
        } else {
            //Set DST timezone name
            System.out.println(tz.getDisplayName(true, TimeZone.SHORT, Locale.ENGLISH));
            System.out.println(tz.getDisplayName(true, TimeZone.LONG, Locale.ENGLISH));
        }

//        //SHORT: CEST
//        DateTimeFormatter.ofPattern("zzz").format(zonedDateTime)
//
//        //SHORT: CET 
//        ZoneId.getDisplayName(TextStyle.SHORT,Locale.ENGLISH)
//
//        //LONG: Central European Summer Time
//        DateTimeFormatter.ofPattern("zzzz").format(zonedDateTime)
//
//        //LONG: Central European Time
//        ZoneId.getDisplayName(TextStyle.LONG,Locale.ENGLISH)
//
//        //Use this for converting CET to CEST and vice versa
//        TimeZone tz = TimeZone.getTimeZone(timeZone.getZone());
//        tz.getDisplayName(true, TimeZone.SHORT, Locale.ENGLISH));


//Joda
//        DateTimeZone dz = DateTimeZone.forID("Asia/Manila");
//        String shortName = dz.getShortName(DateTimeUtils.currentTimeMillis());
//        System.out.println(shortName);
//
//        String longerName = dz.getName(DateTimeUtils.currentTimeMillis());
//        System.out.println(longerName);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top