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
This commit is contained in:
Yoshito Umaoka 2017-09-21 16:51:49 +00:00
parent a0fcf76a8d
commit f8beac7267
2 changed files with 91 additions and 72 deletions

View File

@ -949,54 +949,79 @@ abstract public class TimeZone implements Serializable, Cloneable, Freezable<Tim
}
/**
* Sets the <code>TimeZone</code> that is
* returned by the <code>getDefault</code> method. If <code>zone</code>
* is null, reset the default to the value it had originally when the
* VM first started.
* Sets the <code>TimeZone</code> that is returned by the <code>getDefault</code>
* method. This method also sets a Java TimeZone equivalent to the input <code>tz</code>
* as the JVM's default time zone if not null. If <code>tz</code> 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 <code>TimeZone</code> that is returned by the <code>getDefault</code>
* method. If <code>tz</code> 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);
}
/**

View File

@ -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");
TimeZone.setDefault(saveDefault);
// delete defaultzone;
// delete zoneclone;
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);
// // 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 */) {