Question


In a android form , i am accepting a GMT value(offset) from user such a +5:30 , +3:00.
and from this value , i want to calculate the timeZone that is "India/Delhi".

Any ideas on how to do it ......Plzz

Was it helpful?

Solution

If you already have a specific instant in time at which that offset is valid, you could do something like this:

import java.util.*;

public class Test {

    public static void main(String [] args) throws Exception {
        // Five and a half hours
        int offsetMilliseconds = (5 * 60 + 30) * 60 * 1000;
        for (String id : findTimeZones(System.currentTimeMillis(),
                                       offsetMilliseconds)) {
            System.out.println(id);
        }
    }

    public static List<String> findTimeZones(long instant,
                                             int offsetMilliseconds) {
        List<String> ret = new ArrayList<String>();
        for (String id : TimeZone.getAvailableIDs()) {
            TimeZone zone = TimeZone.getTimeZone(id);
            if (zone.getOffset(instant) == offsetMilliseconds) {
                ret.add(id);
            }
        }
        return ret;
    }
}

On my box that prints:

Asia/Calcutta
Asia/Colombo
Asia/Kolkata
IST

(As far as I'm aware, India/Delhi isn't a valid zoneinfo ID.)

If you don't know an instant at which the offset is valid, this becomes rather harder to really do properly. Here's one version:

public static List<String> findTimeZones(int offsetMilliseconds) {
    List<String> ret = new ArrayList<String>();
    for (String id : TimeZone.getAvailableIDs()) {
        TimeZone zone = TimeZone.getTimeZone(id);
        if (zone.getRawOffset() == offsetMilliseconds ||
            zone.getRawOffset() + zone.getDSTSavings() == offsetMilliseconds) {
            ret.add(id);
        }
    }
    return ret;
}

... but that assumes that there are only ever two offsets per time zone, when in fact time zones can change considerably over history. It also gives you a much wider range of IDs, of course. For example, an offset of one hour would include both Europe/London and Europe/Paris, because in summer time London is at UTC+1, whereas in winter Paris is at UTC+1.

OTHER TIPS

Many timezone IDs can have the same timezone offset

Normally, the relation between timezone ID and timezone offset is many to one i.e. many timezone IDs can have the same timezone offset. In fact, on account of DST, a timezone ID can have two timezone offsets e.g. the timezone offsets for the timezone ID, "Europe/London" are "+00:00" and "+01:00" in the summer and in the winter respectively.

Apart from this, there have been instances when the timezone offset of states has been changed by their rulers/politicians many times as also mentioned by Ole V.V. in the following comment:

The relation between timezone ID and timezone offset is many to one … True if you are considering one point in time. If looking at history, it’s really many to many.

So, taking DST and these historical events into account, we can say that the relation between timezone ID and timezone offset is many to many.

Solution using java.time, the modern Date-Time API:

You can traverse ZoneId.getAvailableZoneIds() to filter and collect the ZoneId whose ZoneOffset is equal to the ZoneOffset created using the input offset string.

Demo:

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(getTimeZoneId("+5:30"));
        System.out.println(getTimeZoneId("-5:00"));
    }

    static List<String> getTimeZoneId(String input) {
        List<String> list = new ArrayList<>();
        // Convert +5:30 to +05:30; similarly, -5:00 to -05:00
        String[] arr = input.split(":");
        if (arr.length == 2) {
            input = arr[0].substring(0, 1) + String.format("%02d", Integer.parseInt(arr[0].replaceAll("\\D", ""))) + ":"
                    + arr[1];

            ZoneOffset offset = ZoneOffset.of(input);
            Instant now = Instant.now();

            list = ZoneId.getAvailableZoneIds()
                    .stream()
                    .filter(tzId -> ZoneId.of(tzId).getRules().getOffset(now).equals(offset))
                    .collect(Collectors.toList());
        }
        return list;
    }
}

Output:

[Asia/Kolkata, Asia/Colombo, Asia/Calcutta]
[America/Panama, America/Chicago, America/Eirunepe, Etc/GMT+5, Mexico/General, America/Porto_Acre, America/Guayaquil, America/Rankin_Inlet, US/Central, America/Rainy_River, America/Indiana/Knox, America/North_Dakota/Beulah, America/Monterrey, America/Jamaica, America/Atikokan, America/Coral_Harbour, America/North_Dakota/Center, America/Cayman, America/Indiana/Tell_City, America/Mexico_City, America/Matamoros, CST6CDT, America/Knox_IN, America/Bogota, America/Menominee, America/Resolute, SystemV/EST5, Canada/Central, Brazil/Acre, America/Cancun, America/Lima, America/Bahia_Banderas, US/Indiana-Starke, America/Rio_Branco, SystemV/CST6CDT, Jamaica, America/Merida, America/North_Dakota/New_Salem, America/Winnipeg]

ONLINE DEMO

Note: The regex pattern, \D specifies a non-digit character.

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.

If I have correctly interpreted your question then try this,

final SimpleDateFormat date=
        new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");
date.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("GMT time: " + date.format(currentTime));

In this you can add your offset. see if this helps you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top