ICU-20205 RelativeDateTimeFormatter pt data fix, improved error handling and test. (#210) * ICU-20205 Add locale test for RelativeDateTimeFormatter. * ICU-20205 Fix error in pt relative date data. Improve error handling in code. * ICU-20205 Add instantiation test & regen data from ICU4C * ICU-20205 Added DateFormatSymbols error check per jefgen's comments. (cherry picked from commit e509105c9b07912562481149aaa1da23c8170548)
diff --git a/icu4c/source/data/locales/pt.txt b/icu4c/source/data/locales/pt.txt index b3c8e5d..bb63cb7 100644 --- a/icu4c/source/data/locales/pt.txt +++ b/icu4c/source/data/locales/pt.txt
@@ -2000,7 +2000,7 @@ } past{ one{"há {0} segunda-feira"} - other{"{{0} segundas-feiras atrás"} + other{"{0} segundas-feiras atrás"} } } }
diff --git a/icu4c/source/i18n/reldatefmt.cpp b/icu4c/source/i18n/reldatefmt.cpp index 0af9b47..1a4da0f 100644 --- a/icu4c/source/i18n/reldatefmt.cpp +++ b/icu4c/source/i18n/reldatefmt.cpp
@@ -605,8 +605,14 @@ static void loadWeekdayNames(UnicodeString absoluteUnits[UDAT_STYLE_COUNT] [UDAT_ABSOLUTE_UNIT_COUNT][UDAT_DIRECTION_COUNT], const char* localeId, UErrorCode& status) { + if (U_FAILURE(status)) { + return; + } Locale locale(localeId); DateFormatSymbols dfSym(locale, status); + if (U_FAILURE(status)) { + return; + } for (int32_t style = 0; style < UDAT_STYLE_COUNT; ++style) { DateFormatSymbols::DtWidthType dtfmtWidth = styleToDateFormatSymbolWidth[style]; int32_t count; @@ -630,6 +636,9 @@ static UBool loadUnitData( RelDateTimeFmtDataSink sink(cacheData); ures_getAllItemsWithFallback(resource, "fields", sink, status); + if (U_FAILURE(status)) { + return false; + } // Get the weekday names from DateFormatSymbols. loadWeekdayNames(cacheData.absoluteUnits, localeId, status);
diff --git a/icu4c/source/test/intltest/reldatefmttest.cpp b/icu4c/source/test/intltest/reldatefmttest.cpp index 65969e4..4481f42 100644 --- a/icu4c/source/test/intltest/reldatefmttest.cpp +++ b/icu4c/source/test/intltest/reldatefmttest.cpp
@@ -10,8 +10,10 @@ * ******************************************************************************* */ +#include <memory> #include <stdio.h> #include <stdlib.h> +#include <vector> #include "intltest.h" @@ -765,6 +767,7 @@ class RelativeDateTimeFormatterTest : public IntlTest { void TestBadDisplayContext(); void TestFormat(); void TestFormatNumeric(); + void TestLocales(); void RunTest( const Locale& locale, const WithQuantityExpected* expectedResults, @@ -854,6 +857,7 @@ void RelativeDateTimeFormatterTest::runIndexedTest( TESTCASE_AUTO(TestSidewaysDataLoading); TESTCASE_AUTO(TestFormat); TESTCASE_AUTO(TestFormatNumeric); + TESTCASE_AUTO(TestLocales); TESTCASE_AUTO_END; } @@ -1296,6 +1300,19 @@ void RelativeDateTimeFormatterTest::TestFormat() { RunTest("en", kEnglishFormat, UPRV_LENGTHOF(kEnglishFormat), false); } +void RelativeDateTimeFormatterTest::TestLocales() { + int32_t numLocales = 0; + const Locale *availableLocales = Locale::getAvailableLocales(numLocales); + std::vector<std::unique_ptr<RelativeDateTimeFormatter>> allFormatters; + for (int localeIdx=0; localeIdx<numLocales; localeIdx++) { + const Locale &loc = availableLocales[localeIdx]; + UErrorCode status = U_ZERO_ERROR; + std::unique_ptr<RelativeDateTimeFormatter> rdtf(new RelativeDateTimeFormatter(loc, status)); + allFormatters.push_back(std::move(rdtf)); + assertSuccess(loc.getName(), status); + } +} + static const char *kLast2 = "Last_2"; static const char *kLast = "Last"; static const char *kThis = "This";
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/RelativeDateTimeFormatter.java b/icu4j/main/classes/core/src/com/ibm/icu/text/RelativeDateTimeFormatter.java index df61c84..6e90d41 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/RelativeDateTimeFormatter.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/RelativeDateTimeFormatter.java
@@ -970,9 +970,9 @@ private static final DateTimeUnit orNullFromString(CharSequence keyword) { } EnumMap<Style, EnumMap<AbsoluteUnit, EnumMap<Direction, String>>> qualitativeUnitMap = - new EnumMap<Style, EnumMap<AbsoluteUnit, EnumMap<Direction, String>>>(Style.class); + new EnumMap<>(Style.class); EnumMap<Style, EnumMap<RelativeUnit, String[][]>> styleRelUnitPatterns = - new EnumMap<Style, EnumMap<RelativeUnit, String[][]>>(Style.class); + new EnumMap<>(Style.class); StringBuilder sb = new StringBuilder(); @@ -1023,7 +1023,7 @@ public void consumeTableRelative(UResource.Key key, UResource.Value value) { // Handle Zero seconds for "now". EnumMap<Direction, String> unitStrings = absMap.get(AbsoluteUnit.NOW); if (unitStrings == null) { - unitStrings = new EnumMap<Direction, String>(Direction.class); + unitStrings = new EnumMap<>(Direction.class); absMap.put(AbsoluteUnit.NOW, unitStrings); } if (unitStrings.get(Direction.PLAIN) == null) { @@ -1042,12 +1042,12 @@ public void consumeTableRelative(UResource.Key key, UResource.Value value) { } if (absMap == null) { - absMap = new EnumMap<AbsoluteUnit, EnumMap<Direction, String>>(AbsoluteUnit.class); + absMap = new EnumMap<>(AbsoluteUnit.class); qualitativeUnitMap.put(style, absMap); } EnumMap<Direction, String> dirMap = absMap.get(absUnit); if (dirMap == null) { - dirMap = new EnumMap<Direction, String>(Direction.class); + dirMap = new EnumMap<>(Direction.class); absMap.put(absUnit, dirMap); } if (dirMap.get(keyDirection) == null) { @@ -1082,7 +1082,7 @@ public void consumeTimeDetail(UResource.Key key, UResource.Value value) { EnumMap<RelativeUnit, String[][]> unitPatterns = styleRelUnitPatterns.get(style); if (unitPatterns == null) { - unitPatterns = new EnumMap<RelativeUnit, String[][]>(RelativeUnit.class); + unitPatterns = new EnumMap<>(RelativeUnit.class); styleRelUnitPatterns.put(style, unitPatterns); } String[][] patterns = unitPatterns.get(unit.relUnit); @@ -1112,12 +1112,12 @@ private void handlePlainDirection(UResource.Key key, UResource.Value value) { EnumMap<AbsoluteUnit, EnumMap<Direction, String>> unitMap = qualitativeUnitMap.get(style); if (unitMap == null) { - unitMap = new EnumMap<AbsoluteUnit, EnumMap<Direction, String>>(AbsoluteUnit.class); + unitMap = new EnumMap<>(AbsoluteUnit.class); qualitativeUnitMap.put(style, unitMap); } EnumMap<Direction,String> dirMap = unitMap.get(absUnit); if (dirMap == null) { - dirMap = new EnumMap<Direction,String>(Direction.class); + dirMap = new EnumMap<>(Direction.class); unitMap.put(absUnit, dirMap); } if (dirMap.get(Direction.PLAIN) == null) {
diff --git a/icu4j/main/shared/data/icudata.jar b/icu4j/main/shared/data/icudata.jar index 57a2a86..2d6f0c1 100644 --- a/icu4j/main/shared/data/icudata.jar +++ b/icu4j/main/shared/data/icudata.jar
@@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:605d9be70f081c26ec0c632d4a73a121a2c80f8b5cc1d8da265458264c5474e1 -size 12683589 +oid sha256:7000d5c698e9d3ec24a866694d719a51cbfe4929220c1c3043f4405eeb33f288 +size 12683583
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java index 7abe32a..5e18667 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java
@@ -973,4 +973,13 @@ public void TestSidewaysDataLoading() { String w = fmt.format(6.0, Direction.NEXT, RelativeUnit.QUARTERS); assertEquals("narrow: in 6 qtr", "in 6 qtr", w); } + +@Test +public void TestLocales() { + ULocale[] availableLocales = ULocale.getAvailableLocales(); + for (ULocale loc: availableLocales) { + RelativeDateTimeFormatter.getInstance(loc); + } +} + }