mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 17:01:16 +00:00
ICU-20739 Force seconds if the skeleton has fractional seconds
This commit is contained in:
parent
cfb298f035
commit
17d23d71c0
4 changed files with 81 additions and 1 deletions
icu4c/source
icu4j/main
classes/core/src/com/ibm/icu/text
tests/core/src/com/ibm/icu/dev/test/format
|
@ -2162,6 +2162,25 @@ DateTimeMatcher::set(const UnicodeString& pattern, FormatParser* fp, PtnSkeleton
|
|||
}
|
||||
skeletonResult.type[field] = subField;
|
||||
}
|
||||
|
||||
// #20739, we have a skeleton with milliseconde, but no seconds
|
||||
if (!skeletonResult.original.isFieldEmpty(UDATPG_FRACTIONAL_SECOND_FIELD)
|
||||
&& skeletonResult.original.isFieldEmpty(UDATPG_SECOND_FIELD)) {
|
||||
// Force the use of seconds
|
||||
for (i = 0; dtTypes[i].patternChar != 0; i++) {
|
||||
if (dtTypes[i].field == UDATPG_SECOND_FIELD) {
|
||||
// first entry for UDATPG_SECOND_FIELD
|
||||
skeletonResult.original.populate(UDATPG_SECOND_FIELD, dtTypes[i].patternChar, dtTypes[i].minLen);
|
||||
skeletonResult.baseOriginal.populate(UDATPG_SECOND_FIELD, dtTypes[i].patternChar, dtTypes[i].minLen);
|
||||
// We add value.length, same as above, when type is first initialized.
|
||||
// The value we want to "fake" here is "s", and 1 means "s".length()
|
||||
int16_t subField = dtTypes[i].type;
|
||||
skeletonResult.type[UDATPG_SECOND_FIELD] = (subField > 0) ? subField + 1 : subField;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #13183, handle special behavior for day period characters (a, b, B)
|
||||
if (!skeletonResult.original.isFieldEmpty(UDATPG_HOUR_FIELD)) {
|
||||
if (skeletonResult.original.getFieldChar(UDATPG_HOUR_FIELD)==LOW_H || skeletonResult.original.getFieldChar(UDATPG_HOUR_FIELD)==CAP_K) {
|
||||
|
|
|
@ -4912,7 +4912,22 @@ void DateFormatTest::TestPatternFromSkeleton() {
|
|||
{Locale::getEnglish(), "jjmm", "h:mm a"},
|
||||
{Locale::getEnglish(), "JJmm", "hh:mm"},
|
||||
{Locale::getGerman(), "jjmm", "HH:mm"},
|
||||
{Locale::getGerman(), "JJmm", "HH:mm"}
|
||||
{Locale::getGerman(), "JJmm", "HH:mm"},
|
||||
// Ticket #20739
|
||||
{Locale::getEnglish(), "SSSSm", "mm:ss.SSSS"},
|
||||
{Locale::getEnglish(), "mSSSS", "mm:ss.SSSS"},
|
||||
{Locale::getEnglish(), "SSSm", "mm:ss.SSS"},
|
||||
{Locale::getEnglish(), "mSSS", "mm:ss.SSS"},
|
||||
{Locale::getEnglish(), "SSm", "mm:ss.SS"},
|
||||
{Locale::getEnglish(), "mSS", "mm:ss.SS"},
|
||||
{Locale::getEnglish(), "Sm", "mm:ss.S"},
|
||||
{Locale::getEnglish(), "mS", "mm:ss.S"},
|
||||
{Locale::getEnglish(), "S", "S"},
|
||||
{Locale::getEnglish(), "SS", "SS"},
|
||||
{Locale::getEnglish(), "SSS", "SSS"},
|
||||
{Locale::getEnglish(), "SSSS", "SSSS"},
|
||||
{Locale::getEnglish(), "jmsSSS", "h:mm:ss.SSS a"},
|
||||
{Locale::getEnglish(), "jmSSS", "h:mm:ss.SSS a"}
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < UPRV_LENGTHOF(TESTDATA); i++) {
|
||||
|
|
|
@ -2649,6 +2649,25 @@ public class DateTimePatternGenerator implements Freezable<DateTimePatternGenera
|
|||
if (subField > 0) subField += value.length();
|
||||
type[field] = subField;
|
||||
}
|
||||
|
||||
// #20739, we have a skeleton with milliseconde, but no seconds
|
||||
if (!original.isFieldEmpty(FRACTIONAL_SECOND) && original.isFieldEmpty(SECOND)) {
|
||||
// Force the use of seconds
|
||||
for (int i = 0; i < types.length; ++i) {
|
||||
int[] row = types[i];
|
||||
if (row[1] == SECOND) {
|
||||
// first entry for SECOND
|
||||
original.populate(SECOND, (char)row[0], row[3]);
|
||||
baseOriginal.populate(SECOND, (char)row[0], row[3]);
|
||||
// We add value.length, same as above, when type is first initialized.
|
||||
// The value we want to "fake" here is "s", and 1 means "s".length()
|
||||
int subField = row[2];
|
||||
type[SECOND] = (subField > 0) ? subField + 1 : subField;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #13183, handle special behavior for day period characters (a, b, B)
|
||||
if (!original.isFieldEmpty(HOUR)) {
|
||||
if (original.getFieldChar(HOUR)=='h' || original.getFieldChar(HOUR)=='K') {
|
||||
|
|
|
@ -5431,4 +5431,31 @@ public class DateFormatTest extends TestFmwk {
|
|||
dfmt.parse(inDate, pos);
|
||||
assertEquals("Error index", inDate.length(), pos.getErrorIndex());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test20739_MillisecondsWithoutSeconds() {
|
||||
String[][] cases = new String[][]{
|
||||
{"SSSSm", "mm:ss.SSSS"},
|
||||
{"mSSSS", "mm:ss.SSSS"},
|
||||
{"SSSm", "mm:ss.SSS"},
|
||||
{"mSSS", "mm:ss.SSS"},
|
||||
{"SSm", "mm:ss.SS"},
|
||||
{"mSS", "mm:ss.SS"},
|
||||
{"Sm", "mm:ss.S"},
|
||||
{"mS", "mm:ss.S"},
|
||||
{"S", "S"},
|
||||
{"SS", "SS"},
|
||||
{"SSS", "SSS"},
|
||||
{"SSSS", "SSSS"},
|
||||
{"jmsSSS", "h:mm:ss.SSS a"},
|
||||
{"jmSSS", "h:mm:ss.SSS a"}
|
||||
};
|
||||
|
||||
ULocale locale = ULocale.ENGLISH;
|
||||
for (String[] cas : cases) {
|
||||
DateFormat fmt = DateFormat.getInstanceForSkeleton( cas[0], locale);
|
||||
String pattern = ((SimpleDateFormat) fmt).toPattern();
|
||||
assertEquals("Format pattern", cas[1], pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue