From: Yoshito Umaoka Date: Thu, 21 Sep 2017 16:51:49 +0000 (+0000) Subject: ICU-13321 Added a new method TimeZone#setICUDefault(TimeZone), which only changes... X-Git-Tag: release-60-rc~124 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f8beac7267bcc9403f5173d552bcc3746e2c9c43;p=icu ICU-13321 Added a new method TimeZone#setICUDefault(TimeZone), which only changes ICU default. Clean up TimeZone#setDefault(TimeZone) with the new method. Updated the API comments to explain the behavior precisely. X-SVN-Rev: 40441 --- diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/TimeZone.java b/icu4j/main/classes/core/src/com/ibm/icu/util/TimeZone.java index c4c5b101a70..dc2352a9abd 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/util/TimeZone.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/util/TimeZone.java @@ -949,54 +949,79 @@ abstract public class TimeZone implements Serializable, Cloneable, FreezableTimeZone that is - * returned by the getDefault method. If zone - * is null, reset the default to the value it had originally when the - * VM first started. + * Sets the TimeZone that is returned by the getDefault + * method. This method also sets a Java TimeZone equivalent to the input tz + * as the JVM's default time zone if not null. If tz is null, next + * {@link #getDefault()} method invocation will reset the default time zone + * synchronized with the JVM's default at that time. + * * @param tz the new default time zone * @stable ICU 2.0 */ public static synchronized void setDefault(TimeZone tz) { - defaultZone = tz; - java.util.TimeZone jdkZone = null; - if (defaultZone instanceof JavaTimeZone) { - jdkZone = ((JavaTimeZone)defaultZone).unwrap(); - } else { + // Set default ICU time zone, used by #getDefault() + setICUDefault(tz); + + if (tz != null) { // Keep java.util.TimeZone default in sync so java.util.Date // can interoperate with com.ibm.icu.util classes. - - if (tz != null) { - if (tz instanceof com.ibm.icu.impl.OlsonTimeZone) { - // Because of the lack of APIs supporting historic - // zone offset/dst saving in JDK TimeZone, - // wrapping ICU TimeZone with JDK TimeZone will - // cause historic offset calculation in Calendar/Date. - // JDK calendar implementation calls getRawOffset() and - // getDSTSavings() when the instance of JDK TimeZone - // is not an instance of JDK internal TimeZone subclass - // (sun.util.calendar.ZoneInfo). Ticket#6459 - String icuID = tz.getID(); + java.util.TimeZone jdkZone = null; + if (tz instanceof JavaTimeZone) { + jdkZone = ((JavaTimeZone)tz).unwrap(); + } else if (tz instanceof com.ibm.icu.impl.OlsonTimeZone) { + // Because of the lack of APIs supporting historic + // zone offset/dst saving in JDK TimeZone, + // wrapping ICU TimeZone with JDK TimeZone will + // cause historic offset calculation in Calendar/Date. + // JDK calendar implementation calls getRawOffset() and + // getDSTSavings() when the instance of JDK TimeZone + // is not an instance of JDK internal TimeZone subclass + // (sun.util.calendar.ZoneInfo). Ticket#6459 + String icuID = tz.getID(); + jdkZone = java.util.TimeZone.getTimeZone(icuID); + if (!icuID.equals(jdkZone.getID())) { + // If the ID was unknown, retry with the canonicalized + // ID instead. This will ensure that JDK 1.1.x + // compatibility IDs supported by ICU (but not + // necessarily supported by the platform) work. + // Ticket#11483 + icuID = getCanonicalID(icuID); jdkZone = java.util.TimeZone.getTimeZone(icuID); if (!icuID.equals(jdkZone.getID())) { - // If the ID was unknown, retry with the canonicalized - // ID instead. This will ensure that JDK 1.1.x - // compatibility IDs supported by ICU (but not - // necessarily supported by the platform) work. - // Ticket#11483 - icuID = getCanonicalID(icuID); - jdkZone = java.util.TimeZone.getTimeZone(icuID); - if (!icuID.equals(jdkZone.getID())) { - // JDK does not know the ID.. - jdkZone = null; - } + // JDK does not know the ID.. + jdkZone = null; } } - if (jdkZone == null) { - jdkZone = TimeZoneAdapter.wrap(tz); - } } + if (jdkZone == null) { + jdkZone = TimeZoneAdapter.wrap(tz); + } + java.util.TimeZone.setDefault(jdkZone); + } + } + + /** + * Sets the TimeZone that is returned by the getDefault + * method. If tz is null, next {@link #getDefault()} method invocation + * will reset the default time zone synchronized with the JVM's default at that time. + * Unlike {@link #setDefault(TimeZone)}, this method does not change the JVM's + * default time zone. + * + * @param tz the new default time zone + * @internal + * @deprecated This API is ICU internal only. + */ + @Deprecated + public static synchronized void setICUDefault(TimeZone tz) { + if (tz == null) { + defaultZone = null; + } else if (tz.isFrozen()) { + // No need to create a defensive copy + defaultZone = tz; + } else { + // Creates a defensive copy and freeze it + defaultZone = ((TimeZone)tz.clone()).freeze(); } - java.util.TimeZone.setDefault(jdkZone); } /** diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneTest.java index 25089080133..7bc747e361f 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/timezone/TimeZoneTest.java @@ -504,52 +504,46 @@ public class TimeZoneTest extends TestFmwk if (!zoneclone.equals(zone)) errln("FAIL: clone or operator== failed"); zoneclone.setID("abc"); if (zoneclone.equals(zone)) errln("FAIL: clone or operator!= failed"); - // delete zoneclone; zoneclone = (TimeZone)zone.clone(); if (!zoneclone.equals(zone)) errln("FAIL: clone or operator== failed"); zoneclone.setRawOffset(45678); if (zoneclone.equals(zone)) errln("FAIL: clone or operator!= failed"); - // C++ only - /* - SimpleTimeZone copy(*zone); - if (!(copy == *zone)) errln("FAIL: copy constructor or operator== failed"); - copy = *(SimpleTimeZone*)zoneclone; - if (!(copy == *zoneclone)) errln("FAIL: assignment operator or operator== failed"); - */ - + // set/getDefault TimeZone saveDefault = TimeZone.getDefault(); TimeZone.setDefault(zone); TimeZone defaultzone = TimeZone.getDefault(); - if (defaultzone == zone) errln("FAIL: Default object is identical, not clone"); - if (!defaultzone.equals(zone)) errln("FAIL: Default object is not equal"); + if (defaultzone == zone) { + errln("FAIL: Default object is identical, not clone"); + } + if (!defaultzone.equals(zone)) { + errln("FAIL: Default object is not equal"); + } + java.util.TimeZone javaDefault = java.util.TimeZone.getDefault(); + if (offset != javaDefault.getRawOffset() || !id.equals(javaDefault.getID())) { + errln("FAIL: Java runtime default time zone is not synchronized"); + } + + String anotheId = "AnotherZone"; + int anotherOffset = 23456; + SimpleTimeZone anotherZone = new SimpleTimeZone(anotherOffset, anotheId); + TimeZone.setICUDefault(anotherZone); + TimeZone newICUDefaultZone = TimeZone.getDefault(); + if (newICUDefaultZone == anotherZone) { + errln("FAIL: New ICU default object is identical, not clone"); + } + if (!newICUDefaultZone.equals(anotherZone)) { + errln("FAIL: New ICU default object is not equal"); + } + javaDefault = java.util.TimeZone.getDefault(); + if (offset != javaDefault.getRawOffset() || !id.equals(javaDefault.getID())) { + errln("FAIL: Java runtime default time zone was updated"); + } + TimeZone.setDefault(saveDefault); - // delete defaultzone; - // delete zoneclone; - -// // ICU 2.6 Coverage -// logln(zone.toString()); -// logln(zone.getDisplayName()); -// SimpleTimeZoneAdapter stza = new SimpleTimeZoneAdapter((SimpleTimeZone) TimeZone.getTimeZone("GMT")); -// stza.setID("Foo"); -// if (stza.hasSameRules(java.util.TimeZone.getTimeZone("GMT"))) { -// errln("FAIL: SimpleTimeZoneAdapter.hasSameRules"); -// } -// stza.setRawOffset(3000); -// offset = stza.getOffset(GregorianCalendar.BC, 2001, Calendar.DECEMBER, -// 25, Calendar.TUESDAY, 12*60*60*1000); -// if (offset != 3000) { -// errln("FAIL: SimpleTimeZoneAdapter.getOffset"); -// } -// SimpleTimeZoneAdapter dup = (SimpleTimeZoneAdapter) stza.clone(); -// if (stza.hashCode() != dup.hashCode()) { -// errln("FAIL: SimpleTimeZoneAdapter.hashCode"); -// } -// if (!stza.equals(dup)) { -// errln("FAIL: SimpleTimeZoneAdapter.equals"); -// } -// logln(stza.toString()); + + String tzver = TimeZone.getTZDataVersion(); if (tzver.length() != 5 /* 4 digits + 1 letter */) {