ICU-21671 Corrected a bug in SimpleDateFormat.subParse() that was causing us to always parse quarter names that begin

with numbers as though the number was the whole quarter name.
This commit is contained in:
Rich Gillam 2021-08-27 17:03:22 -07:00
parent 5b96c2e847
commit 985c05a3ef
2 changed files with 21 additions and 10 deletions
icu4j/main
classes/core/src/com/ibm/icu/text
tests/core/src/com/ibm/icu/dev/test/format

View file

@ -3609,8 +3609,8 @@ public class SimpleDateFormat extends DateFormat {
return ~start;
}
case 27: // 'Q' - QUARTER
if (count <= 2 || (number != null && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC))) {
// i.e., Q or QQ. or lenient & have number
if (count <= 2 && number != null) {
// i.e., Q or QQ.
// Don't want to parse the quarter if it is a string
// while pattern uses numeric style: Q or QQ.
// [We computed 'value' above.]
@ -3634,15 +3634,21 @@ public class SimpleDateFormat extends DateFormat {
}
// count == 3 failed, now try count == 5
if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 5) {
return matchQuarterString(text, start, Calendar.MONTH,
formatData.narrowQuarters, cal);
if ((newStart = matchQuarterString(text, start, Calendar.MONTH, formatData.narrowQuarters, cal)) > 0) {
return newStart;
}
}
// if numeric parsing is on and we got the numeric value already, return it
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC) && number != null) {
cal.set(Calendar.MONTH, (value - 1) * 3);
return pos.getIndex();
}
return newStart;
}
case 28: // 'q' - STANDALONE QUARTER
if (count <= 2 || (number != null && getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC))) {
// i.e., q or qq. or lenient & have number
if (count <= 2 && number != null) {
// i.e., q or qq.
// Don't want to parse the quarter if it is a string
// while pattern uses numeric style: q or qq.
// [We computed 'value' above.]
@ -3666,8 +3672,14 @@ public class SimpleDateFormat extends DateFormat {
}
// count == 3 failed, now try count == 5
if(getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_MULTIPLE_PATTERNS_FOR_MATCH) || count == 5) {
return matchQuarterString(text, start, Calendar.MONTH,
formatData.standaloneNarrowQuarters, cal);
if ((newStart = matchQuarterString(text, start, Calendar.MONTH, formatData.standaloneNarrowQuarters, cal)) > 0) {
return newStart;
}
}
// if numeric parsing is on and we got the numeric value already, return it
if (getBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC) && number != null) {
cal.set(Calendar.MONTH, (value - 1) * 3);
return pos.getIndex();
}
return newStart;
}

View file

@ -3172,8 +3172,7 @@ public class DateFormatTest extends TestFmwk {
String ES_MX_DATA[] = {
"yyyy MM dd",
// Test commented out because of ICU-21671
// "QQQQ y", "fp", "1970 01 01", "1.er trimestre 1970", "1970 01 01",
"QQQQ y", "fp", "1970 01 01", "1.er trimestre 1970", "1970 01 01",
"QQQ y", "fp", "1970 01 01", "T1 1970", "1970 01 01",
"QQQQQ y", "fp", "1970 01 01", "1 1970", "1970 01 01",
"qqqq", "fp", "1970 01 01", "1.er trimestre", "1970 01 01",