Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TimeZone validation in Java

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.

like image 432
user1772643 Avatar asked Oct 26 '12 19:10

user1772643


People also ask

What is TimeZone in Java?

TimeZone represents a time zone offset, and also figures out daylight savings. Typically, you get a TimeZone using getDefault which creates a TimeZone based on the time zone where the program is running. For example, for a program running in Japan, getDefault creates a TimeZone object based on Japanese Standard Time.

How do I change the TimeZone in Java?

You can make use of the following DateFormat. SimpleDateFormat myDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); myDate. setTimeZone(TimeZone. getTimeZone("UTC")); Date newDate = myDate.


9 Answers

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**
like image 147
yali Avatar answered Oct 06 '22 00:10

yali


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);
}
like image 26
Maciej Dzikowicki Avatar answered Oct 06 '22 00:10

Maciej Dzikowicki


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");
      }
}
like image 42
kosa Avatar answered Oct 05 '22 22:10

kosa


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
}
like image 22
Minding Avatar answered Oct 05 '22 22:10

Minding


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.

like image 22
nvolynets Avatar answered Oct 05 '22 23:10

nvolynets


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"));
like image 43
jejare Avatar answered Oct 05 '22 22:10

jejare


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);
}
like image 24
CoatedMoose Avatar answered Oct 05 '22 22:10

CoatedMoose


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

for (String str : TimeZone.getAvailableIDs()) {
    if (str.equals("UTC")) {
        //found
    }
}
like image 33
Amit Deshpande Avatar answered Oct 06 '22 00:10

Amit Deshpande


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.

like image 43
Tomasz Nurkiewicz Avatar answered Oct 05 '22 22:10

Tomasz Nurkiewicz