ICU-12072 RelativeDateTimeFormatter: Improve C++ format API, add plain C API (part 1, structure)

X-SVN-Rev: 38189
This commit is contained in:
Peter Edberg 2016-01-22 07:20:54 +00:00
parent 0d543296da
commit 50ea6cb008
11 changed files with 700 additions and 36 deletions

2
.gitattributes vendored
View file

@ -71,6 +71,7 @@ icu4c/source/data/region/pool.res -text
icu4c/source/data/unit/pool.res -text
icu4c/source/data/zone/pool.res -text
icu4c/source/extra/uconv/uconv.vcxproj -text
icu4c/source/i18n/unicode/ureldatefmt.h -text
icu4c/source/samples/break/break.vcxproj -text
icu4c/source/samples/case/case.vcxproj -text
icu4c/source/samples/citer/citer.vcxproj -text
@ -98,6 +99,7 @@ icu4c/source/samples/ugrep/ugrep.vcxproj -text
icu4c/source/samples/uresb/resources.vcxproj -text
icu4c/source/samples/uresb/uresb.vcxproj -text
icu4c/source/samples/ustring/ustring.vcxproj -text
icu4c/source/test/cintltst/crelativedateformattest.c -text
icu4c/source/test/depstest/icu-dependencies-mode.el -text
icu4c/source/test/iotest/iotest.vcxproj -text
icu4c/source/test/letest/cletest.vcxproj -text

View file

@ -1546,6 +1546,20 @@
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Include="unicode\ureldatefmt.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
</CustomBuild>

View file

@ -1238,6 +1238,9 @@
<CustomBuild Include="unicode\upluralrules.h">
<Filter>formatting</Filter>
</CustomBuild>
<CustomBuild Include="unicode\ureldatefmt.h">
<Filter>formatting</Filter>
</CustomBuild>
<CustomBuild Include="unicode\utmscale.h">
<Filter>formatting</Filter>
</CustomBuild>

View file

@ -1,6 +1,6 @@
/*
******************************************************************************
* Copyright (C) 2014-2015, International Business Machines Corporation and
* Copyright (C) 2014-2016, International Business Machines Corporation and
* others. All Rights Reserved.
******************************************************************************
*
@ -12,6 +12,9 @@
#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION
#include "unicode/ureldatefmt.h"
#include "unicode/udisplaycontext.h"
#include "unicode/unum.h"
#include "unicode/localpointer.h"
#include "quantityformatter.h"
#include "unicode/plurrule.h"
@ -805,6 +808,37 @@ UnicodeString& RelativeDateTimeFormatter::format(
return appendTo.append(result);
}
UnicodeString& RelativeDateTimeFormatter::formatNumeric(
double offset, URelativeDateTimeUnit unit,
UnicodeString& appendTo, UErrorCode& status) const {
if (U_FAILURE(status)) {
return appendTo;
}
// For a quick bringup just call the above method; this leaves some
// holes (e.g. for handling quarter). Need to redo the data structure
// to support all necessary data items, and to be indexed by the
// newer enum.
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_MISSING_RESOURCE_ERROR;
return appendTo;
}
UDateDirection direction = UDAT_DIRECTION_NEXT;
if (offset < 0) {
direction = UDAT_DIRECTION_LAST;
offset = -offset;
}
return format(offset, direction, relunit, appendTo, status);
}
UnicodeString& RelativeDateTimeFormatter::format(
UDateDirection direction, UDateAbsoluteUnit unit,
UnicodeString& appendTo, UErrorCode& status) const {
@ -823,6 +857,61 @@ UnicodeString& RelativeDateTimeFormatter::format(
return appendTo.append(result);
}
UnicodeString& RelativeDateTimeFormatter::format(
double offset, URelativeDateTimeUnit unit,
UnicodeString& appendTo, UErrorCode& status) const {
if (U_FAILURE(status)) {
return appendTo;
}
// For a quick bringup just use the existing data structure; this leaves
// some holes (e.g. for handling quarter). Need to redo the data structure
// to support all necessary data items, and to be indexed by the
// newer enum.
UDateDirection direction = UDAT_DIRECTION_COUNT;
int32_t intoffset = (offset < 0)? (int32_t)(offset-0.5) : (int32_t)(offset+0.5);
switch (intoffset) {
case -2: direction = UDAT_DIRECTION_LAST_2; break;
case -1: direction = UDAT_DIRECTION_LAST; break;
case 0: direction = UDAT_DIRECTION_THIS; break;
case 1: direction = UDAT_DIRECTION_NEXT; break;
case 2: direction = UDAT_DIRECTION_NEXT_2; break;
default: break;
}
UDateAbsoluteUnit absunit = UDAT_ABSOLUTE_UNIT_COUNT;
switch (unit) {
case UDAT_REL_UNIT_YEAR: absunit = UDAT_ABSOLUTE_YEAR; 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;
case UDAT_REL_UNIT_MINUTE:
case UDAT_REL_UNIT_SECOND:
if (direction == UDAT_DIRECTION_THIS) {
absunit = UDAT_ABSOLUTE_NOW;
direction = UDAT_DIRECTION_PLAIN;
}
break;
case UDAT_REL_UNIT_SUNDAY: absunit = UDAT_ABSOLUTE_SUNDAY; break;
case UDAT_REL_UNIT_MONDAY: absunit = UDAT_ABSOLUTE_MONDAY; break;
case UDAT_REL_UNIT_TUESDAY: absunit = UDAT_ABSOLUTE_TUESDAY; break;
case UDAT_REL_UNIT_WEDNESDAY: absunit = UDAT_ABSOLUTE_WEDNESDAY; break;
case UDAT_REL_UNIT_THURSDAY: absunit = UDAT_ABSOLUTE_THURSDAY; break;
case UDAT_REL_UNIT_FRIDAY: absunit = UDAT_ABSOLUTE_FRIDAY; break;
case UDAT_REL_UNIT_SATURDAY: absunit = UDAT_ABSOLUTE_SATURDAY; break;
default: break;
}
if (direction != UDAT_DIRECTION_COUNT && absunit != UDAT_ABSOLUTE_UNIT_COUNT) {
UnicodeString result(fCache->absoluteUnits[fStyle][absunit][direction]);
if (result.length() > 0) {
if (fOptBreakIterator != NULL) {
adjustForContext(result);
}
return appendTo.append(result);
}
}
// otherwise fallback to formatNumeric
return formatNumeric(offset, unit, appendTo, status);
}
UnicodeString& RelativeDateTimeFormatter::combineDateAndTime(
const UnicodeString& relativeDateString, const UnicodeString& timeString,
UnicodeString& appendTo, UErrorCode& status) const {
@ -894,8 +983,126 @@ void RelativeDateTimeFormatter::init(
}
}
U_NAMESPACE_END
// Plain C API
U_NAMESPACE_USE
U_CAPI URelativeDateTimeFormatter* U_EXPORT2
ureldatefmt_open( const char* locale,
UNumberFormat* nfToAdopt,
UDateRelativeDateTimeFormatterStyle width,
UDisplayContext capitalizationContext,
UErrorCode* status )
{
if (U_FAILURE(*status)) {
return NULL;
}
LocalPointer<RelativeDateTimeFormatter> formatter(new RelativeDateTimeFormatter(Locale(locale),
(NumberFormat*)nfToAdopt, width,
capitalizationContext, *status));
if (U_FAILURE(*status)) {
return NULL;
}
return (URelativeDateTimeFormatter*)formatter.orphan();
}
U_CAPI void U_EXPORT2
ureldatefmt_close(URelativeDateTimeFormatter *reldatefmt)
{
delete (RelativeDateTimeFormatter*)reldatefmt;
}
U_CAPI int32_t U_EXPORT2
ureldatefmt_formatNumeric( const URelativeDateTimeFormatter* reldatefmt,
double offset,
URelativeDateTimeUnit unit,
UChar* result,
int32_t resultCapacity,
UErrorCode* status)
{
if (U_FAILURE(*status)) {
return 0;
}
if (result == NULL ? resultCapacity != 0 : resultCapacity < 0) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString res;
if (result != NULL) {
// NULL destination for pure preflighting: empty dummy string
// otherwise, alias the destination buffer (copied from udat_format)
res.setTo(result, 0, resultCapacity);
}
((RelativeDateTimeFormatter*)reldatefmt)->formatNumeric(offset, unit, res, *status);
if (U_FAILURE(*status)) {
return 0;
}
return res.extract(result, resultCapacity, *status);
}
U_CAPI int32_t U_EXPORT2
ureldatefmt_format( const URelativeDateTimeFormatter* reldatefmt,
double offset,
URelativeDateTimeUnit unit,
UChar* result,
int32_t resultCapacity,
UErrorCode* status)
{
if (U_FAILURE(*status)) {
return 0;
}
if (result == NULL ? resultCapacity != 0 : resultCapacity < 0) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString res;
if (result != NULL) {
// NULL destination for pure preflighting: empty dummy string
// otherwise, alias the destination buffer (copied from udat_format)
res.setTo(result, 0, resultCapacity);
}
((RelativeDateTimeFormatter*)reldatefmt)->format(offset, unit, res, *status);
if (U_FAILURE(*status)) {
return 0;
}
return res.extract(result, resultCapacity, *status);
}
U_CAPI int32_t U_EXPORT2
ureldatefmt_combineDateAndTime( const URelativeDateTimeFormatter* reldatefmt,
const UChar * relativeDateString,
int32_t relativeDateStringLen,
const UChar * timeString,
int32_t timeStringLen,
UChar* result,
int32_t resultCapacity,
UErrorCode* status )
{
if (U_FAILURE(*status)) {
return 0;
}
if (result == NULL ? resultCapacity != 0 : resultCapacity < 0 ||
relativeDateString == NULL || relativeDateStringLen < 1 ||
timeString == NULL || timeStringLen < -1) {
*status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString relDateStr((UBool)(relativeDateStringLen == -1), relativeDateString, relativeDateStringLen);
UnicodeString timeStr((UBool)(timeStringLen == -1), timeString, timeStringLen);
UnicodeString res;
if (result != NULL) {
// NULL destination for pure preflighting: empty dummy string
// otherwise, alias the destination buffer (copied from udat_format)
res.setTo(result, 0, resultCapacity);
}
((RelativeDateTimeFormatter*)reldatefmt)->combineDateAndTime(relDateStr, timeStr, res, *status);
if (U_FAILURE(*status)) {
return 0;
}
return res.extract(result, resultCapacity, *status);
}
#endif /* !UCONFIG_NO_FORMATTING */

View file

@ -1,6 +1,6 @@
/*
*****************************************************************************
* Copyright (C) 2014-2015, International Business Machines Corporation and
* Copyright (C) 2014-2016, International Business Machines Corporation and
* others.
* All Rights Reserved.
*****************************************************************************
@ -15,6 +15,7 @@
#include "unicode/utypes.h"
#include "unicode/uobject.h"
#include "unicode/udisplaycontext.h"
#include "unicode/ureldatefmt.h"
#include "unicode/locid.h"
/**
@ -24,36 +25,6 @@
#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION
/**
* The formatting style
* @stable ICU 54
*/
typedef enum UDateRelativeDateTimeFormatterStyle {
/**
* Everything spelled out.
* @stable ICU 54
*/
UDAT_STYLE_LONG,
/**
* Abbreviations used when possible.
* @stable ICU 54
*/
UDAT_STYLE_SHORT,
/**
* Use the shortest possible form.
* @stable ICU 54
*/
UDAT_STYLE_NARROW,
/**
* The number of styles.
* @stable ICU 54
*/
UDAT_STYLE_COUNT
} UDateRelativeDateTimeFormatterStyle;
/**
* Represents the unit for formatting a relative date. e.g "in 5 days"
* or "in 3 months"
@ -434,6 +405,54 @@ public:
UnicodeString& appendTo,
UErrorCode& status) const;
#ifndef U_HIDE_DRAFT_API
/**
* Format a combination of URelativeDateTimeUnit and numeric offset
* using a numeric style, e.g. "1 week ago", "in 1 week",
* "5 weeks ago", "in 5 weeks".
*
* @param offset The signed offset for the specified unit. This
* will be formatted according to this object's
* NumberFormat object.
* @param unit The unit to use when formatting the relative
* date, e.g. UDAT_REL_UNIT_WEEK,
* UDAT_REL_UNIT_FRIDAY.
* @param appendTo The string to which the formatted result will be
* appended.
* @param status ICU error code returned here.
* @return appendTo
* @draft ICU 57
*/
UnicodeString& formatNumeric(
double offset,
URelativeDateTimeUnit unit,
UnicodeString& appendTo,
UErrorCode& status) const;
/**
* Format a combination of URelativeDateTimeUnit and numeric offset
* using a text style if possible, e.g. "last week", "this week",
* "next week", "yesterday", "tomorrow". Falls back to numeric
* style if no appropriate text term is available for the specified
* offset in the objects locale.
*
* @param offset The signed offset for the specified unit.
* @param unit The unit to use when formatting the relative
* date, e.g. UDAT_REL_UNIT_WEEK,
* UDAT_REL_UNIT_FRIDAY.
* @param appendTo The string to which the formatted result will be
* appended.
* @param status ICU error code returned here.
* @return appendTo
* @draft ICU 57
*/
UnicodeString& format(
double offset,
URelativeDateTimeUnit unit,
UnicodeString& appendTo,
UErrorCode& status) const;
#endif /* U_HIDE_DRAFT_API */
/**
* Combines a relative date string and a time string in this object's
* locale. This is done with the same date-time separator used for the

View file

@ -0,0 +1,302 @@
/*
*****************************************************************************************
* Copyright (C) 2016, International Business Machines
* Corporation and others. All Rights Reserved.
*****************************************************************************************
*/
#ifndef URELDATEFMT_H
#define URELDATEFMT_H
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION
#include "unicode/unum.h"
#include "unicode/udisplaycontext.h"
#include "unicode/localpointer.h"
/**
* \file
* \brief C API: URelativeDateTimeFormatter, relative date formatting of unit + numeric offset.
*
* Provides simple formatting of relative dates, in two ways
* <ul>
* <li>relative dates with a quantity e.g "in 5 days"</li>
* <li>relative dates without a quantity e.g "next Tuesday"</li>
* </ul>
* <p>
* This does not provide compound formatting for multiple units,
* other than the ability to combine a time string with a relative date,
* as in "next Tuesday at 3:45 PM". It also does not provide support
* for determining which unit to use, such as deciding between "in 7 days"
* and "in 1 week".
*
* @draft ICU 57
*/
/**
* The formatting style
* @stable ICU 54
*/
typedef enum UDateRelativeDateTimeFormatterStyle {
/**
* Everything spelled out.
* @stable ICU 54
*/
UDAT_STYLE_LONG,
/**
* Abbreviations used when possible.
* @stable ICU 54
*/
UDAT_STYLE_SHORT,
/**
* Use the shortest possible form.
* @stable ICU 54
*/
UDAT_STYLE_NARROW,
/**
* The number of styles.
* @stable ICU 54
*/
UDAT_STYLE_COUNT
} UDateRelativeDateTimeFormatterStyle;
#ifndef U_HIDE_DRAFT_API
/**
* Represents the unit for formatting a relative date. e.g "in 5 days"
* or "next year"
* @draft ICU 57
*/
typedef enum URelativeDateTimeUnit {
/** @draft ICU 57 */
UDAT_REL_UNIT_YEAR,
/** @draft ICU 57 */
UDAT_REL_UNIT_QUARTER,
/** @draft ICU 57 */
UDAT_REL_UNIT_MONTH,
/** @draft ICU 57 */
UDAT_REL_UNIT_WEEK,
/** @draft ICU 57 */
UDAT_REL_UNIT_DAY,
/** @draft ICU 57 */
UDAT_REL_UNIT_HOUR,
/** @draft ICU 57 */
UDAT_REL_UNIT_MINUTE,
/** @draft ICU 57 */
UDAT_REL_UNIT_SECOND,
/** @draft ICU 57 */
UDAT_REL_UNIT_SUNDAY,
/** @draft ICU 57 */
UDAT_REL_UNIT_MONDAY,
/** @draft ICU 57 */
UDAT_REL_UNIT_TUESDAY,
/** @draft ICU 57 */
UDAT_REL_UNIT_WEDNESDAY,
/** @draft ICU 57 */
UDAT_REL_UNIT_THURSDAY,
/** @draft ICU 57 */
UDAT_REL_UNIT_FRIDAY,
/** @draft ICU 57 */
UDAT_REL_UNIT_SATURDAY,
/** @draft ICU 57 */
UDAT_REL_UNIT_COUNT
} URelativeDateTimeUnit;
#endif /* U_HIDE_DRAFT_API */
#ifndef U_HIDE_DRAFT_API
/**
* Opaque URelativeDateTimeFormatter object for use in C programs.
* @draft ICU 57
*/
struct URelativeDateTimeFormatter;
typedef struct URelativeDateTimeFormatter URelativeDateTimeFormatter; /**< C typedef for struct URelativeDateTimeFormatter. @draft ICU 57 */
/**
* Open a new URelativeDateTimeFormatter object for a given locale using the
* specified width and capitalizationContext, along with a number formatter
* (if desired) to override the default formatter that would be used for
* display of numeric field offsets. The default formatter typically rounds
* toward 0 and has a minimum of 0 fraction digits and a maximum of 3
* fraction digits (i.e. it will show as many decimal places as necessary
* up to 3, without showing trailing 0s).
*
* @param locale
* The locale
* @param nfToAdopt
* A number formatter to set for this URelativeDateTimeFormatter
* object (instead of the default decimal formatter). Ownership of
* this UNumberFormat object will pass to the URelativeDateTimeFormatter
* object (the URelativeDateTimeFormatter adopts the UNumberFormat),
* which becomes responsible for closing it. If the caller wishes to
* retain ownership of the UNumberFormat object, the caller must clone
* it (with unum_clone) and pass the clone to ureldatefmt_open. May be
* NULL to use the default decimal formatter.
* @param width
* The width - wide, short, narrow, etc.
* @param capitalizationContext
* A value from UDisplayContext that pertains to capitalization, e.g.
* UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE.
* @param status
* A pointer to a UErrorCode to receive any errors.
* @return
* A pointer to a URelativeDateTimeFormatter object for the specified locale,
* or NULL if an error occurred.
* @draft ICU 57
*/
U_DRAFT URelativeDateTimeFormatter* U_EXPORT2
ureldatefmt_open( const char* locale,
UNumberFormat* nfToAdopt,
UDateRelativeDateTimeFormatterStyle width,
UDisplayContext capitalizationContext,
UErrorCode* status );
/**
* Close a URelativeDateTimeFormatter object. Once closed it may no longer be used.
* @param reldatefmt
* The URelativeDateTimeFormatter object to close.
* @draft ICU 57
*/
U_DRAFT void U_EXPORT2
ureldatefmt_close(URelativeDateTimeFormatter *reldatefmt);
#if U_SHOW_CPLUSPLUS_API
U_NAMESPACE_BEGIN
/**
* \class LocalURelativeDateTimeFormatterPointer
* "Smart pointer" class, closes a URelativeDateTimeFormatter via ureldatefmt_close().
* For most methods see the LocalPointerBase base class.
*
* @see LocalPointerBase
* @see LocalPointer
* @draft ICU 57
*/
U_DEFINE_LOCAL_OPEN_POINTER(LocalURelativeDateTimeFormatterPointer, URelativeDateTimeFormatter, ureldatefmt_close);
U_NAMESPACE_END
#endif
/**
* Format a combination of URelativeDateTimeUnit and numeric
* offset using a numeric style, e.g. "1 week ago", "in 1 week",
* "5 weeks ago", "in 5 weeks".
*
* @param reldatefmt
* The URelativeDateTimeFormatter object specifying the
* format conventions.
* @param offset
* The signed offset for the specified unit. This will
* be formatted according to this object's UNumberFormat
* object.
* @param unit
* The unit to use when formatting the relative
* date, e.g. UDAT_REL_UNIT_WEEK, UDAT_REL_UNIT_FRIDAY.
* @param result
* A pointer to a buffer to receive the formatted result.
* @param resultCapacity
* The maximum size of result.
* @param status
* A pointer to a UErrorCode to receive any errors. In
* case of error status, the contents of result are
* undefined.
* @return
* The length of the formatted result; may be greater
* than resultCapacity, in which case an error is returned.
* @draft ICU 57
*/
U_DRAFT int32_t U_EXPORT2
ureldatefmt_formatNumeric( const URelativeDateTimeFormatter* reldatefmt,
double offset,
URelativeDateTimeUnit unit,
UChar* result,
int32_t resultCapacity,
UErrorCode* status);
/**
* Format a combination of URelativeDateTimeUnit and numeric offset
* using a text style if possible, e.g. "last week", "this week",
* "next week", "yesterday", "tomorrow". Falls back to numeric
* style if no appropriate text term is available for the specified
* offset in the objects locale.
*
* @param reldatefmt
* The URelativeDateTimeFormatter object specifying the
* format conventions.
* @param offset
* The signed offset for the specified unit.
* @param unit
* The unit to use when formatting the relative
* date, e.g. UDAT_REL_UNIT_WEEK, UDAT_REL_UNIT_FRIDAY.
* @param result
* A pointer to a buffer to receive the formatted result.
* @param resultCapacity
* The maximum size of result.
* @param status
* A pointer to a UErrorCode to receive any errors. In
* case of error status, the contents of result are
* undefined.
* @return
* The length of the formatted result; may be greater
* than resultCapacity, in which case an error is returned.
* @draft ICU 57
*/
U_DRAFT int32_t U_EXPORT2
ureldatefmt_format( const URelativeDateTimeFormatter* reldatefmt,
double offset,
URelativeDateTimeUnit unit,
UChar* result,
int32_t resultCapacity,
UErrorCode* status);
/**
* Combines a relative date string and a time string in this object's
* locale. This is done with the same date-time separator used for the
* default calendar in this locale to produce a result such as
* "yesterday at 3:45 PM".
*
* @param reldatefmt
* The URelativeDateTimeFormatter object specifying the format conventions.
* @param relativeDateString
* The relative date string.
* @param relativeDateStringLen
* The length of relativeDateString; may be -1 if relativeDateString
* is zero-terminated.
* @param timeString
* The time string.
* @param timeStringLen
* The length of timeString; may be -1 if timeString is zero-terminated.
* @param result
* A pointer to a buffer to receive the formatted result.
* @param resultCapacity
* The maximum size of result.
* @param status
* A pointer to a UErrorCode to receive any errors. In case of error status,
* the contents of result are undefined.
* @return
* The length of the formatted result; may be greater than resultCapacity,
* in which case an error is returned.
* @draft ICU 57
*/
U_DRAFT int32_t U_EXPORT2
ureldatefmt_combineDateAndTime( const URelativeDateTimeFormatter* reldatefmt,
const UChar * relativeDateString,
int32_t relativeDateStringLen,
const UChar * timeString,
int32_t timeStringLen,
UChar* result,
int32_t resultCapacity,
UErrorCode* status );
#endif /* U_HIDE_DRAFT_API */
#endif /* !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION */
#endif

View file

@ -1,6 +1,6 @@
#******************************************************************************
#
# Copyright (C) 1999-2015, International Business Machines
# Copyright (C) 1999-2016, International Business Machines
# Corporation and others. All Rights Reserved.
#
#******************************************************************************
@ -42,7 +42,7 @@ ccaltst.o ucnvseltst.o cctest.o ccapitst.o ccolltst.o encoll.o cconvtst.o ccurrt
cdateintervalformattest.o cdattst.o cdetst.o cdtdptst.o cdtrgtst.o cestst.o cfintst.o \
cformtst.o cfrtst.o cg7coll.o chashtst.o cintltst.o citertst.o cjaptst.o cloctst.o \
cmsccoll.o cmsgtst.o cpluralrulestest.o cposxtst.o cldrtest.o \
cnmdptst.o cnormtst.o cnumtst.o crestst.o creststn.o cturtst.o \
cnmdptst.o cnormtst.o cnumtst.o crelativedateformattest.o crestst.o creststn.o cturtst.o \
cucdapi.o cucdtst.o custrtst.o cstrcase.o cutiltst.o nucnvtst.o nccbtst.o bocu1tst.o \
cbiditst.o cbididat.o eurocreg.o udatatst.o utf16tst.o utransts.o \
ncnvfbts.o ncnvtst.o putiltst.o cstrtest.o udatpg_test.o utf8tst.o \

View file

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2015, International Business Machines
* Copyright (c) 1997-2016, International Business Machines
* Corporation and others. All Rights Reserved.
********************************************************************/
/********************************************************************************
@ -26,6 +26,7 @@ void addCalTest(TestNode**);
void addDateForTest(TestNode**);
void addDateTimePatternGeneratorTest(TestNode**);
void addDateIntervalFormatTest(TestNode**);
void addRelativeDateFormatTest(TestNode**);
void addNumForTest(TestNode**);
void addMsgForTest(TestNode**);
void addDateForRgrTest(TestNode**);
@ -45,6 +46,7 @@ void addFormatTest(TestNode** root)
addDateForTest(root);
addDateTimePatternGeneratorTest(root);
addDateIntervalFormatTest(root);
addRelativeDateFormatTest(root);
addNumForTest(root);
addNumFrDepTest(root);
addMsgForTest(root);

View file

@ -287,6 +287,7 @@
<ClCompile Include="cldrtest.c" />
<ClCompile Include="cloctst.c" />
<ClCompile Include="cposxtst.c" />
<ClCompile Include="crelativedateformattest.c" />
<ClCompile Include="crestst.c" />
<ClCompile Include="creststn.c" />
<ClCompile Include="calltest.c" />

View file

@ -198,6 +198,9 @@
<ClCompile Include="cpluralrulestest.c">
<Filter>formatting</Filter>
</ClCompile>
<ClCompile Include="crelativedateformattest.c">
<Filter>formatting</Filter>
</ClCompile>
<ClCompile Include="currtest.c">
<Filter>formatting</Filter>
</ClCompile>

View file

@ -0,0 +1,111 @@
/********************************************************************
* Copyright (c) 2016, International Business Machines Corporation
* and others. All Rights Reserved.
********************************************************************/
/* C API TEST FOR DATE INTERVAL FORMAT */
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION
#include "unicode/ureldatefmt.h"
#include "unicode/unum.h"
#include "unicode/udisplaycontext.h"
#include "unicode/ustring.h"
#include "cintltst.h"
#include "cmemory.h"
static void TestRelDateFmtx(void);
#define LEN(a) (sizeof(a)/sizeof(a[0]))
void addRelativeDateFormatTest(TestNode** root);
#define TESTCASE(x) addTest(root, &x, "tsformat/crelativedateformattest/" #x)
void addRelativeDateFormatTest(TestNode** root)
{
TESTCASE(TestRelDateFmtx);
}
static const double offsets[] = { -5.0, -2.2, -1.0, -0.7, 0.0, 0.7, 1.0, 2.2, 5.0 };
enum { kNumOffsets = UPRV_LENGTHOF(offsets) };
static const char* en_defNum_long_midSent_week[kNumOffsets*2] = {
/* text numeric */
"5 weeks ago", "5 weeks ago",
"2.2 weeks ago", "2.2 weeks ago",
"last week", "1 week ago",
"last week", "0.7 weeks ago",
"this week", "in 0 weeks",
"next week", "in 0.7 weeks",
"next week", "in 1 week",
"in 2.2 weeks", "in 2.2 weeks",
"in 5 weeks", "in 5 weeks",
};
typedef struct {
const char* locale;
int32_t decPlaces; /* fixed decimal places; -1 to use default num formatter */
UDateRelativeDateTimeFormatterStyle width;
UDisplayContext capContext;
URelativeDateTimeUnit unit;
const char ** expectedResults; /* for the various offsets */
} RelDateTimeFormatTestItem;
static const RelDateTimeFormatTestItem testItems[] = {
{ "en", -1, UDAT_STYLE_LONG, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UDAT_REL_UNIT_WEEK, en_defNum_long_midSent_week },
{ NULL, 0, (UDateRelativeDateTimeFormatterStyle)0, (UDisplayContext)0, (URelativeDateTimeUnit)0, NULL } /* terminator */
};
enum { kMaxUBuf = 64 };
static void TestRelDateFmtx()
{
const RelDateTimeFormatTestItem *itemPtr;
log_verbose("\nTesting ureldatefmt_open(), ureldatefmt_format(), ureldatefmt_formatNumeric() with various parameters\n");
for (itemPtr = testItems; itemPtr->locale != NULL; itemPtr++) {
URelativeDateTimeFormatter *reldatefmt = NULL;
UNumberFormat* nfToAdopt = NULL;
UErrorCode status = U_ZERO_ERROR;
int32_t iOffset;
if (itemPtr->decPlaces >= 0) {
nfToAdopt = unum_open(UNUM_DECIMAL, NULL, 0, itemPtr->locale, NULL, &status);
if ( U_FAILURE(status) ) {
log_data_err("FAIL: unum_open(UNUM_DECIMAL, ...) for locale %s: %s\n", itemPtr->locale, myErrorName(status));
}
unum_setAttribute(nfToAdopt, UNUM_MIN_FRACTION_DIGITS, itemPtr->decPlaces);
unum_setAttribute(nfToAdopt, UNUM_MAX_FRACTION_DIGITS, itemPtr->decPlaces);
unum_setAttribute(nfToAdopt, UNUM_ROUNDING_MODE, UNUM_ROUND_DOWN);
}
reldatefmt = ureldatefmt_open(itemPtr->locale, nfToAdopt, itemPtr->width, itemPtr->capContext, &status);
if ( U_FAILURE(status) ) {
log_data_err("FAIL: ureldatefmt_open() for locale %s: %s\n", itemPtr->locale, myErrorName(status));
}
for (iOffset = 0; iOffset < kNumOffsets; iOffset++) {
UChar ubuf[kMaxUBuf];
int32_t ulen;
status = U_ZERO_ERROR;
ulen = ureldatefmt_format(reldatefmt, offsets[iOffset], itemPtr->unit, ubuf, kMaxUBuf, &status);
/* check results */
status = U_ZERO_ERROR;
ulen = ureldatefmt_formatNumeric(reldatefmt, offsets[iOffset], itemPtr->unit, ubuf, kMaxUBuf, &status);
/* check results */
}
ureldatefmt_close(reldatefmt);
}
/*
log_err("ERROR: udtitvfmt_format for locale %s, skeleton %s, tzid %s, from %.1f, to %.1f: expect %s, get %s\n",
log_err("FAIL: udtitvfmt_format for locale %s, skeleton %s, tzid %s, from %.1f, to %.1f: %s\n",
log_data_err("FAIL: udtitvfmt_open for locale %s, skeleton %s, tzid %s - %s\n",
*/
}
#endif /* #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION */