diff --git a/icu4c/source/i18n/udat.cpp b/icu4c/source/i18n/udat.cpp index 116eb9b0bea..35a2226136f 100644 --- a/icu4c/source/i18n/udat.cpp +++ b/icu4c/source/i18n/udat.cpp @@ -237,6 +237,38 @@ udat_format( const UDateFormat* format, return res.extract(result, resultLength, *status); } +U_CAPI int32_t U_EXPORT2 +udat_formatCalendar(const UDateFormat* format, + UCalendar* calendar, + UChar* result, + int32_t resultLength, + UFieldPosition* position, + UErrorCode* status) +{ + if(U_FAILURE(*status)) return -1; + + UnicodeString res; + if(!(result==NULL && resultLength==0)) { + // NULL destination for pure preflighting: empty dummy string + // otherwise, alias the destination buffer + res.setTo(result, 0, resultLength); + } + + FieldPosition fp; + + if(position != 0) + fp.setField(position->field); + + ((DateFormat*)format)->format(*(Calendar*)calendar, res, fp); + + if(position != 0) { + position->beginIndex = fp.getBeginIndex(); + position->endIndex = fp.getEndIndex(); + } + + return res.extract(result, resultLength, *status); +} + U_CAPI UDate U_EXPORT2 udat_parse( const UDateFormat* format, const UChar* text, diff --git a/icu4c/source/i18n/unicode/udat.h b/icu4c/source/i18n/unicode/udat.h index 5bbe5aa0736..dd25f65f223 100644 --- a/icu4c/source/i18n/unicode/udat.h +++ b/icu4c/source/i18n/unicode/udat.h @@ -961,6 +961,36 @@ udat_format( const UDateFormat* format, UFieldPosition* position, UErrorCode* status); +/** +* Format a date using an UDateFormat. +* The date will be formatted using the conventions specified in {@link #udat_open } +* @param format The formatter to use +* @param calendar The calendar to format. The calendar instance might be +* mutated when fields are not fully calculated yet, although +* this function won't change the logical date and time held +* by the instance. +* @param result A pointer to a buffer to receive the formatted number. +* @param capacity The maximum size of result. +* @param position A pointer to a UFieldPosition. On input, position->field +* is read. On output, position->beginIndex and position->endIndex indicate +* the beginning and ending indices of field number position->field, if such +* a field exists. This parameter may be NULL, in which case no field +* position data is returned. +* @param status A pointer to an UErrorCode to receive any errors +* @return The total buffer size needed; if greater than resultLength, the output was truncated. +* @see udat_format +* @see udat_parseCalendar +* @see UFieldPosition +* @draft ICU 55 +*/ +U_DRAFT int32_t U_EXPORT2 +udat_formatCalendar( const UDateFormat* format, + UCalendar* calendar, + UChar* result, + int32_t capacity, + UFieldPosition* position, + UErrorCode* status); + /** * Parse a string into an date/time using a UDateFormat. * The date will be parsed using the conventions specified in {@link #udat_open }. diff --git a/icu4c/source/test/cintltst/cdattst.c b/icu4c/source/test/cintltst/cdattst.c index f273de726e5..006d879e368 100644 --- a/icu4c/source/test/cintltst/cdattst.c +++ b/icu4c/source/test/cintltst/cdattst.c @@ -828,6 +828,10 @@ static void TestDateFormatCalendar() { int32_t pos; UDate when; UErrorCode ec = U_ZERO_ERROR; + UChar buf1[256]; + int32_t len1; + const char *expected; + UChar uExpected[32]; ctest_setTimeZone(NULL, &ec); @@ -874,6 +878,19 @@ static void TestDateFormatCalendar() { goto FAIL; } + /* Check if formatCalendar matches the original date */ + len1 = udat_formatCalendar(date, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec); + if (U_FAILURE(ec)) { + log_err("FAIL: udat_formatCalendar(4/5/2001) failed with %s\n", + u_errorName(ec)); + goto FAIL; + } + expected = "4/5/01"; + u_uastrcpy(uExpected, expected); + if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) { + log_err("FAIL: udat_formatCalendar(4/5/2001), expected: %s", expected); + } + /* Parse the time */ u_uastrcpy(buf, "5:45 PM"); pos = 0; @@ -883,7 +900,20 @@ static void TestDateFormatCalendar() { pos, u_errorName(ec)); goto FAIL; } - + + /* Check if formatCalendar matches the original time */ + len1 = udat_formatCalendar(time, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec); + if (U_FAILURE(ec)) { + log_err("FAIL: udat_formatCalendar(17:45) failed with %s\n", + u_errorName(ec)); + goto FAIL; + } + expected = "5:45 PM"; + u_uastrcpy(uExpected, expected); + if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) { + log_err("FAIL: udat_formatCalendar(17:45), expected: %s", expected); + } + /* Check result */ when = ucal_getMillis(cal, &ec); if (U_FAILURE(ec)) {