From d515102c5ac23170d3ebfcd263678ca64f8d4b71 Mon Sep 17 00:00:00 2001 From: Peter Edberg Date: Fri, 23 Jun 2017 05:02:12 +0000 Subject: [PATCH] ICU-13215 DayPeriodRules.getInstance should ignore keywords to get correct data and not hang X-SVN-Rev: 40196 --- icu4c/source/i18n/dayperiodrules.cpp | 2 +- icu4c/source/test/intltest/dtfmttst.cpp | 9 +++++++++ .../core/src/com/ibm/icu/impl/DayPeriodRules.java | 2 +- .../src/com/ibm/icu/dev/test/format/DateFormatTest.java | 8 ++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/icu4c/source/i18n/dayperiodrules.cpp b/icu4c/source/i18n/dayperiodrules.cpp index f7ec1e6dc2d..e364ecb708c 100644 --- a/icu4c/source/i18n/dayperiodrules.cpp +++ b/icu4c/source/i18n/dayperiodrules.cpp @@ -340,7 +340,7 @@ const DayPeriodRules *DayPeriodRules::getInstance(const Locale &locale, UErrorCo // does), return NULL. if(U_FAILURE(errorCode)) { return NULL; } - const char *localeCode = locale.getName(); + const char *localeCode = locale.getBaseName(); char name[ULOC_FULLNAME_CAPACITY]; char parentName[ULOC_FULLNAME_CAPACITY]; diff --git a/icu4c/source/test/intltest/dtfmttst.cpp b/icu4c/source/test/intltest/dtfmttst.cpp index ba0929f2ddf..a782bdfaa2f 100644 --- a/icu4c/source/test/intltest/dtfmttst.cpp +++ b/icu4c/source/test/intltest/dtfmttst.cpp @@ -5251,6 +5251,15 @@ void DateFormatTest::TestDayPeriodWithLocales() { sdf.applyPattern(UnicodeString("hh:mm:ss BBBB")); assertEquals("hh:mm:ss BBBB | 01:00:00 | es", "01:00:00 de la madrugada", sdf.format(k010000, out.remove())); + + // #13215: for locales with keywords, check hang in DayPeriodRules""getInstance(const Locale, ...), + // which is called in SimpleDateFormat::format for patterns that include 'B'. + sdf = SimpleDateFormat(UnicodeString(), Locale("en@calendar=buddhist"), errorCode); + sdf.setTimeZone(*tz); + + sdf.applyPattern(UnicodeString("hh:mm:ss BBBB")); + assertEquals("hh:mm:ss BBBB | 01:00:00 | en@calendar=buddhist", "01:00:00 at night", + sdf.format(k010000, out.remove())); } void DateFormatTest::TestMinuteSecondFieldsInOddPlaces() { diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/DayPeriodRules.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/DayPeriodRules.java index dc60c6059bd..8eec59256dd 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/DayPeriodRules.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/DayPeriodRules.java @@ -242,7 +242,7 @@ public final class DayPeriodRules { * @return a DayPeriodRules object for `locale`. */ public static DayPeriodRules getInstance(ULocale locale) { - String localeCode = locale.getName(); + String localeCode = locale.getBaseName(); if (localeCode.isEmpty()) { localeCode = "root"; } Integer ruleSetNum = null; diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java index 63a55504cae..c3de66d88d7 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/DateFormatTest.java @@ -5195,6 +5195,14 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk { sdf.applyPattern("hh:mm:ss BBBB"); assertEquals("hh:mm:ss BBBB | 01:00:00 | es", "01:00:00 de la madrugada", sdf.format(k010000)); + + // #13215: for locales with keywords, check hang in DayPeriodRules.getInstance(ULocale), + // which is called in SimpleDateFormat.format for patterns that include 'B'. + sdf = new SimpleDateFormat("", new ULocale("en@calendar=buddhist")); + sdf.setTimeZone(TimeZone.GMT_ZONE); + + sdf.applyPattern("hh:mm:ss BBBB"); + assertEquals("hh:mm:ss BBBB | 01:00:00 | en@calendar=buddhist", "01:00:00 at night", sdf.format(k010000)); } @Test