John
John

Reputation: 551

Timezone display value with GMT offset from a given timezone?

I would like to construct a timezone list to show it to users to select. The display name has to be like:

( GMT 5:30 ) India Standard Time(Asia/Calcutta)

I am taking all timezones with TimeZone.getAvailableIDs() and constructing the list. The code I wrote is:

String[] timeZones = TimeZone.getAvailableIDs();
List<String> tzList = new ArrayList<String>();
for (String timeZone : timeZones)
{
  TimeZone tz = TimeZone.getTimeZone(timeZone);
  StringBuilder timeZoneStr = new StringBuilder();
  timeZoneStr.append("( GMT ").append(tz.getRawOffset() / (60 * 60 * 1000)).append(" ) ").append(tz.getDisplayName()).append("(").append(timeZone).append(")");
  tzList.add(timeZoneStr.toString());
  System.out.println(timeZoneStr.toString());
}

A snippet of the output would be like:

( GMT 5 ) Maldives Time(Indian/Maldives)
( GMT 5 ) Pakistan Time(PLT)
( GMT 5 ) India Standard Time(Asia/Calcutta)
( GMT 5 ) India Standard Time(Asia/Kolkata)
( GMT 5 ) India Standard Time(IST)

But the output I need to get is:

( GMT 5:0 ) Maldives Time(Indian/Maldives)
( GMT 5:0 ) Pakistan Time(PLT)
( GMT 5:30 ) India Standard Time(Asia/Calcutta)
( GMT 5:30 ) India Standard Time(Asia/Kolkata)
( GMT 5:30 ) India Standard Time(IST)

What should I do to get 5:30?

Upvotes: 2

Views: 15742

Answers (5)

Matthias M.
Matthias M.

Reputation: 211

Just use a SimpleDateFormat with the XXX timezone pattern (produces an ISO 8601 timezone)

    DateFormat gmt = new SimpleDateFormat("'GMT' XXX");
    for (TimeZone tz : timeZones) {
        gmt.setTimeZone(tz);
        String gmtTimezone = gmt.format(new Date());
        System.err.println(tz.getID() + " " + gmtTimezone);
    }

Source: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html#iso8601timezone

Upvotes: 0

Nandan Tadahal
Nandan Tadahal

Reputation: 19

Offset timezone using below method :

private static String displayTimeZone(TimeZone tz) {

    long hours = TimeUnit.MILLISECONDS.toHours(tz.getRawOffset());
    long minutes = TimeUnit.MILLISECONDS.toMinutes(tz.getRawOffset()) 
                              - TimeUnit.HOURS.toMinutes(hours);
    // avoid -4:-30 issue
    minutes = Math.abs(minutes);

    String result = "";
    if (hours > 0) {
        result = String.format("(GMT+%d:%02d) %s", hours, minutes, tz.getID());
    } else {
        result = String.format("(GMT%d:%02d) %s", hours, minutes, tz.getID());
    }

    return result;

}

Upvotes: 0

Emmanuel Bourg
Emmanuel Bourg

Reputation: 11048

Another solution with the proper formatting :

DateFormat fmt = new SimpleDateFormat("HH:mm");
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));

List<String> tzList = new ArrayList<String>();
for (String timeZone : TimeZone.getAvailableIDs()) {   
    TimeZone tz = TimeZone.getTimeZone(timeZone);

    StringBuilder timeZoneStr = new StringBuilder();
    timeZoneStr.append("( GMT ");
    if (tz.getRawOffset() < 0) {
        timeZoneStr.append("-");
    }
    timeZoneStr.append(fmt.format(new Date(Math.abs(tz.getRawOffset()))));
    timeZoneStr.append(" ) ").append(tz.getDisplayName()).append(timeZone).append(")");

    tzList.add(timeZoneStr.toString());
    System.out.println(timeZoneStr.toString());
}

Upvotes: 2

Duncan Jones
Duncan Jones

Reputation: 69369

A more readable answer is the following:

for (String timeZone : timeZones) {
  TimeZone tz = TimeZone.getTimeZone(timeZone);

  long hours = TimeUnit.MILLISECONDS.toHours(tz.getRawOffset());
  long minutes = TimeUnit.MILLISECONDS.toMinutes(tz.getRawOffset())
      - TimeUnit.HOURS.toMinutes(hours);

  String timeZoneString = String.format("( GMT %d:%02d ) %s(%s)", hours,
      minutes, tz.getDisplayName(), timeZone);
  tzList.add(timeZoneString);
  System.out.println(timeZoneString);
}

This also correctly displays e.g. 5:00 and 5:30. The use of String.format() makes the final string easier to determine when reading the code. The use of the TimeUnit class simplifies the maths.

Upvotes: 6

Filipe Fedalto
Filipe Fedalto

Reputation: 2540

You should switch the timezone forming line to:

timeZoneStr.append("( GMT ").append(tz.getRawOffset() / (60 * 60 * 1000)).append(":").append((tz.getRawOffset() / (60 * 1000))%60).append(" ) ").append(tz.getDisplayName()).append("(").append(timeZone).append(")");

I think this is the answer you're looking for. However, you may still format the minutes, as they only show one digit when the time offset is, for example 12 hours. It's shown as 12:0.

Upvotes: 2

Related Questions