diff options
-rw-r--r-- | luni/src/main/java/java/text/SimpleDateFormat.java | 31 | ||||
-rw-r--r-- | luni/src/main/java/libcore/icu/ICU.java | 39 | ||||
-rw-r--r-- | luni/src/test/java/libcore/icu/ICUTest.java | 133 |
3 files changed, 141 insertions, 62 deletions
diff --git a/luni/src/main/java/java/text/SimpleDateFormat.java b/luni/src/main/java/java/text/SimpleDateFormat.java index 0b3a69e..a757188 100644 --- a/luni/src/main/java/java/text/SimpleDateFormat.java +++ b/luni/src/main/java/java/text/SimpleDateFormat.java @@ -245,22 +245,6 @@ public class SimpleDateFormat extends DateFormat { } /** - * Validates the format character. - * - * @param format - * the format character - * - * @throws IllegalArgumentException - * when the format character is invalid - */ - private void validateFormat(char format) { - int index = PATTERN_CHARS.indexOf(format); - if (index == -1) { - throw new IllegalArgumentException("Unknown pattern character '" + format + "'"); - } - } - - /** * Validates the pattern. * * @param template @@ -280,7 +264,7 @@ public class SimpleDateFormat extends DateFormat { next = (template.charAt(i)); if (next == '\'') { if (count > 0) { - validateFormat((char) last); + validatePatternCharacter((char) last); count = 0; } if (last == next) { @@ -297,21 +281,21 @@ public class SimpleDateFormat extends DateFormat { count++; } else { if (count > 0) { - validateFormat((char) last); + validatePatternCharacter((char) last); } last = next; count = 1; } } else { if (count > 0) { - validateFormat((char) last); + validatePatternCharacter((char) last); count = 0; } last = -1; } } if (count > 0) { - validateFormat((char) last); + validatePatternCharacter((char) last); } if (quote) { @@ -319,6 +303,13 @@ public class SimpleDateFormat extends DateFormat { } } + private void validatePatternCharacter(char format) { + int index = PATTERN_CHARS.indexOf(format); + if (index == -1) { + throw new IllegalArgumentException("Unknown pattern character '" + format + "'"); + } + } + /** * Constructs a new {@code SimpleDateFormat} using the specified * non-localized pattern and {@code DateFormatSymbols} and the {@code diff --git a/luni/src/main/java/libcore/icu/ICU.java b/luni/src/main/java/libcore/icu/ICU.java index 8e0cd0b..6873b0e 100644 --- a/luni/src/main/java/libcore/icu/ICU.java +++ b/luni/src/main/java/libcore/icu/ICU.java @@ -129,6 +129,45 @@ public final class ICU { public static native String getBestDateTimePattern(String skeleton, String localeName); + public static char[] getDateFormatOrder(String pattern) { + char[] result = new char[3]; + int resultIndex = 0; + boolean sawDay = false; + boolean sawMonth = false; + boolean sawYear = false; + + for (int i = 0; i < pattern.length(); ++i) { + char ch = pattern.charAt(i); + if (ch == 'd' || ch == 'L' || ch == 'M' || ch == 'y') { + if (ch == 'd' && !sawDay) { + result[resultIndex++] = 'd'; + sawDay = true; + } else if ((ch == 'L' || ch == 'M') && !sawMonth) { + result[resultIndex++] = 'M'; + sawMonth = true; + } else if ((ch == 'y') && !sawYear) { + result[resultIndex++] = 'y'; + sawYear = true; + } + } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) { + throw new IllegalArgumentException("Bad pattern character '" + ch + "' in " + pattern); + } else if (ch == '\'') { + if (i < pattern.length() - 1 && pattern.charAt(i + 1) == '\'') { + ++i; + } else { + i = pattern.indexOf('\'', i + 1); + if (i == -1) { + throw new IllegalArgumentException("Bad quoting in " + pattern); + } + ++i; + } + } else { + // Ignore spaces and punctuation. + } + } + return result; + } + /** * Returns the version of the CLDR data in use, such as "22.1.1". */ diff --git a/luni/src/test/java/libcore/icu/ICUTest.java b/luni/src/test/java/libcore/icu/ICUTest.java index 9d9892c..7da7519 100644 --- a/luni/src/test/java/libcore/icu/ICUTest.java +++ b/luni/src/test/java/libcore/icu/ICUTest.java @@ -16,58 +16,107 @@ package libcore.icu; +import java.util.Arrays; import java.util.Locale; public class ICUTest extends junit.framework.TestCase { - public void test_getISOLanguages() throws Exception { - // Check that corrupting our array doesn't affect other callers. - assertNotNull(ICU.getISOLanguages()[0]); - ICU.getISOLanguages()[0] = null; - assertNotNull(ICU.getISOLanguages()[0]); - } + public void test_getISOLanguages() throws Exception { + // Check that corrupting our array doesn't affect other callers. + assertNotNull(ICU.getISOLanguages()[0]); + ICU.getISOLanguages()[0] = null; + assertNotNull(ICU.getISOLanguages()[0]); + } - public void test_getISOCountries() throws Exception { - // Check that corrupting our array doesn't affect other callers. - assertNotNull(ICU.getISOCountries()[0]); - ICU.getISOCountries()[0] = null; - assertNotNull(ICU.getISOCountries()[0]); - } + public void test_getISOCountries() throws Exception { + // Check that corrupting our array doesn't affect other callers. + assertNotNull(ICU.getISOCountries()[0]); + ICU.getISOCountries()[0] = null; + assertNotNull(ICU.getISOCountries()[0]); + } + + public void test_getAvailableLocales() throws Exception { + // Check that corrupting our array doesn't affect other callers. + assertNotNull(ICU.getAvailableLocales()[0]); + ICU.getAvailableLocales()[0] = null; + assertNotNull(ICU.getAvailableLocales()[0]); + } + + public void test_getBestDateTimePattern() throws Exception { + assertEquals("d MMMM", ICU.getBestDateTimePattern("MMMMd", "ca_ES")); + assertEquals("d 'de' MMMM", ICU.getBestDateTimePattern("MMMMd", "es_ES")); + assertEquals("d. MMMM", ICU.getBestDateTimePattern("MMMMd", "de_CH")); + assertEquals("MMMM d", ICU.getBestDateTimePattern("MMMMd", "en_US")); + assertEquals("d LLLL", ICU.getBestDateTimePattern("MMMMd", "fa_IR")); + assertEquals("M月d日", ICU.getBestDateTimePattern("MMMMd", "ja_JP")); + } + + public void test_localeFromString() throws Exception { + // localeFromString is pretty lenient. Some of these can't be round-tripped + // through Locale.toString. + assertEquals(Locale.ENGLISH, ICU.localeFromString("en")); + assertEquals(Locale.ENGLISH, ICU.localeFromString("en_")); + assertEquals(Locale.ENGLISH, ICU.localeFromString("en__")); + assertEquals(Locale.US, ICU.localeFromString("en_US")); + assertEquals(Locale.US, ICU.localeFromString("en_US_")); + assertEquals(new Locale("", "US", ""), ICU.localeFromString("_US")); + assertEquals(new Locale("", "US", ""), ICU.localeFromString("_US_")); + assertEquals(new Locale("", "", "POSIX"), ICU.localeFromString("__POSIX")); + assertEquals(new Locale("aa", "BB", "CC"), ICU.localeFromString("aa_BB_CC")); + } + + public void test_getScript_addLikelySubtags() throws Exception { + assertEquals("Latn", ICU.getScript(ICU.addLikelySubtags("en_US"))); + assertEquals("Hebr", ICU.getScript(ICU.addLikelySubtags("he"))); + assertEquals("Hebr", ICU.getScript(ICU.addLikelySubtags("he_IL"))); + assertEquals("Hebr", ICU.getScript(ICU.addLikelySubtags("iw"))); + assertEquals("Hebr", ICU.getScript(ICU.addLikelySubtags("iw_IL"))); + } + + private String best(Locale l, String skeleton) { + return ICU.getBestDateTimePattern(skeleton, l.toString()); + } + + public void test_getDateFormatOrder() throws Exception { + // lv and fa use differing orders depending on whether you're using numeric or textual months. + Locale lv = new Locale("lv"); + assertEquals("[d, M, y]", Arrays.toString(ICU.getDateFormatOrder(best(lv, "yyyy-M-dd")))); + assertEquals("[y, d, M]", Arrays.toString(ICU.getDateFormatOrder(best(lv, "yyyy-MMM-dd")))); + Locale fa = new Locale("fa"); + assertEquals("[y, M, d]", Arrays.toString(ICU.getDateFormatOrder(best(fa, "yyyy-M-dd")))); + assertEquals("[d, M, y]", Arrays.toString(ICU.getDateFormatOrder(best(fa, "yyyy-MMM-dd")))); + + // English differs on each side of the Atlantic. + Locale en_US = Locale.US; + assertEquals("[M, d, y]", Arrays.toString(ICU.getDateFormatOrder(best(en_US, "yyyy-M-dd")))); + assertEquals("[M, d, y]", Arrays.toString(ICU.getDateFormatOrder(best(en_US, "yyyy-MMM-dd")))); + Locale en_GB = Locale.UK; + assertEquals("[d, M, y]", Arrays.toString(ICU.getDateFormatOrder(best(en_GB, "yyyy-M-dd")))); + assertEquals("[d, M, y]", Arrays.toString(ICU.getDateFormatOrder(best(en_GB, "yyyy-MMM-dd")))); + + assertEquals("[y, M, d]", Arrays.toString(ICU.getDateFormatOrder("yyyy - 'why' '' 'ddd' MMM-dd"))); - public void test_getAvailableLocales() throws Exception { - // Check that corrupting our array doesn't affect other callers. - assertNotNull(ICU.getAvailableLocales()[0]); - ICU.getAvailableLocales()[0] = null; - assertNotNull(ICU.getAvailableLocales()[0]); + try { + ICU.getDateFormatOrder("the quick brown fox jumped over the lazy dog"); + fail(); + } catch (IllegalArgumentException expected) { } - public void test_getBestDateTimePattern() throws Exception { - assertEquals("d MMMM", ICU.getBestDateTimePattern("MMMMd", "ca_ES")); - assertEquals("d 'de' MMMM", ICU.getBestDateTimePattern("MMMMd", "es_ES")); - assertEquals("d. MMMM", ICU.getBestDateTimePattern("MMMMd", "de_CH")); - assertEquals("MMMM d", ICU.getBestDateTimePattern("MMMMd", "en_US")); - assertEquals("d LLLL", ICU.getBestDateTimePattern("MMMMd", "fa_IR")); - assertEquals("M月d日", ICU.getBestDateTimePattern("MMMMd", "ja_JP")); + try { + ICU.getDateFormatOrder("'"); + fail(); + } catch (IllegalArgumentException expected) { } - public void test_localeFromString() throws Exception { - // localeFromString is pretty lenient. Some of these can't be round-tripped - // through Locale.toString. - assertEquals(Locale.ENGLISH, ICU.localeFromString("en")); - assertEquals(Locale.ENGLISH, ICU.localeFromString("en_")); - assertEquals(Locale.ENGLISH, ICU.localeFromString("en__")); - assertEquals(Locale.US, ICU.localeFromString("en_US")); - assertEquals(Locale.US, ICU.localeFromString("en_US_")); - assertEquals(new Locale("", "US", ""), ICU.localeFromString("_US")); - assertEquals(new Locale("", "US", ""), ICU.localeFromString("_US_")); - assertEquals(new Locale("", "", "POSIX"), ICU.localeFromString("__POSIX")); - assertEquals(new Locale("aa", "BB", "CC"), ICU.localeFromString("aa_BB_CC")); + try { + ICU.getDateFormatOrder("yyyy'"); + fail(); + } catch (IllegalArgumentException expected) { } - public void test_getScript_addLikelySubtags() throws Exception { - assertEquals("Latn", ICU.getScript(ICU.addLikelySubtags("en_US"))); - assertEquals("Hebr", ICU.getScript(ICU.addLikelySubtags("he"))); - assertEquals("Hebr", ICU.getScript(ICU.addLikelySubtags("he_IL"))); - assertEquals("Hebr", ICU.getScript(ICU.addLikelySubtags("iw"))); - assertEquals("Hebr", ICU.getScript(ICU.addLikelySubtags("iw_IL"))); + try { + ICU.getDateFormatOrder("yyyy'MMM"); + fail(); + } catch (IllegalArgumentException expected) { } + } } |