Add 'quarter' support to RelativeDateFormat
1. Do not trim 'quarter'-related strings from the locale data
and regenerate the ICU data files.
ICU data file size is increased by 24 ~ 35 kB.
2. Chery-pick upstream patch to support quarter in RelativeDateFormat
upstream bug:
https://unicode-org.atlassian.net/browse/ICU-20022
PR to fix:
https://github.com/unicode-org/icu/pull/77
This will unblock the following CL:
https://chromium-review.googlesource.com/c/v8/v8/+/1214522
TBR=ftang@chromium.org
Bug: v8:7869
Test: See the bug
Change-Id: I11740d9b2a1fdb9b2f7bb497eda2746353fa8428
Reviewed-on: https://chromium-review.googlesource.com/1214642
Reviewed-by: Jungshik Shin <jshin@chromium.org>
diff --git a/README.chromium b/README.chromium
index 287215f..b3e0738 100644
--- a/README.chromium
+++ b/README.chromium
@@ -267,3 +267,10 @@
- patches/decimalformat_align.patch
- upstream bug:
https://unicode-org.atlassian.net/browse/ICU-20039
+
+12. Cherry-pick the upstream CL for quarter support in RelativeDate format
+
+ - patches/reldate_quarter.patch
+ - upstream bug:
+ https://unicode-org.atlassian.net/browse/ICU-20022
+ - fix: https://github.com/unicode-org/icu/pull/77
diff --git a/android/icudtl.dat b/android/icudtl.dat
index d076c78..ec23562 100644
--- a/android/icudtl.dat
+++ b/android/icudtl.dat
Binary files differ
diff --git a/cast/icudtl.dat b/cast/icudtl.dat
index 0c0158c..2240788 100644
--- a/cast/icudtl.dat
+++ b/cast/icudtl.dat
Binary files differ
diff --git a/common/icudtb.dat b/common/icudtb.dat
index 470b9a3..e94ea72 100644
--- a/common/icudtb.dat
+++ b/common/icudtb.dat
Binary files differ
diff --git a/common/icudtl.dat b/common/icudtl.dat
index 4ba503b..4a9d942 100644
--- a/common/icudtl.dat
+++ b/common/icudtl.dat
Binary files differ
diff --git a/flutter/icudtl.dat b/flutter/icudtl.dat
index d9677ab..0a0e10b 100644
--- a/flutter/icudtl.dat
+++ b/flutter/icudtl.dat
Binary files differ
diff --git a/ios/icudtl.dat b/ios/icudtl.dat
index 00b1935..2ad3994 100644
--- a/ios/icudtl.dat
+++ b/ios/icudtl.dat
Binary files differ
diff --git a/patches/reldate_quarter.patch b/patches/reldate_quarter.patch
new file mode 100644
index 0000000..80f1a45
--- /dev/null
+++ b/patches/reldate_quarter.patch
@@ -0,0 +1,542 @@
+diff --git a/icu4c/source/i18n/reldatefmt.cpp b/icu4c/source/i18n/reldatefmt.cpp
+index 0a28a743e2..0af9b47a19 100644
+--- a/icu4c/source/i18n/reldatefmt.cpp
++++ b/icu4c/source/i18n/reldatefmt.cpp
+@@ -51,13 +51,13 @@ U_NAMESPACE_BEGIN
+ // RelativeDateTimeFormatter specific data for a single locale
+ class RelativeDateTimeCacheData: public SharedObject {
+ public:
+- RelativeDateTimeCacheData() : combinedDateAndTime(NULL) {
++ RelativeDateTimeCacheData() : combinedDateAndTime(nullptr) {
+ // Initialize the cache arrays
+ for (int32_t style = 0; style < UDAT_STYLE_COUNT; ++style) {
+- for (int32_t relUnit = 0; relUnit < UDAT_RELATIVE_UNIT_COUNT; ++relUnit) {
++ for (int32_t relUnit = 0; relUnit < UDAT_REL_UNIT_COUNT; ++relUnit) {
+ for (int32_t pl = 0; pl < StandardPlural::COUNT; ++pl) {
+- relativeUnitsFormatters[style][relUnit][0][pl] = NULL;
+- relativeUnitsFormatters[style][relUnit][1][pl] = NULL;
++ relativeUnitsFormatters[style][relUnit][0][pl] = nullptr;
++ relativeUnitsFormatters[style][relUnit][1][pl] = nullptr;
+ }
+ }
+ }
+@@ -74,7 +74,7 @@ class RelativeDateTimeCacheData: public SharedObject {
+ // e.g., Next Tuesday; Yesterday; etc. For third index, 0
+ // means past, e.g., 5 days ago; 1 means future, e.g., in 5 days.
+ SimpleFormatter *relativeUnitsFormatters[UDAT_STYLE_COUNT]
+- [UDAT_RELATIVE_UNIT_COUNT][2][StandardPlural::COUNT];
++ [UDAT_REL_UNIT_COUNT][2][StandardPlural::COUNT];
+
+ const UnicodeString& getAbsoluteUnitString(int32_t fStyle,
+ UDateAbsoluteUnit unit,
+@@ -83,6 +83,10 @@ class RelativeDateTimeCacheData: public SharedObject {
+ UDateRelativeUnit unit,
+ int32_t pastFutureIndex,
+ int32_t pluralUnit) const;
++ const SimpleFormatter* getRelativeDateTimeUnitFormatter(int32_t fStyle,
++ URelativeDateTimeUnit unit,
++ int32_t pastFutureIndex,
++ int32_t pluralUnit) const;
+
+ const UnicodeString emptyString;
+
+@@ -107,7 +111,7 @@ class RelativeDateTimeCacheData: public SharedObject {
+ RelativeDateTimeCacheData::~RelativeDateTimeCacheData() {
+ // clear out the cache arrays
+ for (int32_t style = 0; style < UDAT_STYLE_COUNT; ++style) {
+- for (int32_t relUnit = 0; relUnit < UDAT_RELATIVE_UNIT_COUNT; ++relUnit) {
++ for (int32_t relUnit = 0; relUnit < UDAT_REL_UNIT_COUNT; ++relUnit) {
+ for (int32_t pl = 0; pl < StandardPlural::COUNT; ++pl) {
+ delete relativeUnitsFormatters[style][relUnit][0][pl];
+ delete relativeUnitsFormatters[style][relUnit][1][pl];
+@@ -131,20 +135,41 @@ const UnicodeString& RelativeDateTimeCacheData::getAbsoluteUnitString(
+ return emptyString;
+ }
+
+- // Use fallback cache for SimpleFormatter relativeUnits.
+ const SimpleFormatter* RelativeDateTimeCacheData::getRelativeUnitFormatter(
+ int32_t fStyle,
+ UDateRelativeUnit unit,
+ int32_t pastFutureIndex,
+ int32_t pluralUnit) const {
++ URelativeDateTimeUnit rdtunit = UDAT_REL_UNIT_COUNT;
++ switch (unit) {
++ case UDAT_RELATIVE_YEARS: rdtunit = UDAT_REL_UNIT_YEAR; break;
++ case UDAT_RELATIVE_MONTHS: rdtunit = UDAT_REL_UNIT_MONTH; break;
++ case UDAT_RELATIVE_WEEKS: rdtunit = UDAT_REL_UNIT_WEEK; break;
++ case UDAT_RELATIVE_DAYS: rdtunit = UDAT_REL_UNIT_DAY; break;
++ case UDAT_RELATIVE_HOURS: rdtunit = UDAT_REL_UNIT_HOUR; break;
++ case UDAT_RELATIVE_MINUTES: rdtunit = UDAT_REL_UNIT_MINUTE; break;
++ case UDAT_RELATIVE_SECONDS: rdtunit = UDAT_REL_UNIT_SECOND; break;
++ default: // a unit that the above method does not handle
++ return nullptr;
++ }
++
++ return getRelativeDateTimeUnitFormatter(fStyle, rdtunit, pastFutureIndex, pluralUnit);
++ }
++
++ // Use fallback cache for SimpleFormatter relativeUnits.
++ const SimpleFormatter* RelativeDateTimeCacheData::getRelativeDateTimeUnitFormatter(
++ int32_t fStyle,
++ URelativeDateTimeUnit unit,
++ int32_t pastFutureIndex,
++ int32_t pluralUnit) const {
+ int32_t style = fStyle;
+ do {
+- if (relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit] != NULL) {
++ if (relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit] != nullptr) {
+ return relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit];
+ }
+ style = fallBackCache[style];
+ } while (style != -1);
+- return NULL; // No formatter found.
++ return nullptr; // No formatter found.
+ }
+
+ static UBool getStringWithFallback(
+@@ -217,23 +242,35 @@ struct RelDateTimeFmtDataSink : public ResourceSink {
+ // Converts the generic units to UDAT_RELATIVE version.
+ switch (genUnit) {
+ case SECOND:
+- return UDAT_RELATIVE_SECONDS;
++ return UDAT_REL_UNIT_SECOND;
+ case MINUTE:
+- return UDAT_RELATIVE_MINUTES;
++ return UDAT_REL_UNIT_MINUTE;
+ case HOUR:
+- return UDAT_RELATIVE_HOURS;
++ return UDAT_REL_UNIT_HOUR;
+ case DAY:
+- return UDAT_RELATIVE_DAYS;
++ return UDAT_REL_UNIT_DAY;
+ case WEEK:
+- return UDAT_RELATIVE_WEEKS;
++ return UDAT_REL_UNIT_WEEK;
+ case MONTH:
+- return UDAT_RELATIVE_MONTHS;
+- /*
+- * case QUARTER:
+- * return UDATE_RELATIVE_QUARTERS;
+- */
++ return UDAT_REL_UNIT_MONTH;
++ case QUARTER:
++ return UDAT_REL_UNIT_QUARTER;
+ case YEAR:
+- return UDAT_RELATIVE_YEARS;
++ return UDAT_REL_UNIT_YEAR;
++ case SUNDAY:
++ return UDAT_REL_UNIT_SUNDAY;
++ case MONDAY:
++ return UDAT_REL_UNIT_MONDAY;
++ case TUESDAY:
++ return UDAT_REL_UNIT_TUESDAY;
++ case WEDNESDAY:
++ return UDAT_REL_UNIT_WEDNESDAY;
++ case THURSDAY:
++ return UDAT_REL_UNIT_THURSDAY;
++ case FRIDAY:
++ return UDAT_REL_UNIT_FRIDAY;
++ case SATURDAY:
++ return UDAT_REL_UNIT_SATURDAY;
+ default:
+ return -1;
+ }
+@@ -248,10 +285,8 @@ struct RelDateTimeFmtDataSink : public ResourceSink {
+ return UDAT_ABSOLUTE_WEEK;
+ case MONTH:
+ return UDAT_ABSOLUTE_MONTH;
+- /* TODO: Add in QUARTER
+- * case QUARTER:
+- * return UDAT_ABSOLUTE_QUARTER;
+- */
++ case QUARTER:
++ return UDAT_ABSOLUTE_QUARTER;
+ case YEAR:
+ return UDAT_ABSOLUTE_YEAR;
+ case SUNDAY:
+@@ -430,7 +465,7 @@ struct RelDateTimeFmtDataSink : public ResourceSink {
+ }
+
+ int32_t relUnitIndex = relUnitFromGeneric(genericUnit);
+- if (relUnitIndex == UDAT_RELATIVE_SECONDS && uprv_strcmp(key, "0") == 0 &&
++ if (relUnitIndex == UDAT_REL_UNIT_SECOND && uprv_strcmp(key, "0") == 0 &&
+ outputData.absoluteUnits[style][UDAT_ABSOLUTE_NOW][UDAT_DIRECTION_PLAIN].isEmpty()) {
+ // Handle "NOW"
+ outputData.absoluteUnits[style][UDAT_ABSOLUTE_NOW]
+@@ -463,10 +498,10 @@ struct RelDateTimeFmtDataSink : public ResourceSink {
+ outputData.relativeUnitsFormatters[style][relUnitIndex]
+ [pastFutureIndex];
+ // Only set if not already established.
+- if (patterns[pluralIndex] == NULL) {
++ if (patterns[pluralIndex] == nullptr) {
+ patterns[pluralIndex] = new SimpleFormatter(
+ value.getUnicodeString(errorCode), 0, 1, errorCode);
+- if (patterns[pluralIndex] == NULL) {
++ if (patterns[pluralIndex] == nullptr) {
+ errorCode = U_MEMORY_ALLOCATION_ERROR;
+ }
+ }
+@@ -619,7 +654,7 @@ static UBool getDateTimePattern(
+ .append("/DateTimePatterns", status);
+ LocalUResourceBundlePointer topLevel(
+ ures_getByKeyWithFallback(
+- resource, pathBuffer.data(), NULL, &status));
++ resource, pathBuffer.data(), nullptr, &status));
+ if (U_FAILURE(status)) {
+ return FALSE;
+ }
+@@ -636,68 +671,68 @@ static UBool getDateTimePattern(
+ template<> U_I18N_API
+ const RelativeDateTimeCacheData *LocaleCacheKey<RelativeDateTimeCacheData>::createObject(const void * /*unused*/, UErrorCode &status) const {
+ const char *localeId = fLoc.getName();
+- LocalUResourceBundlePointer topLevel(ures_open(NULL, localeId, &status));
++ LocalUResourceBundlePointer topLevel(ures_open(nullptr, localeId, &status));
+ if (U_FAILURE(status)) {
+- return NULL;
++ return nullptr;
+ }
+ LocalPointer<RelativeDateTimeCacheData> result(
+ new RelativeDateTimeCacheData());
+ if (result.isNull()) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+- return NULL;
++ return nullptr;
+ }
+ if (!loadUnitData(
+ topLevel.getAlias(),
+ *result,
+ localeId,
+ status)) {
+- return NULL;
++ return nullptr;
+ }
+ UnicodeString dateTimePattern;
+ if (!getDateTimePattern(topLevel.getAlias(), dateTimePattern, status)) {
+- return NULL;
++ return nullptr;
+ }
+ result->adoptCombinedDateAndTime(
+ new SimpleFormatter(dateTimePattern, 2, 2, status));
+ if (U_FAILURE(status)) {
+- return NULL;
++ return nullptr;
+ }
+ result->addRef();
+ return result.orphan();
+ }
+
+ RelativeDateTimeFormatter::RelativeDateTimeFormatter(UErrorCode& status) :
+- fCache(NULL),
+- fNumberFormat(NULL),
+- fPluralRules(NULL),
++ fCache(nullptr),
++ fNumberFormat(nullptr),
++ fPluralRules(nullptr),
+ fStyle(UDAT_STYLE_LONG),
+ fContext(UDISPCTX_CAPITALIZATION_NONE),
+- fOptBreakIterator(NULL) {
+- init(NULL, NULL, status);
++ fOptBreakIterator(nullptr) {
++ init(nullptr, nullptr, status);
+ }
+
+ RelativeDateTimeFormatter::RelativeDateTimeFormatter(
+ const Locale& locale, UErrorCode& status) :
+- fCache(NULL),
+- fNumberFormat(NULL),
+- fPluralRules(NULL),
++ fCache(nullptr),
++ fNumberFormat(nullptr),
++ fPluralRules(nullptr),
+ fStyle(UDAT_STYLE_LONG),
+ fContext(UDISPCTX_CAPITALIZATION_NONE),
+- fOptBreakIterator(NULL),
++ fOptBreakIterator(nullptr),
+ fLocale(locale) {
+- init(NULL, NULL, status);
++ init(nullptr, nullptr, status);
+ }
+
+ RelativeDateTimeFormatter::RelativeDateTimeFormatter(
+ const Locale& locale, NumberFormat *nfToAdopt, UErrorCode& status) :
+- fCache(NULL),
+- fNumberFormat(NULL),
+- fPluralRules(NULL),
++ fCache(nullptr),
++ fNumberFormat(nullptr),
++ fPluralRules(nullptr),
+ fStyle(UDAT_STYLE_LONG),
+ fContext(UDISPCTX_CAPITALIZATION_NONE),
+- fOptBreakIterator(NULL),
++ fOptBreakIterator(nullptr),
+ fLocale(locale) {
+- init(nfToAdopt, NULL, status);
++ init(nfToAdopt, nullptr, status);
+ }
+
+ RelativeDateTimeFormatter::RelativeDateTimeFormatter(
+@@ -706,12 +741,12 @@ RelativeDateTimeFormatter::RelativeDateTimeFormatter(
+ UDateRelativeDateTimeFormatterStyle styl,
+ UDisplayContext capitalizationContext,
+ UErrorCode& status) :
+- fCache(NULL),
+- fNumberFormat(NULL),
+- fPluralRules(NULL),
++ fCache(nullptr),
++ fNumberFormat(nullptr),
++ fPluralRules(nullptr),
+ fStyle(styl),
+ fContext(capitalizationContext),
+- fOptBreakIterator(NULL),
++ fOptBreakIterator(nullptr),
+ fLocale(locale) {
+ if (U_FAILURE(status)) {
+ return;
+@@ -727,7 +762,7 @@ RelativeDateTimeFormatter::RelativeDateTimeFormatter(
+ }
+ init(nfToAdopt, bi, status);
+ } else {
+- init(nfToAdopt, NULL, status);
++ init(nfToAdopt, nullptr, status);
+ }
+ }
+
+@@ -744,7 +779,7 @@ RelativeDateTimeFormatter::RelativeDateTimeFormatter(
+ fCache->addRef();
+ fNumberFormat->addRef();
+ fPluralRules->addRef();
+- if (fOptBreakIterator != NULL) {
++ if (fOptBreakIterator != nullptr) {
+ fOptBreakIterator->addRef();
+ }
+ }
+@@ -764,16 +799,16 @@ RelativeDateTimeFormatter& RelativeDateTimeFormatter::operator=(
+ }
+
+ RelativeDateTimeFormatter::~RelativeDateTimeFormatter() {
+- if (fCache != NULL) {
++ if (fCache != nullptr) {
+ fCache->removeRef();
+ }
+- if (fNumberFormat != NULL) {
++ if (fNumberFormat != nullptr) {
+ fNumberFormat->removeRef();
+ }
+- if (fPluralRules != NULL) {
++ if (fPluralRules != nullptr) {
+ fPluralRules->removeRef();
+ }
+- if (fOptBreakIterator != NULL) {
++ if (fOptBreakIterator != nullptr) {
+ fOptBreakIterator->removeRef();
+ }
+ }
+@@ -812,7 +847,7 @@ UnicodeString& RelativeDateTimeFormatter::format(
+
+ const SimpleFormatter* formatter =
+ fCache->getRelativeUnitFormatter(fStyle, unit, bFuture, pluralIndex);
+- if (formatter == NULL) {
++ if (formatter == nullptr) {
+ // TODO: WARN - look at quantity formatter's action with an error.
+ status = U_INVALID_FORMAT_ERROR;
+ return appendTo;
+@@ -828,33 +863,35 @@ UnicodeString& RelativeDateTimeFormatter::formatNumeric(
+ if (U_FAILURE(status)) {
+ return appendTo;
+ }
+- // TODO:
+- // The full implementation of this depends on CLDR data that is not yet available,
+- // see: http://unicode.org/cldr/trac/ticket/9165 Add more relative field data.
+- // In the meantime do a quick bring-up by calling the old format method; this
+- // leaves some holes (even for data that is currently available, such as quarter).
+- // When the new CLDR data is available, update the data storage accordingly,
+- // rewrite this to use it directly, and rewrite the old format method to call this
+- // new one; that is covered by http://bugs.icu-project.org/trac/ticket/12171.
+- UDateRelativeUnit relunit = UDAT_RELATIVE_UNIT_COUNT;
+- switch (unit) {
+- case UDAT_REL_UNIT_YEAR: relunit = UDAT_RELATIVE_YEARS; break;
+- case UDAT_REL_UNIT_MONTH: relunit = UDAT_RELATIVE_MONTHS; break;
+- case UDAT_REL_UNIT_WEEK: relunit = UDAT_RELATIVE_WEEKS; break;
+- case UDAT_REL_UNIT_DAY: relunit = UDAT_RELATIVE_DAYS; break;
+- case UDAT_REL_UNIT_HOUR: relunit = UDAT_RELATIVE_HOURS; break;
+- case UDAT_REL_UNIT_MINUTE: relunit = UDAT_RELATIVE_MINUTES; break;
+- case UDAT_REL_UNIT_SECOND: relunit = UDAT_RELATIVE_SECONDS; break;
+- default: // a unit that the above method does not handle
+- status = U_UNSUPPORTED_ERROR;
+- return appendTo;
+- }
+ UDateDirection direction = UDAT_DIRECTION_NEXT;
+ if (std::signbit(offset)) { // needed to handle -0.0
+ direction = UDAT_DIRECTION_LAST;
+ offset = -offset;
+ }
+- return format(offset, direction, relunit, appendTo, status);
++ if (direction != UDAT_DIRECTION_LAST && direction != UDAT_DIRECTION_NEXT) {
++ status = U_ILLEGAL_ARGUMENT_ERROR;
++ return appendTo;
++ }
++ int32_t bFuture = direction == UDAT_DIRECTION_NEXT ? 1 : 0;
++ FieldPosition pos(FieldPosition::DONT_CARE);
++
++ UnicodeString result;
++ UnicodeString formattedNumber;
++
++ StandardPlural::Form pluralIndex = QuantityFormatter::selectPlural(
++ offset, **fNumberFormat, **fPluralRules, formattedNumber, pos,
++ status);
++
++ const SimpleFormatter* formatter =
++ fCache->getRelativeDateTimeUnitFormatter(fStyle, unit, bFuture, pluralIndex);
++ if (formatter == nullptr) {
++ // TODO: WARN - look at quantity formatter's action with an error.
++ status = U_INVALID_FORMAT_ERROR;
++ return appendTo;
++ }
++ formatter->format(formattedNumber, result, status);
++ adjustForContext(result);
++ return appendTo.append(result);
+ }
+
+ UnicodeString& RelativeDateTimeFormatter::format(
+@@ -871,7 +908,7 @@ UnicodeString& RelativeDateTimeFormatter::format(
+ // Get string using fallback.
+ UnicodeString result;
+ result.fastCopyFrom(fCache->getAbsoluteUnitString(fStyle, unit, direction));
+- if (fOptBreakIterator != NULL) {
++ if (fOptBreakIterator != nullptr) {
+ adjustForContext(result);
+ }
+ return appendTo.append(result);
+@@ -908,6 +945,7 @@ UnicodeString& RelativeDateTimeFormatter::format(
+ UDateAbsoluteUnit absunit = UDAT_ABSOLUTE_UNIT_COUNT;
+ switch (unit) {
+ case UDAT_REL_UNIT_YEAR: absunit = UDAT_ABSOLUTE_YEAR; break;
++ case UDAT_REL_UNIT_QUARTER: absunit = UDAT_ABSOLUTE_QUARTER; break;
+ case UDAT_REL_UNIT_MONTH: absunit = UDAT_ABSOLUTE_MONTH; break;
+ case UDAT_REL_UNIT_WEEK: absunit = UDAT_ABSOLUTE_WEEK; break;
+ case UDAT_REL_UNIT_DAY: absunit = UDAT_ABSOLUTE_DAY; break;
+@@ -930,7 +968,7 @@ UnicodeString& RelativeDateTimeFormatter::format(
+ const UnicodeString &unitFormatString =
+ fCache->getAbsoluteUnitString(fStyle, absunit, direction);
+ if (!unitFormatString.isEmpty()) {
+- if (fOptBreakIterator != NULL) {
++ if (fOptBreakIterator != nullptr) {
+ UnicodeString result(unitFormatString);
+ adjustForContext(result);
+ return appendTo.append(result);
+@@ -951,7 +989,7 @@ UnicodeString& RelativeDateTimeFormatter::combineDateAndTime(
+ }
+
+ void RelativeDateTimeFormatter::adjustForContext(UnicodeString &str) const {
+- if (fOptBreakIterator == NULL
++ if (fOptBreakIterator == nullptr
+ || str.length() == 0 || !u_islower(str.char32At(0))) {
+ return;
+ }
+@@ -992,7 +1030,7 @@ void RelativeDateTimeFormatter::init(
+ shared->removeRef();
+ } else {
+ SharedNumberFormat *shared = new SharedNumberFormat(nf.getAlias());
+- if (shared == NULL) {
++ if (shared == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+@@ -1003,7 +1041,7 @@ void RelativeDateTimeFormatter::init(
+ SharedObject::clearPtr(fOptBreakIterator);
+ } else {
+ SharedBreakIterator *shared = new SharedBreakIterator(bi.getAlias());
+- if (shared == NULL) {
++ if (shared == nullptr) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+@@ -1026,13 +1064,13 @@ ureldatefmt_open( const char* locale,
+ UErrorCode* status )
+ {
+ if (U_FAILURE(*status)) {
+- return NULL;
++ return nullptr;
+ }
+ LocalPointer<RelativeDateTimeFormatter> formatter(new RelativeDateTimeFormatter(Locale(locale),
+ (NumberFormat*)nfToAdopt, width,
+ capitalizationContext, *status), *status);
+ if (U_FAILURE(*status)) {
+- return NULL;
++ return nullptr;
+ }
+ return (URelativeDateTimeFormatter*)formatter.orphan();
+ }
+@@ -1054,13 +1092,13 @@ ureldatefmt_formatNumeric( const URelativeDateTimeFormatter* reldatefmt,
+ if (U_FAILURE(*status)) {
+ return 0;
+ }
+- if (result == NULL ? resultCapacity != 0 : resultCapacity < 0) {
++ if (result == nullptr ? resultCapacity != 0 : resultCapacity < 0) {
+ *status = U_ILLEGAL_ARGUMENT_ERROR;
+ return 0;
+ }
+ UnicodeString res;
+- if (result != NULL) {
+- // NULL destination for pure preflighting: empty dummy string
++ if (result != nullptr) {
++ // nullptr destination for pure preflighting: empty dummy string
+ // otherwise, alias the destination buffer (copied from udat_format)
+ res.setTo(result, 0, resultCapacity);
+ }
+@@ -1082,13 +1120,13 @@ ureldatefmt_format( const URelativeDateTimeFormatter* reldatefmt,
+ if (U_FAILURE(*status)) {
+ return 0;
+ }
+- if (result == NULL ? resultCapacity != 0 : resultCapacity < 0) {
++ if (result == nullptr ? resultCapacity != 0 : resultCapacity < 0) {
+ *status = U_ILLEGAL_ARGUMENT_ERROR;
+ return 0;
+ }
+ UnicodeString res;
+- if (result != NULL) {
+- // NULL destination for pure preflighting: empty dummy string
++ if (result != nullptr) {
++ // nullptr destination for pure preflighting: empty dummy string
+ // otherwise, alias the destination buffer (copied from udat_format)
+ res.setTo(result, 0, resultCapacity);
+ }
+@@ -1112,9 +1150,9 @@ ureldatefmt_combineDateAndTime( const URelativeDateTimeFormatter* reldatefmt,
+ if (U_FAILURE(*status)) {
+ return 0;
+ }
+- if (result == NULL ? resultCapacity != 0 : resultCapacity < 0 ||
+- (relativeDateString == NULL ? relativeDateStringLen != 0 : relativeDateStringLen < -1) ||
+- (timeString == NULL ? timeStringLen != 0 : timeStringLen < -1)) {
++ if (result == nullptr ? resultCapacity != 0 : resultCapacity < 0 ||
++ (relativeDateString == nullptr ? relativeDateStringLen != 0 : relativeDateStringLen < -1) ||
++ (timeString == nullptr ? timeStringLen != 0 : timeStringLen < -1)) {
+ *status = U_ILLEGAL_ARGUMENT_ERROR;
+ return 0;
+ }
+diff --git a/icu4c/source/i18n/unicode/reldatefmt.h b/icu4c/source/i18n/unicode/reldatefmt.h
+index 918d43e67a..be06b1013d 100644
+--- a/icu4c/source/i18n/unicode/reldatefmt.h
++++ b/icu4c/source/i18n/unicode/reldatefmt.h
+@@ -165,12 +165,20 @@ typedef enum UDateAbsoluteUnit {
+ */
+ UDAT_ABSOLUTE_NOW,
+
++#ifndef U_HIDE_DRAFT_API
++ /**
++ * Quarter
++ * @draft ICU 63
++ */
++ UDAT_ABSOLUTE_QUARTER,
++#endif // U_HIDE_DRAFT_API
++
+ #ifndef U_HIDE_DEPRECATED_API
+ /**
+ * One more than the highest normal UDateAbsoluteUnit value.
+ * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
+ */
+- UDAT_ABSOLUTE_UNIT_COUNT
++ UDAT_ABSOLUTE_UNIT_COUNT = UDAT_ABSOLUTE_NOW + 2
+ #endif // U_HIDE_DEPRECATED_API
+ } UDateAbsoluteUnit;
+
diff --git a/scripts/trim_data.sh b/scripts/trim_data.sh
index a949755..41e539e 100755
--- a/scripts/trim_data.sh
+++ b/scripts/trim_data.sh
@@ -17,7 +17,7 @@
/^ AuxExemplarCharacters\{$/, /^ \}$/d
/^ ExemplarCharacters\{.*\}$/d
/^ ExemplarCharacters\{$/, /^ \}$/d
- /^ (mon|tue|wed|thu|fri|sat|sun|quarter)(|-short|-narrow)\{$/, /^ \}$/d' ${langpath}
+ /^ (mon|tue|wed|thu|fri|sat|sun)(|-short|-narrow)\{$/, /^ \}$/d' ${langpath}
done
}
diff --git a/source/i18n/reldatefmt.cpp b/source/i18n/reldatefmt.cpp
index aad026c..8e2a8d1 100644
--- a/source/i18n/reldatefmt.cpp
+++ b/source/i18n/reldatefmt.cpp
@@ -51,13 +51,13 @@
// RelativeDateTimeFormatter specific data for a single locale
class RelativeDateTimeCacheData: public SharedObject {
public:
- RelativeDateTimeCacheData() : combinedDateAndTime(NULL) {
+ RelativeDateTimeCacheData() : combinedDateAndTime(nullptr) {
// Initialize the cache arrays
for (int32_t style = 0; style < UDAT_STYLE_COUNT; ++style) {
- for (int32_t relUnit = 0; relUnit < UDAT_RELATIVE_UNIT_COUNT; ++relUnit) {
+ for (int32_t relUnit = 0; relUnit < UDAT_REL_UNIT_COUNT; ++relUnit) {
for (int32_t pl = 0; pl < StandardPlural::COUNT; ++pl) {
- relativeUnitsFormatters[style][relUnit][0][pl] = NULL;
- relativeUnitsFormatters[style][relUnit][1][pl] = NULL;
+ relativeUnitsFormatters[style][relUnit][0][pl] = nullptr;
+ relativeUnitsFormatters[style][relUnit][1][pl] = nullptr;
}
}
}
@@ -74,7 +74,7 @@
// e.g., Next Tuesday; Yesterday; etc. For third index, 0
// means past, e.g., 5 days ago; 1 means future, e.g., in 5 days.
SimpleFormatter *relativeUnitsFormatters[UDAT_STYLE_COUNT]
- [UDAT_RELATIVE_UNIT_COUNT][2][StandardPlural::COUNT];
+ [UDAT_REL_UNIT_COUNT][2][StandardPlural::COUNT];
const UnicodeString& getAbsoluteUnitString(int32_t fStyle,
UDateAbsoluteUnit unit,
@@ -83,6 +83,10 @@
UDateRelativeUnit unit,
int32_t pastFutureIndex,
int32_t pluralUnit) const;
+ const SimpleFormatter* getRelativeDateTimeUnitFormatter(int32_t fStyle,
+ URelativeDateTimeUnit unit,
+ int32_t pastFutureIndex,
+ int32_t pluralUnit) const;
const UnicodeString emptyString;
@@ -107,7 +111,7 @@
RelativeDateTimeCacheData::~RelativeDateTimeCacheData() {
// clear out the cache arrays
for (int32_t style = 0; style < UDAT_STYLE_COUNT; ++style) {
- for (int32_t relUnit = 0; relUnit < UDAT_RELATIVE_UNIT_COUNT; ++relUnit) {
+ for (int32_t relUnit = 0; relUnit < UDAT_REL_UNIT_COUNT; ++relUnit) {
for (int32_t pl = 0; pl < StandardPlural::COUNT; ++pl) {
delete relativeUnitsFormatters[style][relUnit][0][pl];
delete relativeUnitsFormatters[style][relUnit][1][pl];
@@ -131,20 +135,41 @@
return emptyString;
}
- // Use fallback cache for SimpleFormatter relativeUnits.
const SimpleFormatter* RelativeDateTimeCacheData::getRelativeUnitFormatter(
int32_t fStyle,
UDateRelativeUnit unit,
int32_t pastFutureIndex,
int32_t pluralUnit) const {
+ URelativeDateTimeUnit rdtunit = UDAT_REL_UNIT_COUNT;
+ switch (unit) {
+ case UDAT_RELATIVE_YEARS: rdtunit = UDAT_REL_UNIT_YEAR; break;
+ case UDAT_RELATIVE_MONTHS: rdtunit = UDAT_REL_UNIT_MONTH; break;
+ case UDAT_RELATIVE_WEEKS: rdtunit = UDAT_REL_UNIT_WEEK; break;
+ case UDAT_RELATIVE_DAYS: rdtunit = UDAT_REL_UNIT_DAY; break;
+ case UDAT_RELATIVE_HOURS: rdtunit = UDAT_REL_UNIT_HOUR; break;
+ case UDAT_RELATIVE_MINUTES: rdtunit = UDAT_REL_UNIT_MINUTE; break;
+ case UDAT_RELATIVE_SECONDS: rdtunit = UDAT_REL_UNIT_SECOND; break;
+ default: // a unit that the above method does not handle
+ return nullptr;
+ }
+
+ return getRelativeDateTimeUnitFormatter(fStyle, rdtunit, pastFutureIndex, pluralUnit);
+ }
+
+ // Use fallback cache for SimpleFormatter relativeUnits.
+ const SimpleFormatter* RelativeDateTimeCacheData::getRelativeDateTimeUnitFormatter(
+ int32_t fStyle,
+ URelativeDateTimeUnit unit,
+ int32_t pastFutureIndex,
+ int32_t pluralUnit) const {
int32_t style = fStyle;
do {
- if (relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit] != NULL) {
+ if (relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit] != nullptr) {
return relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit];
}
style = fallBackCache[style];
} while (style != -1);
- return NULL; // No formatter found.
+ return nullptr; // No formatter found.
}
static UBool getStringWithFallback(
@@ -217,23 +242,35 @@
// Converts the generic units to UDAT_RELATIVE version.
switch (genUnit) {
case SECOND:
- return UDAT_RELATIVE_SECONDS;
+ return UDAT_REL_UNIT_SECOND;
case MINUTE:
- return UDAT_RELATIVE_MINUTES;
+ return UDAT_REL_UNIT_MINUTE;
case HOUR:
- return UDAT_RELATIVE_HOURS;
+ return UDAT_REL_UNIT_HOUR;
case DAY:
- return UDAT_RELATIVE_DAYS;
+ return UDAT_REL_UNIT_DAY;
case WEEK:
- return UDAT_RELATIVE_WEEKS;
+ return UDAT_REL_UNIT_WEEK;
case MONTH:
- return UDAT_RELATIVE_MONTHS;
- /*
- * case QUARTER:
- * return UDATE_RELATIVE_QUARTERS;
- */
+ return UDAT_REL_UNIT_MONTH;
+ case QUARTER:
+ return UDAT_REL_UNIT_QUARTER;
case YEAR:
- return UDAT_RELATIVE_YEARS;
+ return UDAT_REL_UNIT_YEAR;
+ case SUNDAY:
+ return UDAT_REL_UNIT_SUNDAY;
+ case MONDAY:
+ return UDAT_REL_UNIT_MONDAY;
+ case TUESDAY:
+ return UDAT_REL_UNIT_TUESDAY;
+ case WEDNESDAY:
+ return UDAT_REL_UNIT_WEDNESDAY;
+ case THURSDAY:
+ return UDAT_REL_UNIT_THURSDAY;
+ case FRIDAY:
+ return UDAT_REL_UNIT_FRIDAY;
+ case SATURDAY:
+ return UDAT_REL_UNIT_SATURDAY;
default:
return -1;
}
@@ -248,10 +285,8 @@
return UDAT_ABSOLUTE_WEEK;
case MONTH:
return UDAT_ABSOLUTE_MONTH;
- /* TODO: Add in QUARTER
- * case QUARTER:
- * return UDAT_ABSOLUTE_QUARTER;
- */
+ case QUARTER:
+ return UDAT_ABSOLUTE_QUARTER;
case YEAR:
return UDAT_ABSOLUTE_YEAR;
case SUNDAY:
@@ -430,7 +465,7 @@
}
int32_t relUnitIndex = relUnitFromGeneric(genericUnit);
- if (relUnitIndex == UDAT_RELATIVE_SECONDS && uprv_strcmp(key, "0") == 0 &&
+ if (relUnitIndex == UDAT_REL_UNIT_SECOND && uprv_strcmp(key, "0") == 0 &&
outputData.absoluteUnits[style][UDAT_ABSOLUTE_NOW][UDAT_DIRECTION_PLAIN].isEmpty()) {
// Handle "NOW"
outputData.absoluteUnits[style][UDAT_ABSOLUTE_NOW]
@@ -463,10 +498,10 @@
outputData.relativeUnitsFormatters[style][relUnitIndex]
[pastFutureIndex];
// Only set if not already established.
- if (patterns[pluralIndex] == NULL) {
+ if (patterns[pluralIndex] == nullptr) {
patterns[pluralIndex] = new SimpleFormatter(
value.getUnicodeString(errorCode), 0, 1, errorCode);
- if (patterns[pluralIndex] == NULL) {
+ if (patterns[pluralIndex] == nullptr) {
errorCode = U_MEMORY_ALLOCATION_ERROR;
}
}
@@ -619,7 +654,7 @@
.append("/DateTimePatterns", status);
LocalUResourceBundlePointer topLevel(
ures_getByKeyWithFallback(
- resource, pathBuffer.data(), NULL, &status));
+ resource, pathBuffer.data(), nullptr, &status));
if (U_FAILURE(status)) {
return FALSE;
}
@@ -636,68 +671,68 @@
template<> U_I18N_API
const RelativeDateTimeCacheData *LocaleCacheKey<RelativeDateTimeCacheData>::createObject(const void * /*unused*/, UErrorCode &status) const {
const char *localeId = fLoc.getName();
- LocalUResourceBundlePointer topLevel(ures_open(NULL, localeId, &status));
+ LocalUResourceBundlePointer topLevel(ures_open(nullptr, localeId, &status));
if (U_FAILURE(status)) {
- return NULL;
+ return nullptr;
}
LocalPointer<RelativeDateTimeCacheData> result(
new RelativeDateTimeCacheData());
if (result.isNull()) {
status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
+ return nullptr;
}
if (!loadUnitData(
topLevel.getAlias(),
*result,
localeId,
status)) {
- return NULL;
+ return nullptr;
}
UnicodeString dateTimePattern;
if (!getDateTimePattern(topLevel.getAlias(), dateTimePattern, status)) {
- return NULL;
+ return nullptr;
}
result->adoptCombinedDateAndTime(
new SimpleFormatter(dateTimePattern, 2, 2, status));
if (U_FAILURE(status)) {
- return NULL;
+ return nullptr;
}
result->addRef();
return result.orphan();
}
RelativeDateTimeFormatter::RelativeDateTimeFormatter(UErrorCode& status) :
- fCache(NULL),
- fNumberFormat(NULL),
- fPluralRules(NULL),
+ fCache(nullptr),
+ fNumberFormat(nullptr),
+ fPluralRules(nullptr),
fStyle(UDAT_STYLE_LONG),
fContext(UDISPCTX_CAPITALIZATION_NONE),
- fOptBreakIterator(NULL) {
- init(NULL, NULL, status);
+ fOptBreakIterator(nullptr) {
+ init(nullptr, nullptr, status);
}
RelativeDateTimeFormatter::RelativeDateTimeFormatter(
const Locale& locale, UErrorCode& status) :
- fCache(NULL),
- fNumberFormat(NULL),
- fPluralRules(NULL),
+ fCache(nullptr),
+ fNumberFormat(nullptr),
+ fPluralRules(nullptr),
fStyle(UDAT_STYLE_LONG),
fContext(UDISPCTX_CAPITALIZATION_NONE),
- fOptBreakIterator(NULL),
+ fOptBreakIterator(nullptr),
fLocale(locale) {
- init(NULL, NULL, status);
+ init(nullptr, nullptr, status);
}
RelativeDateTimeFormatter::RelativeDateTimeFormatter(
const Locale& locale, NumberFormat *nfToAdopt, UErrorCode& status) :
- fCache(NULL),
- fNumberFormat(NULL),
- fPluralRules(NULL),
+ fCache(nullptr),
+ fNumberFormat(nullptr),
+ fPluralRules(nullptr),
fStyle(UDAT_STYLE_LONG),
fContext(UDISPCTX_CAPITALIZATION_NONE),
- fOptBreakIterator(NULL),
+ fOptBreakIterator(nullptr),
fLocale(locale) {
- init(nfToAdopt, NULL, status);
+ init(nfToAdopt, nullptr, status);
}
RelativeDateTimeFormatter::RelativeDateTimeFormatter(
@@ -706,12 +741,12 @@
UDateRelativeDateTimeFormatterStyle styl,
UDisplayContext capitalizationContext,
UErrorCode& status) :
- fCache(NULL),
- fNumberFormat(NULL),
- fPluralRules(NULL),
+ fCache(nullptr),
+ fNumberFormat(nullptr),
+ fPluralRules(nullptr),
fStyle(styl),
fContext(capitalizationContext),
- fOptBreakIterator(NULL),
+ fOptBreakIterator(nullptr),
fLocale(locale) {
if (U_FAILURE(status)) {
return;
@@ -727,7 +762,7 @@
}
init(nfToAdopt, bi, status);
} else {
- init(nfToAdopt, NULL, status);
+ init(nfToAdopt, nullptr, status);
}
}
@@ -744,7 +779,7 @@
fCache->addRef();
fNumberFormat->addRef();
fPluralRules->addRef();
- if (fOptBreakIterator != NULL) {
+ if (fOptBreakIterator != nullptr) {
fOptBreakIterator->addRef();
}
}
@@ -764,16 +799,16 @@
}
RelativeDateTimeFormatter::~RelativeDateTimeFormatter() {
- if (fCache != NULL) {
+ if (fCache != nullptr) {
fCache->removeRef();
}
- if (fNumberFormat != NULL) {
+ if (fNumberFormat != nullptr) {
fNumberFormat->removeRef();
}
- if (fPluralRules != NULL) {
+ if (fPluralRules != nullptr) {
fPluralRules->removeRef();
}
- if (fOptBreakIterator != NULL) {
+ if (fOptBreakIterator != nullptr) {
fOptBreakIterator->removeRef();
}
}
@@ -812,7 +847,7 @@
const SimpleFormatter* formatter =
fCache->getRelativeUnitFormatter(fStyle, unit, bFuture, pluralIndex);
- if (formatter == NULL) {
+ if (formatter == nullptr) {
// TODO: WARN - look at quantity formatter's action with an error.
status = U_INVALID_FORMAT_ERROR;
return appendTo;
@@ -828,33 +863,35 @@
if (U_FAILURE(status)) {
return appendTo;
}
- // TODO:
- // The full implementation of this depends on CLDR data that is not yet available,
- // see: http://unicode.org/cldr/trac/ticket/9165 Add more relative field data.
- // In the meantime do a quick bring-up by calling the old format method; this
- // leaves some holes (even for data that is currently available, such as quarter).
- // When the new CLDR data is available, update the data storage accordingly,
- // rewrite this to use it directly, and rewrite the old format method to call this
- // new one; that is covered by http://bugs.icu-project.org/trac/ticket/12171.
- UDateRelativeUnit relunit = UDAT_RELATIVE_UNIT_COUNT;
- switch (unit) {
- case UDAT_REL_UNIT_YEAR: relunit = UDAT_RELATIVE_YEARS; break;
- case UDAT_REL_UNIT_MONTH: relunit = UDAT_RELATIVE_MONTHS; break;
- case UDAT_REL_UNIT_WEEK: relunit = UDAT_RELATIVE_WEEKS; break;
- case UDAT_REL_UNIT_DAY: relunit = UDAT_RELATIVE_DAYS; break;
- case UDAT_REL_UNIT_HOUR: relunit = UDAT_RELATIVE_HOURS; break;
- case UDAT_REL_UNIT_MINUTE: relunit = UDAT_RELATIVE_MINUTES; break;
- case UDAT_REL_UNIT_SECOND: relunit = UDAT_RELATIVE_SECONDS; break;
- default: // a unit that the above method does not handle
- status = U_UNSUPPORTED_ERROR;
- return appendTo;
- }
UDateDirection direction = UDAT_DIRECTION_NEXT;
if (std::signbit(offset)) { // needed to handle -0.0
direction = UDAT_DIRECTION_LAST;
offset = -offset;
}
- return format(offset, direction, relunit, appendTo, status);
+ if (direction != UDAT_DIRECTION_LAST && direction != UDAT_DIRECTION_NEXT) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ return appendTo;
+ }
+ int32_t bFuture = direction == UDAT_DIRECTION_NEXT ? 1 : 0;
+ FieldPosition pos(FieldPosition::DONT_CARE);
+
+ UnicodeString result;
+ UnicodeString formattedNumber;
+
+ StandardPlural::Form pluralIndex = QuantityFormatter::selectPlural(
+ offset, **fNumberFormat, **fPluralRules, formattedNumber, pos,
+ status);
+
+ const SimpleFormatter* formatter =
+ fCache->getRelativeDateTimeUnitFormatter(fStyle, unit, bFuture, pluralIndex);
+ if (formatter == nullptr) {
+ // TODO: WARN - look at quantity formatter's action with an error.
+ status = U_INVALID_FORMAT_ERROR;
+ return appendTo;
+ }
+ formatter->format(formattedNumber, result, status);
+ adjustForContext(result);
+ return appendTo.append(result);
}
UnicodeString& RelativeDateTimeFormatter::format(
@@ -871,7 +908,7 @@
// Get string using fallback.
UnicodeString result;
result.fastCopyFrom(fCache->getAbsoluteUnitString(fStyle, unit, direction));
- if (fOptBreakIterator != NULL) {
+ if (fOptBreakIterator != nullptr) {
adjustForContext(result);
}
return appendTo.append(result);
@@ -908,6 +945,7 @@
UDateAbsoluteUnit absunit = UDAT_ABSOLUTE_UNIT_COUNT;
switch (unit) {
case UDAT_REL_UNIT_YEAR: absunit = UDAT_ABSOLUTE_YEAR; break;
+ case UDAT_REL_UNIT_QUARTER: absunit = UDAT_ABSOLUTE_QUARTER; break;
case UDAT_REL_UNIT_MONTH: absunit = UDAT_ABSOLUTE_MONTH; break;
case UDAT_REL_UNIT_WEEK: absunit = UDAT_ABSOLUTE_WEEK; break;
case UDAT_REL_UNIT_DAY: absunit = UDAT_ABSOLUTE_DAY; break;
@@ -930,7 +968,7 @@
const UnicodeString &unitFormatString =
fCache->getAbsoluteUnitString(fStyle, absunit, direction);
if (!unitFormatString.isEmpty()) {
- if (fOptBreakIterator != NULL) {
+ if (fOptBreakIterator != nullptr) {
UnicodeString result(unitFormatString);
adjustForContext(result);
return appendTo.append(result);
@@ -951,7 +989,7 @@
}
void RelativeDateTimeFormatter::adjustForContext(UnicodeString &str) const {
- if (fOptBreakIterator == NULL
+ if (fOptBreakIterator == nullptr
|| str.length() == 0 || !u_islower(str.char32At(0))) {
return;
}
@@ -992,7 +1030,7 @@
shared->removeRef();
} else {
SharedNumberFormat *shared = new SharedNumberFormat(nf.getAlias());
- if (shared == NULL) {
+ if (shared == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
@@ -1003,7 +1041,7 @@
SharedObject::clearPtr(fOptBreakIterator);
} else {
SharedBreakIterator *shared = new SharedBreakIterator(bi.getAlias());
- if (shared == NULL) {
+ if (shared == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR;
return;
}
@@ -1026,13 +1064,13 @@
UErrorCode* status )
{
if (U_FAILURE(*status)) {
- return NULL;
+ return nullptr;
}
LocalPointer<RelativeDateTimeFormatter> formatter(new RelativeDateTimeFormatter(Locale(locale),
(NumberFormat*)nfToAdopt, width,
capitalizationContext, *status), *status);
if (U_FAILURE(*status)) {
- return NULL;
+ return nullptr;
}
return (URelativeDateTimeFormatter*)formatter.orphan();
}
@@ -1054,13 +1092,13 @@
if (U_FAILURE(*status)) {
return 0;
}
- if (result == NULL ? resultCapacity != 0 : resultCapacity < 0) {
+ if (result == nullptr ? resultCapacity != 0 : resultCapacity < 0) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString res;
- if (result != NULL) {
- // NULL destination for pure preflighting: empty dummy string
+ if (result != nullptr) {
+ // nullptr destination for pure preflighting: empty dummy string
// otherwise, alias the destination buffer (copied from udat_format)
res.setTo(result, 0, resultCapacity);
}
@@ -1082,13 +1120,13 @@
if (U_FAILURE(*status)) {
return 0;
}
- if (result == NULL ? resultCapacity != 0 : resultCapacity < 0) {
+ if (result == nullptr ? resultCapacity != 0 : resultCapacity < 0) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString res;
- if (result != NULL) {
- // NULL destination for pure preflighting: empty dummy string
+ if (result != nullptr) {
+ // nullptr destination for pure preflighting: empty dummy string
// otherwise, alias the destination buffer (copied from udat_format)
res.setTo(result, 0, resultCapacity);
}
@@ -1112,9 +1150,9 @@
if (U_FAILURE(*status)) {
return 0;
}
- if (result == NULL ? resultCapacity != 0 : resultCapacity < 0 ||
- (relativeDateString == NULL ? relativeDateStringLen != 0 : relativeDateStringLen < -1) ||
- (timeString == NULL ? timeStringLen != 0 : timeStringLen < -1)) {
+ if (result == nullptr ? resultCapacity != 0 : resultCapacity < 0 ||
+ (relativeDateString == nullptr ? relativeDateStringLen != 0 : relativeDateStringLen < -1) ||
+ (timeString == nullptr ? timeStringLen != 0 : timeStringLen < -1)) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
diff --git a/source/i18n/unicode/reldatefmt.h b/source/i18n/unicode/reldatefmt.h
index 09d9620..987fddd 100644
--- a/source/i18n/unicode/reldatefmt.h
+++ b/source/i18n/unicode/reldatefmt.h
@@ -165,12 +165,20 @@
*/
UDAT_ABSOLUTE_NOW,
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Quarter
+ * @draft ICU 63
+ */
+ UDAT_ABSOLUTE_QUARTER,
+#endif // U_HIDE_DRAFT_API
+
#ifndef U_HIDE_DEPRECATED_API
/**
* One more than the highest normal UDateAbsoluteUnit value.
* @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
*/
- UDAT_ABSOLUTE_UNIT_COUNT
+ UDAT_ABSOLUTE_UNIT_COUNT = UDAT_ABSOLUTE_NOW + 2
#endif // U_HIDE_DEPRECATED_API
} UDateAbsoluteUnit;