mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-16 18:25:57 +00:00
ICU-21984 Fix DateIntervalFormat.normalizeHourMetacharacters() so that it doesn't require the hour and day-period
fields to appear in any particular order or position in the skeleton string.
This commit is contained in:
parent
c205e7ee49
commit
131146a5f4
4 changed files with 63 additions and 59 deletions
|
@ -966,23 +966,26 @@ DateIntervalFormat::normalizeHourMetacharacters(const UnicodeString& skeleton) c
|
|||
|
||||
UChar hourMetachar = u'\0';
|
||||
UChar dayPeriodChar = u'\0';
|
||||
int32_t metacharStart = 0;
|
||||
int32_t metacharCount = 0;
|
||||
int32_t hourFieldStart = 0;
|
||||
int32_t hourFieldLength = 0;
|
||||
int32_t dayPeriodStart = 0;
|
||||
int32_t dayPeriodLength = 0;
|
||||
for (int32_t i = 0; i < result.length(); i++) {
|
||||
UChar c = result[i];
|
||||
if (c == LOW_J || c == CAP_J || c == CAP_C || c == LOW_H || c == CAP_H || c == LOW_K || c == CAP_K) {
|
||||
if (hourMetachar == u'\0') {
|
||||
hourMetachar = c;
|
||||
metacharStart = i;
|
||||
hourFieldStart = i;
|
||||
}
|
||||
++metacharCount;
|
||||
++hourFieldLength;
|
||||
} else if (c == LOW_A || c == LOW_B || c == CAP_B) {
|
||||
if (dayPeriodChar == u'\0') {
|
||||
dayPeriodChar = c;
|
||||
dayPeriodStart = i;
|
||||
}
|
||||
++metacharCount;
|
||||
++dayPeriodLength;
|
||||
} else {
|
||||
if (hourMetachar != u'\0') {
|
||||
if (hourMetachar != u'\0' && dayPeriodChar != u'\0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1022,31 +1025,27 @@ DateIntervalFormat::normalizeHourMetacharacters(const UnicodeString& skeleton) c
|
|||
}
|
||||
}
|
||||
|
||||
if (hourChar == CAP_H || hourChar == LOW_K) {
|
||||
result.replace(metacharStart, metacharCount, hourChar);
|
||||
} else {
|
||||
UnicodeString hourAndDayPeriod(hourChar);
|
||||
switch (metacharCount) {
|
||||
case 1:
|
||||
case 2:
|
||||
default:
|
||||
hourAndDayPeriod.append(UnicodeString(dayPeriodChar));
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
for (int32_t i = 0; i < 4; i++) {
|
||||
hourAndDayPeriod.append(dayPeriodChar);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
for (int32_t i = 0; i < 5; i++) {
|
||||
hourAndDayPeriod.append(dayPeriodChar);
|
||||
}
|
||||
break;
|
||||
UnicodeString hourAndDayPeriod(hourChar);
|
||||
if (hourChar != CAP_H && hourChar != LOW_K) {
|
||||
int32_t newDayPeriodLength = 0;
|
||||
if (dayPeriodLength >= 5 || hourFieldLength >= 5) {
|
||||
newDayPeriodLength = 5;
|
||||
} else if (dayPeriodLength >= 3 || hourFieldLength >= 3) {
|
||||
newDayPeriodLength = 3;
|
||||
} else {
|
||||
newDayPeriodLength = 1;
|
||||
}
|
||||
for (int32_t i = 0; i < newDayPeriodLength; i++) {
|
||||
hourAndDayPeriod.append(dayPeriodChar);
|
||||
}
|
||||
result.replace(metacharStart, metacharCount, hourAndDayPeriod);
|
||||
}
|
||||
result.replace(hourFieldStart, hourFieldLength, hourAndDayPeriod);
|
||||
if (dayPeriodStart > hourFieldStart) {
|
||||
// before deleting the original day period field, adjust its position in case
|
||||
// we just changed the size of the hour field (and new day period field)
|
||||
dayPeriodStart += hourAndDayPeriod.length() - hourFieldLength;
|
||||
}
|
||||
result.remove(dayPeriodStart, dayPeriodLength);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1194,6 +1194,10 @@ void DateIntervalFormatTest::testHourMetacharacters() {
|
|||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "12 \\u2013 1 AM", // (this was producing "0 - 1 AM" before)
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 00:00:00", "jj", "12 AM",
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jj", "12 \\u2013 1 AM",
|
||||
|
||||
// regression test for ICU-21984 (multiple day-period characters in date-interval patterns)
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "MMMdhhmma", "Sep 27, 12:00 \\u2013 1:00 AM",
|
||||
"sq", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "Bhm", "12:00 \\u2013 1:00 e nat\\u00EBs",
|
||||
};
|
||||
expect(DATA, UPRV_LENGTHOF(DATA));
|
||||
}
|
||||
|
|
|
@ -1616,23 +1616,26 @@ public class DateIntervalFormat extends UFormat {
|
|||
|
||||
char hourMetachar = '\0';
|
||||
char dayPeriodChar = '\0';
|
||||
int metacharStart = 0;
|
||||
int metacharCount = 0;
|
||||
int hourFieldStart = 0;
|
||||
int hourFieldLength = 0;
|
||||
int dayPeriodStart = 0;
|
||||
int dayPeriodLength = 0;
|
||||
for (int i = 0; i < result.length(); i++) {
|
||||
char c = result.charAt(i);
|
||||
if (c == 'j' || c == 'J' || c == 'C' || c == 'h' || c == 'H' || c == 'k' || c == 'K') {
|
||||
if (hourMetachar == '\0') {
|
||||
hourMetachar = c;
|
||||
metacharStart = i;
|
||||
hourFieldStart = i;
|
||||
}
|
||||
++metacharCount;
|
||||
++hourFieldLength;
|
||||
} else if (c == 'a' || c == 'b' || c == 'B') {
|
||||
if (dayPeriodChar == '\0') {
|
||||
dayPeriodChar = c;
|
||||
dayPeriodStart = i;
|
||||
}
|
||||
++metacharCount;
|
||||
++dayPeriodLength;
|
||||
} else {
|
||||
if (hourMetachar != '\0') {
|
||||
if (hourMetachar != '\0' && dayPeriodChar != '\0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1671,32 +1674,26 @@ public class DateIntervalFormat extends UFormat {
|
|||
dayPeriodChar = 'a';
|
||||
}
|
||||
|
||||
if (hourChar == 'H' || hourChar == 'k') {
|
||||
result.replace(metacharStart, metacharStart + metacharCount, String.valueOf(hourChar));
|
||||
} else {
|
||||
StringBuilder hourAndDayPeriod = new StringBuilder();
|
||||
hourAndDayPeriod.append(hourChar);
|
||||
switch (metacharCount) {
|
||||
case 1:
|
||||
case 2:
|
||||
default:
|
||||
hourAndDayPeriod.append(dayPeriodChar);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
for (int i = 0; i < 4; i++) {
|
||||
hourAndDayPeriod.append(dayPeriodChar);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
for (int i = 0; i < 5; i++) {
|
||||
hourAndDayPeriod.append(dayPeriodChar);
|
||||
}
|
||||
break;
|
||||
StringBuilder hourAndDayPeriod = new StringBuilder();
|
||||
hourAndDayPeriod.append(hourChar);
|
||||
if (hourChar != 'H' && hourChar != 'k') {
|
||||
int newDayPeriodLength = 0;
|
||||
if (dayPeriodLength >= 5 || hourFieldLength >= 5) {
|
||||
newDayPeriodLength = 5;
|
||||
} else if (dayPeriodLength >= 3 || hourFieldLength >= 3) {
|
||||
newDayPeriodLength = 3;
|
||||
} else {
|
||||
newDayPeriodLength = 1;
|
||||
}
|
||||
for (int i = 0; i < newDayPeriodLength; i++) {
|
||||
hourAndDayPeriod.append(dayPeriodChar);
|
||||
}
|
||||
result.replace(metacharStart, metacharStart + metacharCount, hourAndDayPeriod.toString());
|
||||
}
|
||||
result.replace(hourFieldStart, hourFieldStart + hourFieldLength, hourAndDayPeriod.toString());
|
||||
if (dayPeriodStart > hourFieldStart) {
|
||||
dayPeriodStart += hourAndDayPeriod.length() - hourFieldLength;
|
||||
}
|
||||
result.delete(dayPeriodStart, dayPeriodStart + dayPeriodLength);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
|
|
@ -839,6 +839,10 @@ public class DateIntervalFormatTest extends TestFmwk {
|
|||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "KK", "12 \\u2013 1 AM", // (this was producing "0 - 1 AM" before)
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 00:00:00", "jj", "12 AM",
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "jj", "12 \\u2013 1 AM",
|
||||
|
||||
// regression test for ICU-21984 (multiple day-period characters in date-interval patterns)
|
||||
"en", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "MMMdhhmma", "Sep 27, 12:00 \\u2013 1:00 AM",
|
||||
"sq", "CE 2010 09 27 00:00:00", "CE 2010 09 27 01:00:00", "Bhm", "12:00 \\u2013 1:00 e nat\\u00EBs",
|
||||
};
|
||||
expect(DATA, DATA.length);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue