fields to appear in any particular order or position in the skeleton string.
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;
}
}
}
}
- 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;
}
- result.replace(metacharStart, metacharCount, hourAndDayPeriod);
+ for (int32_t i = 0; i < newDayPeriodLength; i++) {
+ hourAndDayPeriod.append(dayPeriodChar);
+ }
+ }
+ 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;
}
"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));
}
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;
}
}
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;
}
- result.replace(metacharStart, metacharStart + metacharCount, hourAndDayPeriod.toString());
+ for (int i = 0; i < newDayPeriodLength; i++) {
+ hourAndDayPeriod.append(dayPeriodChar);
+ }
+ }
+ result.replace(hourFieldStart, hourFieldStart + hourFieldLength, hourAndDayPeriod.toString());
+ if (dayPeriodStart > hourFieldStart) {
+ dayPeriodStart += hourAndDayPeriod.length() - hourFieldLength;
}
+ result.delete(dayPeriodStart, dayPeriodStart + dayPeriodLength);
}
return result.toString();
}
"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);
}