diff options
author | Elliott Hughes <enh@google.com> | 2013-08-27 14:30:34 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2013-08-27 14:55:28 -0700 |
commit | 482b89bdd3e2069852061909f35823ab7dba844f (patch) | |
tree | 2eee674aa4dbbae6d5df5e32ec862b73519b5f88 | |
parent | 3b91d105cbd66fabcb5f4bf5d7a257cb58364bbb (diff) | |
download | libcore-482b89bdd3e2069852061909f35823ab7dba844f.zip libcore-482b89bdd3e2069852061909f35823ab7dba844f.tar.gz libcore-482b89bdd3e2069852061909f35823ab7dba844f.tar.bz2 |
Fix German date parsing.
CLDR changed German from having a mix of 3- and 4-character abbreviated month
names (such as "Juli" and "Aug"[ust]) to having only 4-character names by
adding periods to the end of abbreviated names (giving "Juli" and "Aug.").
This means that a date formatted with the old data (by jb-mr1, say) can't
be parsed with the new data (in jb-mr2, say). Work around this by doing what
icu4c's SimpleDateFormat::parse does --- accepting "xxx" as a match for "xxx.".
Bug: https://code.google.com/p/android/issues/detail?id=59383
Bug: 10511599
(cherry picked from commit df0ad3c0e7a4b15fc7ac16b7aaf6be3e7acfa309)
Change-Id: Iefa65f8399a5657f7060d40baab43f909d4b0481
-rw-r--r-- | luni/src/main/java/java/text/SimpleDateFormat.java | 35 | ||||
-rw-r--r-- | luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java | 7 |
2 files changed, 31 insertions, 11 deletions
diff --git a/luni/src/main/java/java/text/SimpleDateFormat.java b/luni/src/main/java/java/text/SimpleDateFormat.java index 04287ae..ea90bbb 100644 --- a/luni/src/main/java/java/text/SimpleDateFormat.java +++ b/luni/src/main/java/java/text/SimpleDateFormat.java @@ -1130,22 +1130,35 @@ public class SimpleDateFormat extends DateFormat { return position.getIndex(); } - private int parseText(String string, int offset, String[] text, int field) { - int found = -1; - for (int i = 0; i < text.length; i++) { - if (text[i].isEmpty()) { + private int parseText(String string, int offset, String[] options, int field) { + // We search for the longest match, in case some entries are substrings of others. + int bestIndex = -1; + int bestLength = -1; + for (int i = 0; i < options.length; ++i) { + String option = options[i]; + int optionLength = option.length(); + if (optionLength == 0) { continue; } - if (string.regionMatches(true, offset, text[i], 0, text[i].length())) { - // Search for the longest match, in case some fields are subsets - if (found == -1 || text[i].length() > text[found].length()) { - found = i; + if (string.regionMatches(true, offset, option, 0, optionLength)) { + if (bestIndex == -1 || optionLength > bestLength) { + bestIndex = i; + bestLength = optionLength; + } + } else if (option.charAt(optionLength - 1) == '.') { + // If CLDR has abbreviated forms like "Aug.", we should accept "Aug" too. + // https://code.google.com/p/android/issues/detail?id=59383 + if (string.regionMatches(true, offset, option, 0, optionLength - 1)) { + if (bestIndex == -1 || optionLength - 1 > bestLength) { + bestIndex = i; + bestLength = optionLength - 1; + } } } } - if (found != -1) { - calendar.set(field, found); - return offset + text[found].length(); + if (bestIndex != -1) { + calendar.set(field, bestIndex); + return offset + bestLength; } return -offset - 1; } diff --git a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java index 21d7302..2813cee 100644 --- a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java +++ b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java @@ -346,4 +346,11 @@ public class SimpleDateFormatTest extends junit.framework.TestCase { Date d2 = sdf.parse(formatted); assertEquals(d, d2); } + + public void test_59383() throws Exception { + SimpleDateFormat sdf = new SimpleDateFormat("d. MMM yyyy H:mm", Locale.GERMAN); + sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); + assertEquals(1376927400000L, sdf.parse("19. Aug 2013 8:50").getTime()); + assertEquals(1376927400000L, sdf.parse("19. Aug. 2013 8:50").getTime()); + } } |