16

I have a string, I need to check whether it is a standard time zone identifier or not. I am not sure which method I need to use.

String timeZoneToCheck = "UTC";

I would like to check whether it represents a valid time zone or not.

xav
  • 5,452
  • 7
  • 48
  • 57
user1772643
  • 615
  • 3
  • 11
  • 23

9 Answers9

36

You can write it in one line

public boolean validTimeZone(String timezone) {
    return Set.of(TimeZone.getAvailableIDs()).contains(timezone);
}

Alternatively, you can make a static field for it

private static final Set<String> TIMEZONES = Set.of(TimeZone.getAvailableIDs())
public boolean validTimeZone(String timezone) {
    return TIMEZONES.contains(timezone);
}
Yan Khonski
  • 12,225
  • 15
  • 76
  • 114
Maciej Dzikowicki
  • 859
  • 1
  • 10
  • 10
18

You can get all supported ID using getAvailableIDs()

Then loop the supportedID array and compare with your String.

Example:

String[] validIDs = TimeZone.getAvailableIDs();
for (String str : validIDs) {
      if (str != null && str.equals("yourString")) {
        System.out.println("Valid ID");
      }
}
xav
  • 5,452
  • 7
  • 48
  • 57
kosa
  • 65,990
  • 13
  • 130
  • 167
13

java.time.ZoneId

It's simple just use ZoneId.of("Asia/Kolkata").

try {
    ZoneId.of("Asia/Kolkataa");
} catch (Exception e) {
    e.printStackTrace();
}

if your insert invalid time zone it will throw exception

**java.time.zone.ZoneRulesException: Unknown time-zone ID: Asia/Kolkataa**
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
yali
  • 1,038
  • 4
  • 15
  • 31
6

This is a more efficient solution, than looping through all possible IDs. It checks the output of getTimeZone.

Java Docs (TimeZone#getTimeZone):

Returns: the specified TimeZone, or the GMT zone if the given ID cannot be understood.

So if the output is the GMT timezone the input is invalid, except if the input accually was "GMT".

public static boolean isValidTimeZone(@NonNull String timeZoneID) {
    return (timeZoneID.equals("GMT") || !TimeZone.getTimeZone(timeZoneID).getID().equals("GMT"));
}

Or if you want to use the valid timezone without calling getTimeZone twice:

TimeZone timeZone = TimeZone.getTimeZone(timeZoneToCheck);
if(timeZoneToCheck.equals("GMT") || !timeZone.getID().equals("GMT")) {
    // TODO Valid - use timeZone
} else {
    // TODO Invalid - handle the invalid input
}
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Minding
  • 1,383
  • 1
  • 17
  • 29
4

I would like to propose the next workaround:

public static final String GMT_ID = "GMT";
public static TimeZone getTimeZone(String ID) {
    if (null == ID) {
        return null;
    }

    TimeZone tz = TimeZone.getTimeZone(ID);

    // not nullable value - look at implementation of TimeZone.getTimeZone
    String tzID = tz.getID();

    // check if not fallback result 
    return GMT_ID.equals(tzID) && !tzID.equals(ID) ? null : tz;
}

As result in case of invalid timezone ID or invalid just custom timezone you will receive null. Additionally you can introduce corresponding null value handler (use case dependent) - throw exception & etc.

nvolynets
  • 119
  • 3
  • 2
    Except for the obvious fact your method will return null for valid id "GMT" (or any equivalent). – Piotr Findeisen Jul 27 '15 at 08:07
  • To expand on that: there are lots (about 200?) of valid tzid strings that are aliases to other tzids. When you ask for "US/Pacific", you get back the valid and equivalent timezone "America/Los_Angeles", for example. – benkc Mar 30 '18 at 16:45
3
private boolean isValidTimeZone(final String timeZone) {
    final String DEFAULT_GMT_TIMEZONE = "GMT";
    if (timeZone.equals(DEFAULT_GMT_TIMEZONE)) {
        return true;
    } else {
        // if custom time zone is invalid,
        // time zone id returned is always "GMT" by default
        String id = TimeZone.getTimeZone(timeZone).getID();
        if (!id.equals(DEFAULT_GMT_TIMEZONE)) {
            return true;
        }
    }
    return false;
}

The method returns true for the following:

assertTrue(this.isValidTimeZone("JST"));
assertTrue(this.isValidTimeZone("UTC"));
assertTrue(this.isValidTimeZone("GMT"));
// GMT+00:00
assertTrue(this.isValidTimeZone("GMT+0"));
// GMT-00:00
assertTrue(this.isValidTimeZone("GMT-0"));
// GMT+09:00
assertTrue(this.isValidTimeZone("GMT+9:00"));
// GMT+10:30
assertTrue(this.isValidTimeZone("GMT+10:30"));
// GMT-04:00
assertTrue(this.isValidTimeZone("GMT-0400"));
// GMT+08:00
assertTrue(this.isValidTimeZone("GMT+8"));
// GMT-13:00
assertTrue(this.isValidTimeZone("GMT-13"));
// GMT-13:59
assertTrue(this.isValidTimeZone("GMT+13:59"));
// NOTE: valid time zone IDs (see TimeZone.getAvailableIDs())
// GMT-08:00
assertTrue(this.isValidTimeZone("America/Los_Angeles"));
// GMT+09:00
assertTrue(this.isValidTimeZone("Japan"));
// GMT+01:00
assertTrue(this.isValidTimeZone("Europe/Berlin"));
// GMT+04:00
assertTrue(this.isValidTimeZone("Europe/Moscow"));
// GMT+08:00
assertTrue(this.isValidTimeZone("Asia/Singapore"));

...And false with the following timezones:

assertFalse(this.isValidTimeZone("JPY"));
assertFalse(this.isValidTimeZone("USD"));
assertFalse(this.isValidTimeZone("UTC+8"));
assertFalse(this.isValidTimeZone("UTC+09:00"));
assertFalse(this.isValidTimeZone("+09:00"));
assertFalse(this.isValidTimeZone("-08:00"));
assertFalse(this.isValidTimeZone("-1"));
assertFalse(this.isValidTimeZone("GMT+10:-30"));
// hours is 0-23 only
assertFalse(this.isValidTimeZone("GMT+24:00"));
// minutes 00-59 only
assertFalse(this.isValidTimeZone("GMT+13:60"));
Laurel
  • 5,965
  • 14
  • 31
  • 57
jejare
  • 51
  • 4
1

If TimeZone.getAvailableIDs() contains ID in question, it's valid:

public boolean validTimeZone(String id) {
    for (String tzId : TimeZone.getAvailableIDs()) {
            if (tzId.equals(id))
                return true;
    }
    return false;
}

Unfortunately TimeZone.getTimeZone() method silently discards invalid IDs and returns GMT instead:

Returns:

the specified TimeZone, or the GMT zone if the given ID cannot be understood.

Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • I thought if there is any method to validate the the id instead of looping through all ids as it just discard the invalid IDs and returns GMT. Thanks for your answers. – user1772643 Oct 26 '12 at 19:12
1

You can use TimeZone.getAvailableIDs() to get list of supported Id

for (String str : TimeZone.getAvailableIDs()) {
    if (str.equals("UTC")) {
        //found
    }
}
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Amit Deshpande
  • 19,001
  • 4
  • 46
  • 72
1

Since TimeZone#getTimeZone(String id) returns a default if the value is invalid (rather than returning an invalid time zone), if the reinterpreted value does not match the initial value, it wasn't valid.

private static boolean isValidTimeZone(@Nonnull String potentialTimeZone)
{
    // If the input matches the re-interpreted value, then the time zone is valid.
    return TimeZone.getTimeZone(potentialTimeZone).getID().equals(potentialTimeZone);
}
CoatedMoose
  • 3,624
  • 1
  • 20
  • 36
  • 1
    No, because there are lots of valid tzid strings that are aliases to other tzids. When you ask for "US/Pacific", you get back the valid and equivalent timezone "America/Los_Angeles", for example. – benkc Mar 30 '18 at 16:46
  • You may still need GMT check as suggested in above answer https://stackoverflow.com/a/17926927/3343801 – Venkateswara Rao May 20 '21 at 05:13