diff options
author | Neil Fuller <nfuller@google.com> | 2014-05-15 12:15:12 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-05-15 12:15:14 +0000 |
commit | 76886eb39ac2e44075f0df90addae83933268722 (patch) | |
tree | 4395643d6a3c227049561aca1bdd9ca075576ae6 | |
parent | ab49c8586b1c74e16bf1e7d16e0dee5c7814f8cd (diff) | |
parent | e4a3071d6f5b8ef0f9d86463524491ce0091c62a (diff) | |
download | libcore-76886eb39ac2e44075f0df90addae83933268722.zip libcore-76886eb39ac2e44075f0df90addae83933268722.tar.gz libcore-76886eb39ac2e44075f0df90addae83933268722.tar.bz2 |
Merge "Removing data hacks from ICU root.txt"
8 files changed, 114 insertions, 60 deletions
diff --git a/luni/src/main/java/java/text/SimpleDateFormat.java b/luni/src/main/java/java/text/SimpleDateFormat.java index f832a6e..259bfe0 100644 --- a/luni/src/main/java/java/text/SimpleDateFormat.java +++ b/luni/src/main/java/java/text/SimpleDateFormat.java @@ -1168,6 +1168,8 @@ public class SimpleDateFormat extends DateFormat { if (foundGMT) { offset += 3; } + + // Check for an offset, which may have been preceded by "GMT" char sign; if (offset < string.length() && ((sign = string.charAt(offset)) == '+' || sign == '-')) { ParsePosition position = new ParsePosition(offset + 1); @@ -1195,10 +1197,14 @@ public class SimpleDateFormat extends DateFormat { calendar.setTimeZone(new SimpleTimeZone(raw, "")); return position.getIndex(); } + + // If there was "GMT" but no offset. if (foundGMT) { calendar.setTimeZone(TimeZone.getTimeZone("GMT")); return offset; } + + // Exhaustively look for the string in this DateFormat's localized time zone strings. for (String[] row : formatData.internalZoneStrings()) { for (int i = TimeZoneNames.LONG_NAME; i < TimeZoneNames.NAME_COUNT; ++i) { if (row[i] == null) { diff --git a/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java b/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java index 1f0ee63..42de50a 100644 --- a/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java +++ b/luni/src/test/java/libcore/java/security/cert/X509CRLTest.java @@ -122,7 +122,7 @@ public class X509CRLTest extends TestCase { private Map<String, Date> getCrlDates(String name) throws Exception { Map<String, Date> dates = new HashMap<String, Date>(); - final SimpleDateFormat sdf = new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz"); + final SimpleDateFormat sdf = new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz", Locale.US); final InputStream ris = Support_Resources.getStream(name); try { diff --git a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java index ffddcbe..c35f8e6 100644 --- a/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java +++ b/luni/src/test/java/libcore/java/security/cert/X509CertificateTest.java @@ -170,7 +170,8 @@ public class X509CertificateTest extends TestCase { final InputStream ris = Support_Resources.getStream("x509/cert-rsa-dates.txt"); try { // notBefore=Dec 26 00:19:14 2012 GMT - final SimpleDateFormat sdf = new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz"); + final SimpleDateFormat sdf = + new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz", Locale.US); final BufferedReader buf = new BufferedReader(new InputStreamReader(ris)); String line = buf.readLine(); diff --git a/luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java b/luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java index e13e4df..9ab6f70 100644 --- a/luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java +++ b/luni/src/test/java/libcore/java/text/DateFormatSymbolsTest.java @@ -46,6 +46,10 @@ public class DateFormatSymbolsTest extends junit.framework.TestCase { } public void testSerialization() throws Exception { + // Set the default locale. The default locale determines what strings are used by the + // DateFormatSymbols after deserialization. + Locale.setDefault(Locale.US); + // The Polish language needs stand-alone month and weekday names. Locale pl = new Locale("pl"); DateFormatSymbols originalDfs = new DateFormatSymbols(pl); diff --git a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java index 2813cee..bc21739 100644 --- a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java +++ b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java @@ -80,27 +80,12 @@ public class SimpleDateFormatTest extends junit.framework.TestCase { // The RI fails this test because it doesn't fully support UTS #35. // https://code.google.com/p/android/issues/detail?id=39616 public void testFiveCount_parsing() throws Exception { - // It's pretty silly to try to parse the shortest names, because they're almost always ambiguous. - try { - parseDate(Locale.ENGLISH, "MMMMM", "J"); - fail(); - } catch (junit.framework.AssertionFailedError expected) { - } - try { - parseDate(Locale.ENGLISH, "LLLLL", "J"); - fail(); - } catch (junit.framework.AssertionFailedError expected) { - } - try { - parseDate(Locale.ENGLISH, "EEEEE", "T"); - fail(); - } catch (junit.framework.AssertionFailedError expected) { - } - try { - parseDate(Locale.ENGLISH, "ccccc", "T"); - fail(); - } catch (junit.framework.AssertionFailedError expected) { - } + // It's pretty silly to try to parse the shortest names, because they're almost always + // ambiguous. + assertCannotParse(Locale.ENGLISH, "MMMMM", "J"); + assertCannotParse(Locale.ENGLISH, "LLLLL", "J"); + assertCannotParse(Locale.ENGLISH, "EEEEE", "T"); + assertCannotParse(Locale.ENGLISH, "ccccc", "T"); } // The RI fails this test because it doesn't fully support UTS #35. @@ -197,6 +182,13 @@ public class SimpleDateFormatTest extends junit.framework.TestCase { return dateFormat.format(new Date(0)); } + private static void assertCannotParse(Locale l, String fmt, String value) { + SimpleDateFormat sdf = new SimpleDateFormat(fmt, l); + ParsePosition pp = new ParsePosition(0); + Date d = sdf.parse(value, pp); + assertNull("Value " + value + " must not parse in locale " + l + " with format " + fmt, d); + } + private static Calendar parseDate(Locale l, String fmt, String value) { SimpleDateFormat sdf = new SimpleDateFormat(fmt, l); ParsePosition pp = new ParsePosition(0); @@ -215,21 +207,37 @@ public class SimpleDateFormatTest extends junit.framework.TestCase { String date = "2010-12-23 12:44:57.0 CET"; // ICU considers "CET" (Central European Time) to be common in Britain... assertEquals(1293104697000L, parseDate(Locale.UK, fmt, date).getTimeInMillis()); - // ...but not in the US. Check we can parse such a date anyway. - assertEquals(1293104697000L, parseDate(Locale.US, fmt, date).getTimeInMillis()); + // ...but not in the US. + assertCannotParse(Locale.US, fmt, date); } + // In Honeycomb, only one Olson id was associated with CET (or any other "uncommon" + // abbreviation). This was changed after KitKat to avoid Java hacks on top of ICU data. + // ICU data only provides abbreviations for timezones in the locales where they would + // not be ambiguous to most people of that locale. public void testFormattingUncommonTimeZoneAbbreviations() { - // In Honeycomb, only one Olson id was associated with CET (or any - // other "uncommon" abbreviation). String fmt = "yyyy-MM-dd HH:mm:ss.SSS z"; - String date = "1970-01-01 01:00:00.000 CET"; - SimpleDateFormat sdf = new SimpleDateFormat(fmt, Locale.US); + String unambiguousDate = "1970-01-01 01:00:00.000 CET"; + String ambiguousDate = "1970-01-01 01:00:00.000 GMT+01:00"; + + // The locale to use when formatting. Not every Locale renders "Europe/Berlin" as "CET". The + // UK is one that does, the US is one that does not. + Locale cetUnambiguousLocale = Locale.UK; + Locale cetAmbiguousLocale = Locale.US; + + SimpleDateFormat sdf = new SimpleDateFormat(fmt, cetUnambiguousLocale); sdf.setTimeZone(TimeZone.getTimeZone("Europe/Berlin")); - assertEquals(date, sdf.format(new Date(0))); - sdf = new SimpleDateFormat(fmt, Locale.US); + assertEquals(unambiguousDate, sdf.format(new Date(0))); + sdf = new SimpleDateFormat(fmt, cetUnambiguousLocale); sdf.setTimeZone(TimeZone.getTimeZone("Europe/Zurich")); - assertEquals(date, sdf.format(new Date(0))); + assertEquals(unambiguousDate, sdf.format(new Date(0))); + + sdf = new SimpleDateFormat(fmt, cetAmbiguousLocale); + sdf.setTimeZone(TimeZone.getTimeZone("Europe/Berlin")); + assertEquals(ambiguousDate, sdf.format(new Date(0))); + sdf = new SimpleDateFormat(fmt, cetAmbiguousLocale); + sdf.setTimeZone(TimeZone.getTimeZone("Europe/Zurich")); + assertEquals(ambiguousDate, sdf.format(new Date(0))); } // http://code.google.com/p/android/issues/detail?id=8258 @@ -270,17 +278,6 @@ public class SimpleDateFormatTest extends junit.framework.TestCase { assertEquals("2010-07-08T02:44:48+0000", sdf.format(date)); } - /** - * Africa/Cairo standard time is EET and daylight time is EEST. They no - * longer use their DST zone but we should continue to parse it properly. - */ - public void testObsoleteDstZoneName() throws Exception { - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm zzzz", Locale.US); - Date normal = format.parse("1970-01-01T00:00 EET"); - Date dst = format.parse("1970-01-01T00:00 EEST"); - assertEquals(60 * 60 * 1000, normal.getTime() - dst.getTime()); - } - public void testDstZoneNameWithNonDstTimestamp() throws Exception { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm zzzz", Locale.US); Calendar calendar = new GregorianCalendar(AMERICA_LOS_ANGELES); diff --git a/luni/src/test/java/libcore/java/util/DateTest.java b/luni/src/test/java/libcore/java/util/DateTest.java index ddcc3e5..3ed0952 100644 --- a/luni/src/test/java/libcore/java/util/DateTest.java +++ b/luni/src/test/java/libcore/java/util/DateTest.java @@ -24,16 +24,26 @@ import junit.framework.TestCase; public class DateTest extends TestCase { // http://code.google.com/p/android/issues/detail?id=6013 - public void test_toString() throws Exception { - // Ensure that no matter where this is run, we know what time zone - // to expect. (Though we still assume an "en" locale.) + public void test_toString_us() throws Exception { + // Ensure that no matter where this is run, we know what time zone to expect. + Locale.setDefault(Locale.US); TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago")); assertEquals("Wed Dec 31 18:00:00 CST 1969", new Date(0).toString()); } - public void test_toGMTString() throws Exception { + public void test_toString_nonUs() { + // The string for the timezone depends on what the default locale is. Not every locale + // has a short-name for America/Chicago -> PST. + Locale.setDefault(Locale.UK); + TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago")); + assertEquals("Wed Dec 31 18:00:00 GMT-06:00 1969", new Date(0).toString()); + } + + public void test_toGMTString_us() throws Exception { // Based on https://issues.apache.org/jira/browse/HARMONY-501 TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); + Locale.setDefault(Locale.US); + Calendar c = Calendar.getInstance(); c.clear(); c.set(Calendar.YEAR, 21); @@ -43,4 +53,18 @@ public class DateTest extends TestCase { assertEquals("Sun Jan 01 00:00:00 PST 321", c.getTime().toString()); assertEquals("1 Jan 321 08:00:00 GMT", c.getTime().toGMTString()); } + + public void test_toGMTString_nonUs() throws Exception { + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); + Locale.setDefault(Locale.UK); + + Calendar c = Calendar.getInstance(); + c.clear(); + c.set(Calendar.YEAR, 21); + assertEquals("Wed Jan 01 00:00:00 GMT-08:00 21", c.getTime().toString()); + assertEquals("1 Jan 21 08:00:00 GMT", c.getTime().toGMTString()); + c.set(Calendar.YEAR, 321); + assertEquals("Sun Jan 01 00:00:00 GMT-08:00 321", c.getTime().toString()); + assertEquals("1 Jan 321 08:00:00 GMT", c.getTime().toGMTString()); + } } diff --git a/luni/src/test/java/libcore/java/util/OldTimeZoneTest.java b/luni/src/test/java/libcore/java/util/OldTimeZoneTest.java index 93bd028..ecf2e5f 100644 --- a/luni/src/test/java/libcore/java/util/OldTimeZoneTest.java +++ b/luni/src/test/java/libcore/java/util/OldTimeZoneTest.java @@ -25,7 +25,7 @@ import junit.framework.TestCase; public class OldTimeZoneTest extends TestCase { - class Mock_TimeZone extends TimeZone { + static class Mock_TimeZone extends TimeZone { @Override public int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds) { return 0; @@ -91,29 +91,50 @@ public class OldTimeZoneTest extends TestCase { public void test_getDisplayNameLjava_util_Locale() { TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); - assertEquals("Pacific Standard Time", tz.getDisplayName(new Locale("US"))); + assertEquals("Pacific Standard Time", tz.getDisplayName(Locale.US)); assertEquals("heure normale du Pacifique nord-américain", tz.getDisplayName(Locale.FRANCE)); } public void test_getDisplayNameZI() { Locale.setDefault(Locale.US); TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); - assertEquals("PST", tz.getDisplayName(false, 0)); - assertEquals("Pacific Daylight Time", tz.getDisplayName(true, 1)); - assertEquals("Pacific Standard Time", tz.getDisplayName(false, 1)); + assertEquals("PST", tz.getDisplayName(false, TimeZone.SHORT)); + assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG)); + assertEquals("Pacific Standard Time", tz.getDisplayName(false, TimeZone.LONG)); } @AndroidOnly("fail on RI. See comment below") public void test_getDisplayNameZILjava_util_Locale() { TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); - assertEquals("PST", tz.getDisplayName(false, 0, Locale.US)); - assertEquals("Pacific Daylight Time", tz.getDisplayName(true, 1, Locale.US)); - assertEquals("Pacific Standard Time", tz.getDisplayName(false, 1, Locale.UK)); - // RI always returns short time zone name as "PST" - // ICU zone/root.txt patched to allow metazone names. - assertEquals("PST", tz.getDisplayName(false, 0, Locale.FRANCE)); - assertEquals("heure avanc\u00e9e du Pacifique", tz.getDisplayName(true, 1, Locale.FRANCE)); - assertEquals("heure normale du Pacifique nord-américain", tz.getDisplayName(false, 1, Locale.FRANCE)); + assertEquals("Pacific Daylight Time", tz.getDisplayName(true, TimeZone.LONG, Locale.US)); + assertEquals("Pacific Standard Time", tz.getDisplayName(false, TimeZone.LONG, Locale.UK)); + assertEquals("heure avanc\u00e9e du Pacifique", + tz.getDisplayName(true, TimeZone.LONG, Locale.FRANCE)); + assertEquals("heure normale du Pacifique nord-américain", + tz.getDisplayName(false, TimeZone.LONG, Locale.FRANCE)); + + assertEquals("PDT", tz.getDisplayName(true, TimeZone.SHORT, Locale.US)); + assertEquals("PST", tz.getDisplayName(false, TimeZone.SHORT, Locale.US)); + // RI fails on following lines. RI always returns short time zone name for + // "America/Los_Angeles" as "PST", Android only returns a string if ICU has a translation. + // There is no short time zone name for America/Los_Angeles in French or British English in + // ICU data so an offset is returned instead. + assertEquals("GMT-08:00", tz.getDisplayName(false, TimeZone.SHORT, Locale.FRANCE)); + assertEquals("GMT-07:00", tz.getDisplayName(true, TimeZone.SHORT, Locale.FRANCE)); + assertEquals("GMT-08:00", tz.getDisplayName(false, TimeZone.SHORT, Locale.UK)); + assertEquals("GMT-07:00", tz.getDisplayName(true, TimeZone.SHORT, Locale.UK)); + + // The RI behavior mentioned above does not appear to be because "PST" is a legacy + // three-character timezone supported by the RI: it happens for "Asia/Tehran"/"IRST" too + // (IRST is not a legacy code). The RI may just use a different dataset that has "PST" / + // "IRST" as valid translations (even for scripts like Chinese). + TimeZone iranTz = TimeZone.getTimeZone("Asia/Tehran"); + assertEquals("Iran Summer Time", iranTz.getDisplayName(true, TimeZone.LONG, Locale.UK)); + assertEquals("Iran Daylight Time", iranTz.getDisplayName(true, TimeZone.LONG, Locale.US)); + assertEquals("Iran Standard Time", iranTz.getDisplayName(false, TimeZone.LONG, Locale.UK)); + assertEquals("Iran Standard Time", iranTz.getDisplayName(false, TimeZone.LONG, Locale.US)); + assertEquals("GMT+03:30", iranTz.getDisplayName(false, TimeZone.SHORT, Locale.UK)); + assertEquals("GMT+04:30", iranTz.getDisplayName(true, TimeZone.SHORT, Locale.UK)); } public void test_getID() { diff --git a/luni/src/test/java/libcore/java/util/TimeZoneTest.java b/luni/src/test/java/libcore/java/util/TimeZoneTest.java index 08d1e69..86a8b7f 100644 --- a/luni/src/test/java/libcore/java/util/TimeZoneTest.java +++ b/luni/src/test/java/libcore/java/util/TimeZoneTest.java @@ -57,6 +57,7 @@ public class TimeZoneTest extends TestCase { // http://code.google.com/p/android/issues/detail?id=14395 public void testPreHistoricInDaylightTime() throws Exception { + Locale.setDefault(Locale.US); TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); TimeZone.setDefault(tz); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); |