< prev index next >

src/java.base/share/classes/java/util/TimeZone.java

Print this page

        

@@ -40,10 +40,13 @@
 
 import java.io.Serializable;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.time.ZoneId;
+
+import sun.misc.JavaUtilTimeZoneAccess;
+import sun.misc.SharedSecrets;
 import sun.security.action.GetPropertyAction;
 import sun.util.calendar.ZoneInfo;
 import sun.util.calendar.ZoneInfoFile;
 import sun.util.locale.provider.TimeZoneNameUtility;
 

@@ -129,10 +132,20 @@
  * @see          SimpleTimeZone
  * @author       Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu
  * @since        1.1
  */
 abstract public class TimeZone implements Serializable, Cloneable {
+
+    static {
+        SharedSecrets.setJavaUtilTimeZoneAccess(new JavaUtilTimeZoneAccess() {
+            @Override
+            public TimeZone getDefaultRef() {
+                return TimeZone.getDefaultRef();
+            }
+        });
+    }
+
     /**
      * Sole constructor.  (For invocation by subclass constructors, typically
      * implicit.)
      */
     public TimeZone() {

@@ -291,10 +304,11 @@
     {
         if (ID == null) {
             throw new NullPointerException();
         }
         this.ID = ID;
+        this.zoneId = null; // invalidate cache
     }
 
     /**
      * Returns a long standard time name of this {@code TimeZone} suitable for
      * presentation to the user in the default locale.

@@ -542,20 +556,26 @@
      * @return a {@code ZoneId} representing the same time zone as this
      *         {@code TimeZone}
      * @since 1.8
      */
     public ZoneId toZoneId() {
+        ZoneId zId = zoneId;
+        if (zId == null) {
         String id = getID();
         if (ZoneInfoFile.useOldMapping() && id.length() == 3) {
             if ("EST".equals(id))
-                return ZoneId.of("America/New_York");
-            if ("MST".equals(id))
-                return ZoneId.of("America/Denver");
-            if ("HST".equals(id))
-                return ZoneId.of("America/Honolulu");
+                    zId = ZoneId.of("America/New_York");
+                else if ("MST".equals(id))
+                    zId = ZoneId.of("America/Denver");
+                else if ("HST".equals(id))
+                    zId = ZoneId.of("America/Honolulu");
+            } else {
+                zId = ZoneId.of(id, ZoneId.SHORT_IDS);
+            }
+            zoneId = zId;
         }
-        return ZoneId.of(id, ZoneId.SHORT_IDS);
+        return zId;
     }
 
     private static TimeZone getTimeZone(String ID, boolean fallback) {
         TimeZone tz = ZoneInfo.getTimeZone(ID);
         if (tz == null) {

@@ -708,11 +728,11 @@
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             sm.checkPermission(new PropertyPermission
                                ("user.timezone", "write"));
         }
-        defaultTimeZone = zone;
+        defaultTimeZone = (TimeZone) zone.clone();
     }
 
     /**
      * Returns true if this zone has the same rule and offset as another zone.
      * That is, if this zone differs only in ID, if at all.  Returns false

@@ -733,13 +753,11 @@
      * @return a clone of this <code>TimeZone</code>
      */
     public Object clone()
     {
         try {
-            TimeZone other = (TimeZone) super.clone();
-            other.ID = ID;
-            return other;
+            return super.clone();
         } catch (CloneNotSupportedException e) {
             throw new InternalError(e);
         }
     }
 

@@ -757,10 +775,16 @@
      * display names.  <code>ID</code> values are unique in the system
      * table but may not be for dynamically created zones.
      * @serial
      */
     private String           ID;
+
+    /**
+     * Cached {@link ZoneId} for this TimeZone
+     */
+    private transient ZoneId zoneId;
+
     private static volatile TimeZone defaultTimeZone;
 
     static final String         GMT_ID        = "GMT";
     private static final int    GMT_ID_LENGTH = 3;
 
< prev index next >