]> granicus.if.org Git - icu/commitdiff
ICU-11619 VTimeZone throws a ClassCastException when Zone ID unknown; move fixes...
authorAndy Heninger <andy.heninger@gmail.com>
Wed, 7 Oct 2015 00:32:46 +0000 (00:32 +0000)
committerAndy Heninger <andy.heninger@gmail.com>
Wed, 7 Oct 2015 00:32:46 +0000 (00:32 +0000)
X-SVN-Rev: 38039

icu4j/main/classes/core/src/com/ibm/icu/impl/ZoneMeta.java
icu4j/main/classes/core/src/com/ibm/icu/util/TimeZone.java
icu4j/main/classes/core/src/com/ibm/icu/util/VTimeZone.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneTest.java

index 177206b90d33e5a44cbe88baf73d0bbb9c04e11a..b89bbf9eda776dac3a68cf6376e1297e62c0eca2 100644 (file)
@@ -1,6 +1,6 @@
 /*
 **********************************************************************
-* Copyright (c) 2003-2014 International Business Machines
+* Copyright (c) 2003-2015 International Business Machines
 * Corporation and others.  All Rights Reserved.
 **********************************************************************
 * Author: Alan Liu
@@ -571,7 +571,7 @@ public final class ZoneMeta {
      * Returns a frozen OlsonTimeZone instance for the given ID.
      * This method returns null when the given ID is unknown.
      */
-    public static TimeZone getSystemTimeZone(String id) {
+    public static OlsonTimeZone getSystemTimeZone(String id) {
         return SYSTEM_ZONE_CACHE.getInstance(id, id);
     }
 
@@ -612,7 +612,7 @@ public final class ZoneMeta {
      * @return a frozen SimpleTimeZone with the given offset and
      * no Daylight Savings Time, or null if the id cannot be parsed.
     */
-    public static TimeZone getCustomTimeZone(String id){
+    public static SimpleTimeZone getCustomTimeZone(String id){
         int[] fields = new int[4];
         if (parseCustomID(id, fields)) {
             // fields[0] - sign
@@ -769,7 +769,7 @@ public final class ZoneMeta {
      * @param offset GMT offset in milliseconds
      * @return A custom TimeZone for the offset with normalized time zone id
      */
-    public static TimeZone getCustomTimeZone(int offset) {
+    public static SimpleTimeZone getCustomTimeZone(int offset) {
         boolean negative = false;
         int tmp = offset;
         if (offset < 0) {
index 421ed136cc776deaba1e24e899acb46bdd195fe4..b441c8eaad4076a91ffe8fc8a90bf68437221ea1 100644 (file)
@@ -740,45 +740,47 @@ abstract public class TimeZone implements Serializable, Cloneable, Freezable<Tim
 
     /**
      * Gets the <code>TimeZone</code> for the given ID and the timezone type.
-     * @param ID time zone ID
+     * @param id time zone ID
      * @param type time zone implementation type, TIMEZONE_JDK or TIMEZONE_ICU 
      * @param frozen specify if the returned object can be frozen
      * @return the specified <code>TimeZone</code> or UNKNOWN_ZONE if the given ID
      * cannot be understood.
      */
-    private static TimeZone getTimeZone(String ID, int type, boolean frozen) {
+    private static TimeZone getTimeZone(String id, int type, boolean frozen) {
         TimeZone result;
         if (type == TIMEZONE_JDK) {
-            result = JavaTimeZone.createTimeZone(ID);
+            result = JavaTimeZone.createTimeZone(id);
             if (result != null) {
                 return frozen ? result.freeze() : result;
-            }
+            } 
+            result = getFrozenICUTimeZone(id, false);
         } else {
-            /* We first try to lookup the zone ID in our system list.  If this
-             * fails, we try to parse it as a custom string GMT[+-]HH:mm.  If
-             * all else fails, we return GMT, which is probably not what the
-             * user wants, but at least is a functioning TimeZone object.
-             *
-             * We cannot return NULL, because that would break compatibility
-             * with the JDK.
-             */
-            if(ID==null){
-                throw new NullPointerException();
-            }
-            result = ZoneMeta.getSystemTimeZone(ID);
-        }
-
-        if (result == null) {
-            result = ZoneMeta.getCustomTimeZone(ID);
+            result = getFrozenICUTimeZone(id, true);
         }
-
         if (result == null) {
-            LOGGER.fine("\"" +ID + "\" is a bogus id so timezone is falling back to Etc/Unknown(GMT).");
+            LOGGER.fine("\"" +id + "\" is a bogus id so timezone is falling back to Etc/Unknown(GMT).");
             result = UNKNOWN_ZONE;
         }
-
         return frozen ? result : result.cloneAsThawed();
     }
+    
+    /**
+     * Returns a frozen ICU type TimeZone object given a time zone ID.
+     * @param id the time zone ID
+     * @param trySystem if true tries the system time zones first otherwise skip to the
+     *   custom time zones.
+     * @return the frozen ICU TimeZone or null if one could not be created.
+     */
+    static BasicTimeZone getFrozenICUTimeZone(String id, boolean trySystem) {
+        BasicTimeZone result = null;
+        if (trySystem) {
+            result = ZoneMeta.getSystemTimeZone(id);
+        }
+        if (result == null) {
+            result = ZoneMeta.getCustomTimeZone(id);
+        }
+        return result;
+    }
 
     /**
      * Sets the default time zone type used by <code>getTimeZone</code>.
index bcfbec2d778a90bac92fbe37900ca999d97fb47c..3aeed4aa162972a174bb10a81a68c1f6adcf5144 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *******************************************************************************
- * Copyright (C) 2007-2014, International Business Machines Corporation and    *
+ * Copyright (C) 2007-2015, International Business Machines Corporation and    *
  * others. All Rights Reserved.                                                *
  *******************************************************************************
  */
@@ -47,8 +47,12 @@ public class VTimeZone extends BasicTimeZone {
      * @stable ICU 3.8
      */
     public static VTimeZone create(String tzid) {
+        BasicTimeZone basicTimeZone = TimeZone.getFrozenICUTimeZone(tzid, true);
+        if (basicTimeZone == null) {
+            return null;
+        }
         VTimeZone vtz = new VTimeZone(tzid);
-        vtz.tz = (BasicTimeZone)TimeZone.getTimeZone(tzid, TimeZone.TIMEZONE_ICU);
+        vtz.tz = (BasicTimeZone) basicTimeZone.cloneAsThawed();
         vtz.olsonzid = vtz.tz.getID();
 
         return vtz;
index ee9d5e7e8ad49630b1cfbbed62f1b23899e17747..bc644726ed66094b30a10a24fa1703ee9ab92940 100644 (file)
@@ -2179,6 +2179,11 @@ public class TimeZoneTest extends TestFmwk
             }
         }
     }
+    
+    public void Test11619_UnrecognizedTimeZoneID() {
+        VTimeZone vzone = VTimeZone.create("ABadTimeZoneId");
+        this.assertNull("", vzone);
+    }
 
     private static boolean isDaylightTimeAvailable(TimeZone tz, long start) {
         if (tz.inDaylightTime(new Date(start))) {