+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2016, International Business Machines Corporation and
#include "cdattst.h"
#include "cformtst.h"
#include "cmemory.h"
+#if !U_PLATFORM_HAS_WIN32_API
#include "unicode/uatimeunitformat.h" /* Apple-specific */
+#endif
#include <math.h>
static void TestCalendarDateParse(void);
static void TestParseErrorReturnValue(void);
static void TestFormatForFields(void);
+static void TestForceGannenNumbering(void);
static void TestStandardPatterns(void);
static void TestApplyPatnOverridesTimeSep(void);
static void Test12HrFormats(void);
+#if !U_PLATFORM_HAS_WIN32_API
static void TestTimeUnitFormat(void); /* Apple-specific */
+#endif
static void TestRemapPatternWithOpts(void); /* Apple-specific */
void addDateForTest(TestNode** root);
TESTCASE(TestOverrideNumberFormat);
TESTCASE(TestParseErrorReturnValue);
TESTCASE(TestFormatForFields);
+ TESTCASE(TestForceGannenNumbering);
TESTCASE(TestStandardPatterns);
TESTCASE(TestApplyPatnOverridesTimeSep);
TESTCASE(Test12HrFormats);
+#if !U_PLATFORM_HAS_WIN32_API
TESTCASE(TestTimeUnitFormat); /* Apple-specific */
+#endif
TESTCASE(TestRemapPatternWithOpts); /* Apple-specific */
}
/* Testing the DateFormat API */
{ NULL, (UDisplayContext)0, NULL, NULL }
};
+static const UChar january_esDefault[] = { 0x65,0x6E,0x65,0x72,0x6F,0 }; /* "enero" */
+static const UChar january_esTitle[] = { 0x45,0x6E,0x65,0x72,0x6F,0 }; /* "Enero */
+static const UChar monday_daDefault[] = { 0x6D,0x61,0x6E,0x64,0x61,0x67,0 }; /* "mandag" */
+static const UChar monday_daTitle[] = { 0x4D,0x61,0x6E,0x64,0x61,0x67,0 }; /* "Mandag */
+
+typedef struct {
+ const char * locale;
+ UDateFormatSymbolType type;
+ int32_t index;
+ UDisplayContext capitalizationContext;
+ const UChar * expectedFormat;
+} TestSymbolContextItem;
+
+static const TestSymbolContextItem testContextSymbolItems[] = {
+ { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_NONE, january_esDefault },
+#if !UCONFIG_NO_BREAK_ITERATION
+ { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, january_esDefault },
+ { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, january_esTitle },
+ { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, january_esTitle },
+ { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, january_esTitle },
+#endif
+ { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_NONE, monday_daDefault },
+#if !UCONFIG_NO_BREAK_ITERATION
+ { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, monday_daDefault },
+ { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, monday_daTitle },
+ { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, monday_daDefault },
+ { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, monday_daDefault },
+#endif
+ { NULL, (UDateFormatSymbolType)0, 0, (UDisplayContext)0, NULL }
+};
+
static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */
static const UDate july022008 = 1215000000000.0;
enum { kUbufMax = 64, kBbufMax = 3*kUbufMax };
static void TestContext(void) {
const TestContextItem* textContextItemPtr;
const TestRelativeContextItem* textRelContextItemPtr;
+ const TestSymbolContextItem* testSymContextItemPtr;
+
for (textContextItemPtr = textContextItems; textContextItemPtr->locale != NULL; ++textContextItemPtr) {
UErrorCode status = U_ZERO_ERROR;
UDateTimePatternGenerator* udtpg = udatpg_open(textContextItemPtr->locale, &status);
log_data_err("FAIL: udatpg_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
}
}
+
for (textRelContextItemPtr = textContextRelativeItems; textRelContextItemPtr->locale != NULL; ++textRelContextItemPtr) {
UErrorCode status = U_ZERO_ERROR;
UCalendar* ucal = ucal_open(zoneGMT, -1, "root", UCAL_GREGORIAN, &status);
log_data_err("FAIL: ucal_open for locale root, status %s\n", u_errorName(status) );
}
}
+
+ for (testSymContextItemPtr = testContextSymbolItems; testSymContextItemPtr->locale != NULL; ++testSymContextItemPtr) {
+ UErrorCode status = U_ZERO_ERROR;
+ UDateFormat* udfmt = udat_open(UDAT_MEDIUM, UDAT_FULL, testSymContextItemPtr->locale, zoneGMT, -1, NULL, 0, &status);
+ if ( U_SUCCESS(status) ) {
+ udat_setContext(udfmt, testSymContextItemPtr->capitalizationContext, &status);
+ if ( U_SUCCESS(status) ) {
+ UChar ubuf[kUbufMax];
+ int32_t len = udat_getSymbols(udfmt, testSymContextItemPtr->type, testSymContextItemPtr->index, ubuf, kUbufMax, &status);
+ if ( U_FAILURE(status) ) {
+ log_err("FAIL: udat_getSymbols for locale %s, capitalizationContext %d, status %s\n",
+ testSymContextItemPtr->locale, (int)testSymContextItemPtr->capitalizationContext, u_errorName(status) );
+ } else if (u_strncmp(ubuf, testSymContextItemPtr->expectedFormat, kUbufMax) != 0) {
+ char bbuf1[kBbufMax];
+ char bbuf2[kBbufMax];
+ log_err("FAIL: udat_getSymbols for locale %s, capitalizationContext %d, expected %s, got %s\n",
+ testSymContextItemPtr->locale, (int)testSymContextItemPtr->capitalizationContext,
+ u_austrncpy(bbuf1,testSymContextItemPtr->expectedFormat,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
+ }
+ } else {
+ log_err("FAIL: udat_setContext std for locale %s, capitalizationContext %d, status %s\n",
+ testSymContextItemPtr->locale, (int)testSymContextItemPtr->capitalizationContext, u_errorName(status) );
+ }
+ udat_close(udfmt);
+ } else {
+ log_data_err("FAIL: udat_open std for locale %s, status %s\n", testSymContextItemPtr->locale, u_errorName(status) );
+ }
+ }
}
overrideFmt = NULL; // no longer valid
assertSuccess("udat_setNumberFormatForField()", &status);
- getter_result = udat_getNumberFormatForField(fmt, 'd');
+ getter_result = udat_getNumberFormatForField(fmt, 0x0064 /*'d'*/);
if(getter_result == NULL) {
log_err("FAIL: udat_getNumberFormatForField did not return a valid pointer\n");
}
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 */
+static const UChar patNoFields[] = { 0x0027, 0x0078, 0x0078, 0x0078, 0x0027, 0 }; /* "'xxx'" */
typedef struct {
int32_t field;
}
}
+ udat_applyPattern(udfmt, FALSE, patNoFields, -1);
+ status = U_ZERO_ERROR;
+ ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status);
+ if ( U_FAILURE(status) ) {
+ log_err("udat_formatForFields with no-field pattern fails, status %s\n", u_errorName(status));
+ } else {
+ field = ufieldpositer_next(fpositer, &beginPos, &endPos);
+ if (field >= 0) {
+ log_err("udat_formatForFields with no-field pattern as \"%s\"; expect field < 0, get field %d range %d-%d\n",
+ aescstrdup(ubuf, ulen), field, beginPos, endPos);
+ }
+ }
+
ucal_close(ucal);
udat_close(udfmt);
}
}
}
+static void TestForceGannenNumbering(void) {
+ UErrorCode status;
+ const char* locID = "ja_JP@calendar=japanese";
+ UDate refDate = 600336000000.0; // 1989 Jan 9 Monday = Heisei 1
+ const UChar* testSkeleton = u"yMMMd";
+
+ // Test Gannen year forcing
+ status = U_ZERO_ERROR;
+ UDateTimePatternGenerator* dtpgen = udatpg_open(locID, &status);
+ if (U_FAILURE(status)) {
+ log_data_err("Fail in udatpg_open locale %s: %s", locID, u_errorName(status));
+ } else {
+ UChar pattern[kUbufMax];
+ int32_t patlen = udatpg_getBestPattern(dtpgen, testSkeleton, -1, pattern, kUbufMax, &status);
+ if (U_FAILURE(status)) {
+ log_data_err("Fail in udatpg_getBestPattern locale %s: %s", locID, u_errorName(status));
+ } else {
+ UDateFormat *testFmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, locID, NULL, 0, pattern, patlen, &status);
+ if (U_FAILURE(status)) {
+ log_data_err("Fail in udat_open locale %s: %s", locID, u_errorName(status));
+ } else {
+ UChar testString[kUbufMax];
+ int32_t testStrLen = udat_format(testFmt, refDate, testString, kUbufMax, NULL, &status);
+ if (U_FAILURE(status)) {
+ log_err("Fail in udat_format locale %s: %s", locID, u_errorName(status));
+ } else if (testStrLen < 3 || testString[2] != 0x5143) {
+ char bbuf[kBbufMax];
+ UErrorCode convStatus = U_ZERO_ERROR;
+ u_strToUTF8(bbuf, kBbufMax, NULL, testString, testStrLen, &convStatus);
+ log_err("Formatting year 1 as Gannen, (conv status %s) got %s but expected 3rd char to be 0x5143", u_errorName(convStatus), bbuf);
+ }
+ udat_close(testFmt);
+ }
+ }
+ udatpg_close(dtpgen);
+ }
+}
+
/* defined above
static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; // "GMT"
static const UDate date2015Feb25 = 1424841000000.0; // Wednesday, February 25, 2015 at 5:10:00 AM GMT
} StandardPatternItem;
static const StandardPatternItem stdPatternItems[] = {
- { "en_JP", UDAT_MEDIUM, UDAT_SHORT, "2015 Feb 25 5:10" },
- { "en_CN", UDAT_MEDIUM, UDAT_SHORT, "25 Feb 2015, 5:10 AM" },
- { "en_TW", UDAT_MEDIUM, UDAT_SHORT, "25 Feb 2015, 5:10 AM" },
- { "en_KR", UDAT_MEDIUM, UDAT_SHORT, "25 Feb 2015, 5:10 AM" },
+ { "en_JP", UDAT_MEDIUM, UDAT_SHORT, "Feb 25, 2015 5:10" },
+ { "en_CN", UDAT_MEDIUM, UDAT_SHORT, "Feb 25, 2015 at 5:10 AM" },
+ { "en_TW", UDAT_MEDIUM, UDAT_SHORT, "Feb 25, 2015 at 5:10 AM" },
+ { "en_KR", UDAT_MEDIUM, UDAT_SHORT, "25 Feb 2015 at 5:10 AM" },
{ NULL, (UDateFormatStyle)0, (UDateFormatStyle)0, NULL } /* terminator */
};
}
}
+#if !U_PLATFORM_HAS_WIN32_API
/* *** */
typedef struct {
}
}
+#endif
typedef enum RemapTesttype {
REMAP_TESTTYPE_FULL = UDAT_FULL, // 0
{ "EEE, d MMM y 'aha' H:mm:ss 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
{ "EEE, d MMM y 'aha' H'h'mm'm'ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
{ "EEE, d MMM y 'aha' H'h'mm'm'ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
+
+ // special cases per bugs
+ { "uuuu-MM-dd HH:mm:ss '+0000'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE }, // <rdar://problem/38826484>
+
{ NULL, (RemapTesttype)0, 0 }
};
"EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
"EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
"EEE, d MMM y 'aha' H'h'mm'm'ss", //
+
+ "uuuu-MM-dd h:mm:ss a '+0000'", //
+
NULL
};
"EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
"EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
"EEE, d MMM y 'aha' H'h'mm'm'ss", //
+
+ "uuuu-MM-dd h:mm:ss a '+0000'", //
+
NULL
};
"H:mm", // short
"H:mm", // force24
"aK:mm", // force12
- "y\\u5E74M\\u6708d\\u65E5EEEE H:mm:ss z", // long_df
- "y\\u5E74M\\u6708d\\u65E5EEEE H:mm:ss z", // force24
- "y\\u5E74M\\u6708d\\u65E5EEEE aK:mm:ss z", // force12
+ "y\\u5E74M\\u6708d\\u65E5 EEEE H:mm:ss z", // long_df
+ "y\\u5E74M\\u6708d\\u65E5 EEEE H:mm:ss z", // force24
+ "y\\u5E74M\\u6708d\\u65E5 EEEE aK:mm:ss z", // force12
"y/MM/dd H:mm", // short_ds
"y/MM/dd H:mm", // force24
"y/MM/dd aK:mm", // force12
"EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
"EEE, d MMM y 'aha' aK'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
"EEE, d MMM y 'aha' H'h'mm'm'ss", //
+
+ "uuuu-MM-dd aK:mm:ss '+0000'", //
+
NULL
};
"EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
"EEE, d MMM y 'aha' a h'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
"EEE, d MMM y 'aha' H'h'mm'm'ss", //
+
+ "uuuu-MM-dd a h:mm:ss '+0000'", //
+
NULL
};
"EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
"EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
"EEE, d MMM y 'aha' H'h'mm'm'ss", //
+
+ "uuuu-MM-dd h:mm:ss a '+0000'", //
+
NULL
};
"EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
"EEE, d MMM y 'aha' a h'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
"EEE, d MMM y 'aha' H'h'mm'm'ss", //
+
+ "uuuu-MM-dd a h:mm:ss '+0000'", //
+
+ NULL
+};
+
+static const char * remapResults_ar[] = {
+ "h:mm:ss\\u00A0a zzzz", // full
+ "HH:mm:ss zzzz", // force24
+ "h:mm:ss\\u00A0a zzzz", // force12
+ "h:mm:ss\\u00A0a z", // long
+ "HH:mm:ss z", // force24
+ "h:mm:ss\\u00A0a z", // force12
+ "h:mm:ss\\u00A0a", // medium
+ "HH:mm:ss", // force24
+ "h:mm:ss\\u00A0a", // force12
+ "h:mm\\u00A0a", // short
+ "HH:mm", // force24
+ "h:mm\\u00A0a", // force12
+ "EEEE\\u060C d MMMM\\u060C y\\u060C h:mm:ss\\u00A0a z", // long_df
+ "EEEE\\u060C d MMMM\\u060C y\\u060C HH:mm:ss z", // force24
+ "EEEE\\u060C d MMMM\\u060C y\\u060C h:mm:ss\\u00A0a z", // force12
+ "d\\u200F/M\\u200F/y\\u060C h:mm\\u00A0a", // short_ds
+ "d\\u200F/M\\u200F/y\\u060C HH:mm", // force24
+ "d\\u200F/M\\u200F/y\\u060C h:mm\\u00A0a", // force12
+
+ "h:mm:ss\\u00A0a", // jmmss
+ "HH:mm:ss", // force24
+ "h:mm:ss\\u00A0a", // force12
+ "h:mm:ss\\u00A0a", // jjmmss
+ "HH:mm:ss", // force24
+ "HH:mm:ss", // force24 | match hour field length
+ "h:mm:ss\\u00A0a", // force12
+ "hh:mm:ss\\u00A0a", // force12 | match hour field length
+ "hh:mm", // Jmm
+ "HH:mm", // force24
+ "hh:mm", // force12
+ "h:mm:ss\\u00A0a v", // jmsv
+ "HH:mm:ss v", // force24
+ "h:mm:ss\\u00A0a v", // force12
+ "h:mm:ss\\u00A0a z", // jmsz
+ "HH:mm:ss z", // force24
+ "h:mm:ss\\u00A0a z", // force12
+
+ "h:mm:ss a", // "h:mm:ss"
+ "HH:mm:ss", //
+ "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
+ "HH:mm:ss d MMM y", //
+ "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
+ "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
+ "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
+ "EEE, d MMM y 'aha' HH:mm:ss", //
+ "yyMMddhhmmss", // "yyMMddhhmmss"
+ "yyMMddHHmmss", //
+
+ "h:mm:ssa", // "H:mm:ss" (should there be \\u00A0 before a?)
+ "H:mm:ss", //
+ "h:mm:ssa d MMM y", // "H:mm:ss d MMM y" (should there be \\u00A0 before a?)
+ "H:mm:ss d MMM y", //
+ "EEE, d MMM y 'aha' h:mm:ssa 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'" (should there be \\u00A0 before a?)
+ "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
+ "EEE, d MMM y 'aha' h'h'mm'm'ssa", // "EEE, d MMM y 'aha' H'h'mm'm'ss" (should there be \\u00A0 before a?)
+ "EEE, d MMM y 'aha' H'h'mm'm'ss", //
+
+ "uuuu-MM-dd h:mm:ss\\u00A0a '+0000'", //
+
+ NULL
+};
+
+static const char * remapResults_en_IL[] = {
+ "H:mm:ss zzzz", // full
+ "H:mm:ss zzzz", // force24
+ "h:mm:ss a zzzz", // force12
+ "H:mm:ss z", // long
+ "H:mm:ss z", // force24
+ "h:mm:ss a z", // force12
+ "H:mm:ss", // medium
+ "H:mm:ss", // force24
+ "h:mm:ss a", // force12
+ "H:mm", // short
+ "H:mm", // force24
+ "h:mm a", // force12
+ "EEEE, d MMMM y 'at' H:mm:ss z", // long_df
+ "EEEE, d MMMM y 'at' H:mm:ss z", // force24
+ "EEEE, d MMMM y 'at' h:mm:ss a z", // force12
+ "dd/MM/y, H:mm", // short_ds
+ "dd/MM/y, H:mm", // force24
+ "dd/MM/y, h:mm a", // force12
+
+ "H:mm:ss", // jmmss
+ "H:mm:ss", // force24
+ "h:mm:ss a", // force12
+ "H:mm:ss", // jjmmss
+ "H:mm:ss", // force24
+ "HH:mm:ss", // force24 | match hour field length
+ "h:mm:ss a", // force12
+ "hh:mm:ss a", // force12 | match hour field length
+ "H:mm", // Jmm
+ "H:mm", // force24
+ "h:mm", // force12
+ "H:mm:ss v", // jmsv
+ "H:mm:ss v", // force24
+ "h:mm:ss a v", // force12
+ "H:mm:ss z", // jmsz
+ "H:mm:ss z", // force24
+ "h:mm:ss a z", // force12
+
+ "h:mm:ss a", // "h:mm:ss"
+ "H:mm:ss", //
+ "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
+ "H:mm:ss d MMM y", //
+ "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
+ "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
+ "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
+ "EEE, d MMM y 'aha' H:mm:ss", //
+ "yyMMddhhmmss", // "yyMMddhhmmss"
+ "yyMMddHHmmss", //
+
+ "h:mm:ss a", // "H:mm:ss"
+ "H:mm:ss", //
+ "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
+ "H:mm:ss d MMM y", //
+ "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
+ "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
+ "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
+ "EEE, d MMM y 'aha' H'h'mm'm'ss", //
+
+ "uuuu-MM-dd h:mm:ss a '+0000'", //
+
NULL
};
{ "ko", remapResults_ko },
{ "th", remapResults_th },
{ "hi", remapResults_hi },
+ { "ar", remapResults_ar },
+ { "en_IL", remapResults_en_IL },
{ NULL, NULL }
};