diff --git a/.gitattributes b/.gitattributes
index 87b2557fb8f..2b93351a80d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -88,6 +88,8 @@ icu4c/source/extra/uconv/uconv.vcxproj -text
icu4c/source/extra/uconv/uconv.vcxproj.filters -text
icu4c/source/i18n/i18n.vcxproj -text
icu4c/source/i18n/i18n.vcxproj.filters -text
+icu4c/source/i18n/ufieldpositer.cpp -text
+icu4c/source/i18n/unicode/ufieldpositer.h -text
icu4c/source/io/io.vcxproj -text
icu4c/source/io/io.vcxproj.filters -text
icu4c/source/layout/layout.vcxproj -text
diff --git a/icu4c/source/i18n/Makefile.in b/icu4c/source/i18n/Makefile.in
index 8517dd50c92..bb730d6a44d 100644
--- a/icu4c/source/i18n/Makefile.in
+++ b/icu4c/source/i18n/Makefile.in
@@ -1,6 +1,6 @@
#******************************************************************************
#
-# Copyright (C) 1998-2014, International Business Machines
+# Copyright (C) 1998-2015, International Business Machines
# Corporation and others. All Rights Reserved.
#
#******************************************************************************
@@ -91,7 +91,7 @@ wintzimpl.o windtfmt.o winnmfmt.o basictz.o dtrule.o rbtz.o tzrule.o tztrans.o v
upluralrules.o plurrule.o plurfmt.o selfmt.o dtitvfmt.o dtitvinf.o udateintervalformat.o \
tmunit.o tmutamt.o tmutfmt.o currpinf.o \
uspoof.o uspoof_impl.o uspoof_build.o uspoof_conf.o uspoof_wsconf.o decfmtst.o smpdtfst.o \
-ztrans.o zrule.o vzone.o fphdlimp.o fpositer.o locdspnm.o \
+ztrans.o zrule.o vzone.o fphdlimp.o fpositer.o ufieldpositer.o locdspnm.o \
decNumber.o decContext.o alphaindex.o tznames.o tznames_impl.o tzgnames.o \
tzfmt.o compactdecimalformat.o gender.o region.o scriptset.o identifier_info.o \
uregion.o reldatefmt.o quantityformatter.o measunit.o filteredbrk.o \
diff --git a/icu4c/source/i18n/i18n.vcxproj b/icu4c/source/i18n/i18n.vcxproj
index d34987efc0b..caa286e6aa8 100644
--- a/icu4c/source/i18n/i18n.vcxproj
+++ b/icu4c/source/i18n/i18n.vcxproj
@@ -365,6 +365,7 @@
+
@@ -1421,6 +1422,20 @@
..\..\include\unicode\%(Filename)%(Extension);%(Outputs)
copy "%(FullPath)" ..\..\include\unicode
+
+ ..\..\include\unicode\%(Filename)%(Extension);%(Outputs)
+
+
+ copy "%(FullPath)" ..\..\include\unicode
+
+ ..\..\include\unicode\%(Filename)%(Extension);%(Outputs)
+ copy "%(FullPath)" ..\..\include\unicode
+
+ ..\..\include\unicode\%(Filename)%(Extension);%(Outputs)
+ copy "%(FullPath)" ..\..\include\unicode
+
+ ..\..\include\unicode\%(Filename)%(Extension);%(Outputs)
+ copy "%(FullPath)" ..\..\include\unicode
..\..\include\unicode\%(Filename)%(Extension);%(Outputs)
diff --git a/icu4c/source/i18n/i18n.vcxproj.filters b/icu4c/source/i18n/i18n.vcxproj.filters
index 9c518b81510..6658a482c8b 100644
--- a/icu4c/source/i18n/i18n.vcxproj.filters
+++ b/icu4c/source/i18n/i18n.vcxproj.filters
@@ -282,6 +282,9 @@
formatting
+
+ formatting
+
formatting
@@ -1134,6 +1137,9 @@
formatting
+
+ formatting
+
formatting
diff --git a/icu4c/source/i18n/udat.cpp b/icu4c/source/i18n/udat.cpp
index 2ad49c88e21..96890cfabb1 100644
--- a/icu4c/source/i18n/udat.cpp
+++ b/icu4c/source/i18n/udat.cpp
@@ -22,6 +22,7 @@
#include "unicode/dtfmtsym.h"
#include "unicode/ustring.h"
#include "unicode/udisplaycontext.h"
+#include "unicode/ufieldpositer.h"
#include "cpputils.h"
#include "reldtfmt.h"
#include "umutex.h"
@@ -269,6 +270,50 @@ udat_formatCalendar(const UDateFormat* format,
return res.extract(result, resultLength, *status);
}
+U_CAPI int32_t U_EXPORT2
+udat_formatForFields( const UDateFormat* format,
+ UDate dateToFormat,
+ UChar* result,
+ int32_t resultLength,
+ UFieldPositionIterator* fpositer,
+ 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);
+ }
+
+ ((DateFormat*)format)->format(dateToFormat, res, (FieldPositionIterator*)fpositer, *status);
+
+ return res.extract(result, resultLength, *status);
+}
+
+U_CAPI int32_t U_EXPORT2
+udat_formatCalendarForFields(const UDateFormat* format,
+ UCalendar* calendar,
+ UChar* result,
+ int32_t resultLength,
+ UFieldPositionIterator* fpositer,
+ 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);
+ }
+
+ ((DateFormat*)format)->format(*(Calendar*)calendar, res, (FieldPositionIterator*)fpositer, *status);
+
+ 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/ufieldpositer.cpp b/icu4c/source/i18n/ufieldpositer.cpp
new file mode 100644
index 00000000000..7f8688425d6
--- /dev/null
+++ b/icu4c/source/i18n/ufieldpositer.cpp
@@ -0,0 +1,59 @@
+/*
+*****************************************************************************************
+* Copyright (C) 2015, International Business Machines
+* Corporation and others. All Rights Reserved.
+*****************************************************************************************
+*/
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/ufieldpositer.h"
+#include "unicode/fpositer.h"
+#include "unicode/localpointer.h"
+
+U_NAMESPACE_USE
+
+
+U_CAPI UFieldPositionIterator* U_EXPORT2
+ufieldpositer_open(UErrorCode* status)
+{
+ if (U_FAILURE(*status)) {
+ return NULL;
+ }
+ FieldPositionIterator* fpositer = new FieldPositionIterator();
+ if (fpositer == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ }
+ return (UFieldPositionIterator*)fpositer;
+}
+
+
+U_CAPI void U_EXPORT2
+ufieldpositer_close(UFieldPositionIterator *fpositer)
+{
+ delete (FieldPositionIterator*)fpositer;
+}
+
+
+U_CAPI int32_t U_EXPORT2
+ufieldpositer_next(UFieldPositionIterator *fpositer,
+ int32_t *beginIndex, int32_t *endIndex)
+{
+ FieldPosition fp;
+ int32_t field = -1;
+ if (((FieldPositionIterator*)fpositer)->next(fp)) {
+ field = fp.getField();
+ if (beginIndex) {
+ *beginIndex = fp.getBeginIndex();
+ }
+ if (endIndex) {
+ *endIndex = fp.getEndIndex();
+ }
+ }
+ return field;
+}
+
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
diff --git a/icu4c/source/i18n/unicode/udat.h b/icu4c/source/i18n/unicode/udat.h
index 5add1516841..4cea93c649a 100644
--- a/icu4c/source/i18n/unicode/udat.h
+++ b/icu4c/source/i18n/unicode/udat.h
@@ -16,6 +16,7 @@
#include "unicode/ucal.h"
#include "unicode/unum.h"
#include "unicode/udisplaycontext.h"
+#include "unicode/ufieldpositer.h"
/**
* \file
* \brief C API: DateFormat
@@ -945,7 +946,7 @@ udat_clone(const UDateFormat *fmt,
UErrorCode *status);
/**
-* Format a date using an UDateFormat.
+* Format a date using a UDateFormat.
* The date will be formatted using the conventions specified in {@link #udat_open }
* @param format The formatter to use
* @param dateToFormat The date to format
@@ -976,8 +977,8 @@ udat_format( const UDateFormat* format,
* 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
+* mutated if fields are not yet fully calculated, though
+* the 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.
@@ -1000,6 +1001,80 @@ udat_formatCalendar( const UDateFormat* format,
int32_t capacity,
UFieldPosition* position,
UErrorCode* status);
+
+/**
+* Format a date using a UDateFormat.
+* The date will be formatted using the conventions specified in {@link #udat_open}
+* @param format
+* The formatter to use
+* @param dateToFormat
+* The date to format
+* @param result
+* A pointer to a buffer to receive the formatted number.
+* @param resultLength
+* The maximum size of result.
+* @param fpositer
+* A pointer to a UFieldPositionIterator created by {@link #ufieldpositer_open}
+* (may be NULL if field position information is not needed). Any
+* iteration information already present in the UFieldPositionIterator
+* will be deleted, and the iterator will be reset to apply to the
+* fields in the formatted string created by this function call; the
+* field values provided by {@link #ufieldpositer_next} will be from the
+* UDateFormatField enum.
+* @param status
+* A pointer to a UErrorCode to receive any errors
+* @return
+* The total buffer size needed; if greater than resultLength, the output was truncated.
+* @see udat_parse
+* @see UFieldPositionIterator
+* @draft ICU 55
+*/
+U_DRAFT int32_t U_EXPORT2
+udat_formatForFields( const UDateFormat* format,
+ UDate dateToFormat,
+ UChar* result,
+ int32_t resultLength,
+ UFieldPositionIterator* fpositer,
+ UErrorCode* status);
+
+/**
+* Format a date using a 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 if fields
+* are not yet fully calculated, though the 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 fpositer
+* A pointer to a UFieldPositionIterator created by {@link #ufieldpositer_open}
+* (may be NULL if field position information is not needed). Any
+* iteration information already present in the UFieldPositionIterator
+* will be deleted, and the iterator will be reset to apply to the
+* fields in the formatted string created by this function call; the
+* field values provided by {@link #ufieldpositer_next} will be from the
+* UDateFormatField enum.
+* @param status
+* A pointer to a 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 UFieldPositionIterator
+* @draft ICU 55
+*/
+U_DRAFT int32_t U_EXPORT2
+udat_formatCalendarForFields( const UDateFormat* format,
+ UCalendar* calendar,
+ UChar* result,
+ int32_t capacity,
+ UFieldPositionIterator* fpositer,
+ UErrorCode* status);
+
#endif /* U_HIDE_DRAFT_API */
/**
@@ -1341,40 +1416,40 @@ typedef enum UDateFormatSymbolType {
UDAT_STANDALONE_SHORTER_WEEKDAYS
#ifndef U_HIDE_DRAFT_API
,
- /**
- * Cyclic year names (only supported for some calendars, and only for FORMAT usage;
- * udat_setSymbols not supported for UDAT_CYCLIC_YEARS_WIDE)
- * @draft ICU 54
- */
- UDAT_CYCLIC_YEARS_WIDE,
- /**
- * Cyclic year names (only supported for some calendars, and only for FORMAT usage)
- * @draft ICU 54
- */
- UDAT_CYCLIC_YEARS_ABBREVIATED,
- /**
- * Cyclic year names (only supported for some calendars, and only for FORMAT usage;
- * udat_setSymbols not supported for UDAT_CYCLIC_YEARS_NARROW)
- * @draft ICU 54
- */
- UDAT_CYCLIC_YEARS_NARROW,
- /**
- * Calendar zodiac names (only supported for some calendars, and only for FORMAT usage;
- * udat_setSymbols not supported for UDAT_ZODIAC_NAMES_WIDE)
- * @draft ICU 54
- */
- UDAT_ZODIAC_NAMES_WIDE,
- /**
- * Calendar zodiac names (only supported for some calendars, and only for FORMAT usage)
- * @draft ICU 54
- */
- UDAT_ZODIAC_NAMES_ABBREVIATED,
- /**
- * Calendar zodiac names (only supported for some calendars, and only for FORMAT usage;
- * udat_setSymbols not supported for UDAT_ZODIAC_NAMES_NARROW)
- * @draft ICU 54
- */
- UDAT_ZODIAC_NAMES_NARROW
+ /**
+ * Cyclic year names (only supported for some calendars, and only for FORMAT usage;
+ * udat_setSymbols not supported for UDAT_CYCLIC_YEARS_WIDE)
+ * @draft ICU 54
+ */
+ UDAT_CYCLIC_YEARS_WIDE,
+ /**
+ * Cyclic year names (only supported for some calendars, and only for FORMAT usage)
+ * @draft ICU 54
+ */
+ UDAT_CYCLIC_YEARS_ABBREVIATED,
+ /**
+ * Cyclic year names (only supported for some calendars, and only for FORMAT usage;
+ * udat_setSymbols not supported for UDAT_CYCLIC_YEARS_NARROW)
+ * @draft ICU 54
+ */
+ UDAT_CYCLIC_YEARS_NARROW,
+ /**
+ * Calendar zodiac names (only supported for some calendars, and only for FORMAT usage;
+ * udat_setSymbols not supported for UDAT_ZODIAC_NAMES_WIDE)
+ * @draft ICU 54
+ */
+ UDAT_ZODIAC_NAMES_WIDE,
+ /**
+ * Calendar zodiac names (only supported for some calendars, and only for FORMAT usage)
+ * @draft ICU 54
+ */
+ UDAT_ZODIAC_NAMES_ABBREVIATED,
+ /**
+ * Calendar zodiac names (only supported for some calendars, and only for FORMAT usage;
+ * udat_setSymbols not supported for UDAT_ZODIAC_NAMES_NARROW)
+ * @draft ICU 54
+ */
+ UDAT_ZODIAC_NAMES_NARROW
#endif /* U_HIDE_DRAFT_API */
} UDateFormatSymbolType;
diff --git a/icu4c/source/i18n/unicode/ufieldpositer.h b/icu4c/source/i18n/unicode/ufieldpositer.h
new file mode 100644
index 00000000000..6cc9ffada49
--- /dev/null
+++ b/icu4c/source/i18n/unicode/ufieldpositer.h
@@ -0,0 +1,121 @@
+/*
+*****************************************************************************************
+* Copyright (C) 2015, International Business Machines
+* Corporation and others. All Rights Reserved.
+*****************************************************************************************
+*/
+
+#ifndef UFIELDPOSITER_H
+#define UFIELDPOSITER_H
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+#ifndef U_HIDE_DRAFT_API
+
+#include "unicode/localpointer.h"
+
+/**
+ * \file
+ * \brief C API: UFieldPositionIterator for use with format APIs.
+ *
+ * Usage:
+ * ufieldpositer_open creates an empty (unset) UFieldPositionIterator.
+ * This can be passed to format functions such as {@link #udat_formatForFields},
+ * which will set it to apply to the fields in a particular formatted string.
+ * ufieldpositer_next can then be used to iterate over those fields,
+ * providing for each field its type (using values that are specific to the
+ * particular format type, such as date or number formats), as well as the
+ * start and end positions of the field in the formatted string.
+ * A given UFieldPositionIterator can be re-used for different format calls;
+ * each such call resets it to apply to that format string.
+ * ufieldpositer_close should be called to dispose of the UFieldPositionIterator
+ * when it is no longer needed.
+ *
+ * @see FieldPositionIterator
+ */
+
+/**
+ * Opaque UFieldPositionIterator object for use in C.
+ * @draft ICU 55
+ */
+struct UFieldPositionIterator;
+typedef struct UFieldPositionIterator UFieldPositionIterator; /**< C typedef for struct UFieldPositionIterator. @draft ICU 55 */
+
+/**
+ * Open a new, unset UFieldPositionIterator object.
+ * @param status
+ * A pointer to a UErrorCode to receive any errors.
+ * @return
+ * A pointer to an empty (unset) UFieldPositionIterator object,
+ * or NULL if an error occurred.
+ * @draft ICU 55
+ */
+U_DRAFT UFieldPositionIterator* U_EXPORT2
+ufieldpositer_open(UErrorCode* status);
+
+/**
+ * Close a UFieldPositionIterator object. Once closed it may no longer be used.
+ * @param fpositer
+ * A pointer to the UFieldPositionIterator object to close.
+ * @draft ICU 55
+ */
+U_DRAFT void U_EXPORT2
+ufieldpositer_close(UFieldPositionIterator *fpositer);
+
+
+#if U_SHOW_CPLUSPLUS_API
+
+U_NAMESPACE_BEGIN
+
+/**
+ * \class LocalUFieldPositionIteratorPointer
+ * "Smart pointer" class, closes a UFieldPositionIterator via ufieldpositer_close().
+ * For most methods see the LocalPointerBase base class.
+ *
+ * @see LocalPointerBase
+ * @see LocalPointer
+ * @draft ICU 55
+ */
+U_DEFINE_LOCAL_OPEN_POINTER(LocalUFieldPositionIteratorPointer, UFieldPositionIterator, ufieldpositer_close);
+
+U_NAMESPACE_END
+
+#endif
+
+/**
+ * Get information for the next field in the formatted string to which this
+ * UFieldPositionIterator currently applies, or return FALSE if there are
+ * no more fields.
+ * @param fpositer
+ * A pointer to the UFieldPositionIterator object containing iteration
+ * state for the format fields.
+ * @param beginIndex
+ * A pointer to an int32_t to receive information about the start offset
+ * of the field in the formatted string (undefined if the function
+ * returns a negative value). May be NULL if this information is not needed.
+ * @param endIndex
+ * A pointer to an int32_t to receive information about the end offset
+ * of the field in the formatted string (undefined if the function
+ * returns a negative value). May be NULL if this information is not needed.
+ * @return
+ * The field type (non-negative value), or a negative value if there are
+ * no more fields for which to provide information. If negative, then any
+ * values pointed to by beginIndex and endIndex are undefined.
+ *
+ * The values for field type depend on what type of formatter the
+ * UFieldPositionIterator has been set by; for a date formatter, the
+ * values from the UDateFormatField enum. For more information, see the
+ * descriptions of format functions that take a UFieldPositionIterator*
+ * parameter, such as {@link #udat_formatForFields}.
+ *
+ * @draft ICU 55
+ */
+U_DRAFT int32_t U_EXPORT2
+ufieldpositer_next(UFieldPositionIterator *fpositer,
+ int32_t *beginIndex, int32_t *endIndex);
+
+#endif /* U_HIDE_DRAFT_API */
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif
diff --git a/icu4c/source/test/cintltst/cdattst.c b/icu4c/source/test/cintltst/cdattst.c
index fec9f2640ee..aef58d07660 100644
--- a/icu4c/source/test/cintltst/cdattst.c
+++ b/icu4c/source/test/cintltst/cdattst.c
@@ -25,6 +25,7 @@
#include "unicode/ucal.h"
#include "unicode/unum.h"
#include "unicode/ustring.h"
+#include "unicode/ufieldpositer.h"
#include "cintltst.h"
#include "cdattst.h"
#include "cformtst.h"
@@ -38,6 +39,7 @@ static void TestRelativeCrash(void);
static void TestContext(void);
static void TestCalendarDateParse(void);
static void TestParseErrorReturnValue(void);
+static void TestFormatForFields(void);
#define LEN(a) (sizeof(a)/sizeof(a[0]))
@@ -58,6 +60,7 @@ void addDateForTest(TestNode** root)
TESTCASE(TestCalendarDateParse);
TESTCASE(TestOverrideNumberFormat);
TESTCASE(TestParseErrorReturnValue);
+ TESTCASE(TestFormatForFields);
}
/* Testing the DateFormat API */
static void TestDateFormat()
@@ -1734,4 +1737,103 @@ static void TestParseErrorReturnValue(void) {
udat_close(df);
}
+/*
+ * Ticket #11553
+ * Test new udat_formatForFields, udat_formatCalendarForFields (and UFieldPositionIterator)
+ */
+static const char localeForFields[] = "en_US";
+/* zoneGMT[]defined above */
+static const UDate date2015Feb25 = 1424841000000.0; /* Wednesday, February 25, 2015 at 5:10:00 AM GMT */
+
+typedef struct {
+ int32_t field;
+ int32_t beginPos;
+ int32_t endPos;
+} FieldsData;
+static const FieldsData expectedFields[] = {
+ { UDAT_DAY_OF_WEEK_FIELD /* 9*/, 0, 9 },
+ { UDAT_MONTH_FIELD /* 2*/, 11, 19 },
+ { UDAT_DATE_FIELD /* 3*/, 20, 22 },
+ { UDAT_YEAR_FIELD /* 1*/, 24, 28 },
+ { UDAT_HOUR1_FIELD /*15*/, 32, 33 },
+ { UDAT_TIME_SEPARATOR_FIELD /*35*/, 33, 34 },
+ { UDAT_MINUTE_FIELD /* 6*/, 34, 36 },
+ { UDAT_TIME_SEPARATOR_FIELD /*35*/, 36, 37 },
+ { UDAT_SECOND_FIELD /* 7*/, 37, 39 },
+ { UDAT_AM_PM_FIELD /*14*/, 40, 42 },
+ { UDAT_TIMEZONE_FIELD /*17*/, 43, 46 },
+ { -1, -1, -1 },
+};
+
+enum {kUBufFieldsLen = 128, kBBufFieldsLen = 256 };
+
+static void TestFormatForFields(void) {
+ UErrorCode status = U_ZERO_ERROR;
+ UFieldPositionIterator* fpositer = ufieldpositer_open(&status);
+ if ( U_FAILURE(status) ) {
+ log_err("ufieldpositer_open fails, status %s\n", u_errorName(status));
+ } else {
+ UDateFormat* udfmt = udat_open(UDAT_LONG, UDAT_FULL, localeForFields, zoneGMT, -1, NULL, 0, &status);
+ UCalendar* ucal = ucal_open(zoneGMT, -1, localeForFields, UCAL_DEFAULT, &status);
+ if ( U_FAILURE(status) ) {
+ log_data_err("udat_open or ucal_open fails for locale %s, status %s (Are you missing data?)\n", localeForFields, u_errorName(status));
+ } else {
+ int32_t ulen, field, beginPos, endPos;
+ UChar ubuf[kUBufFieldsLen];
+ const FieldsData * fptr;
+
+ status = U_ZERO_ERROR;
+ ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status);
+ if ( U_FAILURE(status) ) {
+ log_err("udat_formatForFields fails, status %s\n", u_errorName(status));
+ } else {
+ for (fptr = expectedFields; ; fptr++) {
+ field = ufieldpositer_next(fpositer, &beginPos, &endPos);
+ if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
+ if (fptr->field >= 0) {
+ log_err("udat_formatForFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
+ aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
+ } else {
+ log_err("udat_formatForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
+ aescstrdup(ubuf, ulen), field, beginPos, endPos);
+ }
+ break;
+ }
+ if (field < 0) {
+ break;
+ }
+ }
+ }
+
+ ucal_setMillis(ucal, date2015Feb25, &status);
+ status = U_ZERO_ERROR;
+ ulen = udat_formatCalendarForFields(udfmt, ucal, ubuf, kUBufFieldsLen, fpositer, &status);
+ if ( U_FAILURE(status) ) {
+ log_err("udat_formatCalendarForFields fails, status %s\n", u_errorName(status));
+ } else {
+ for (fptr = expectedFields; ; fptr++) {
+ field = ufieldpositer_next(fpositer, &beginPos, &endPos);
+ if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
+ if (fptr->field >= 0) {
+ log_err("udat_formatFudat_formatCalendarForFieldsorFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
+ aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
+ } else {
+ log_err("udat_formatCalendarForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
+ aescstrdup(ubuf, ulen), field, beginPos, endPos);
+ }
+ break;
+ }
+ if (field < 0) {
+ break;
+ }
+ }
+ }
+
+ ucal_close(ucal);
+ udat_close(udfmt);
+ }
+ ufieldpositer_close(fpositer);
+ }
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */