summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--luni/src/main/java/java/text/SimpleDateFormat.java31
-rw-r--r--luni/src/main/java/libcore/icu/ICU.java39
-rw-r--r--luni/src/test/java/libcore/icu/ICUTest.java133
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 e904dc8..04287ae 100644
--- a/luni/src/main/java/java/text/SimpleDateFormat.java
+++ b/luni/src/main/java/java/text/SimpleDateFormat.java
@@ -250,22 +250,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
@@ -285,7 +269,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) {
@@ -302,21 +286,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) {
@@ -324,6 +308,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) {
}
+ }
}