+#define UDATE_SECOND (1000.0)
+#define UDATE_MINUTE (60.0*UDATE_SECOND)
+#define UDATE_HOUR (60.0*UDATE_MINUTE)
+
+static const double dayOffsets[] = {
+ 0.0, /* 00:00:00 */
+ UDATE_SECOND, /* 00:00:01 */
+ UDATE_MINUTE, /* 00:01:00 */
+ UDATE_HOUR, /* 01:00:00 */
+ 11.0*UDATE_HOUR + 59.0*UDATE_MINUTE, /* 11:59:00 */
+ 12.0*UDATE_HOUR, /* 12:00:00 */
+ 12.0*UDATE_HOUR + UDATE_SECOND, /* 12:00:01 */
+ 12.0*UDATE_HOUR + UDATE_MINUTE, /* 12:01:00 */
+ 13.0*UDATE_HOUR, /* 13:00:00 */
+ 23.0*UDATE_HOUR + 59.0*UDATE_MINUTE, /* 23:59:00 */
+};
+enum { kNumDayOffsets = UPRV_LENGTHOF(dayOffsets) };
+
+static const char* ja12HrFmt_hm[kNumDayOffsets] = { /* aK:mm */
+ "\\u5348\\u524D0:00", /* "午前0:00" */
+ "\\u5348\\u524D0:00",
+ "\\u5348\\u524D0:01",
+ "\\u5348\\u524D1:00",
+ "\\u5348\\u524D11:59",
+ "\\u5348\\u5F8C0:00", /* "午後0:00" */
+ "\\u5348\\u5F8C0:00",
+ "\\u5348\\u5F8C0:01", /* "午後0:01" */
+ "\\u5348\\u5F8C1:00",
+ "\\u5348\\u5F8C11:59",
+};
+
+static const char* ja12HrFmt_h[kNumDayOffsets] = { /* aK時 */
+ "\\u5348\\u524D0\\u6642", /* "午前0時" */
+ "\\u5348\\u524D0\\u6642",
+ "\\u5348\\u524D0\\u6642",
+ "\\u5348\\u524D1\\u6642",
+ "\\u5348\\u524D11\\u6642",
+ "\\u5348\\u5F8C0\\u6642", /* "午後0時" */
+ "\\u5348\\u5F8C0\\u6642",
+ "\\u5348\\u5F8C0\\u6642", /* "午後0時" */
+ "\\u5348\\u5F8C1\\u6642",
+ "\\u5348\\u5F8C11\\u6642",
+};
+typedef struct {
+ const char* locale;
+ const char* skeleton;
+ const char ** expected;
+} Test12HrFmtItem;
+
+static const Test12HrFmtItem test12HrFmtItems[] = {
+ { "ja", "hm", ja12HrFmt_hm },
+ { "ja", "h", ja12HrFmt_h },
+ { NULL, NULL, NULL } /* terminator */
+};
+
+enum { kUBufMax = 128, };
+static void Test12HrFormats(void) {
+ const Test12HrFmtItem* itemPtr;
+ for (itemPtr = test12HrFmtItems; itemPtr->locale != NULL; itemPtr++) {
+ UErrorCode status = U_ZERO_ERROR;
+ UCalendar* ucal = ucal_open(NULL, 0, itemPtr->locale, UCAL_DEFAULT, &status);
+ if ( U_FAILURE(status) ) {
+ log_data_err("ucal_open fails for locale %s: status %s (Are you missing data?)\n", itemPtr->locale, u_errorName(status));
+ } else {
+ ucal_clear(ucal);
+ ucal_setDateTime(ucal, 2016, UCAL_JANUARY, 1, 0, 0, 0, &status);
+ UDate baseDate = ucal_getMillis(ucal, &status);
+ if ( U_FAILURE(status) ) {
+ log_err("ucal_setDateTime or ucal_getMillis fails for locale %s: status %s\n", itemPtr->locale, u_errorName(status));
+ } else {
+ UDateTimePatternGenerator* udatpg = udatpg_open(itemPtr->locale, &status);
+ if ( U_FAILURE(status) ) {
+ log_data_err("udatpg_open fails for locale %s: status %s (Are you missing data?)\n", itemPtr->locale, u_errorName(status));
+ } else {
+ UChar ubuf1[kUbufMax], ubuf2[kUbufMax];
+ int32_t ulen1 = u_unescape(itemPtr->skeleton, ubuf1, kUbufMax);
+ int32_t ulen2 = udatpg_getBestPattern(udatpg, ubuf1, ulen1, ubuf2, kUbufMax, &status);
+ if ( U_FAILURE(status) ) {
+ log_err("udatpg_getBestPattern fails for locale %s, skeleton %s: status %s\n",
+ itemPtr->locale, itemPtr->skeleton, u_errorName(status));
+ } else {
+ UDateFormat* udat = udat_open(UDAT_PATTERN, UDAT_PATTERN, itemPtr->locale, NULL, 0, ubuf2, ulen2, &status);
+ if ( U_FAILURE(status) ) {
+ log_data_err("udat_open fails for locale %s, skeleton %s: status %s (Are you missing data?)\n",
+ itemPtr->locale, itemPtr->skeleton, u_errorName(status));
+ } else {
+ int32_t iDayOffset;
+ for (iDayOffset = 0; iDayOffset < kNumDayOffsets; iDayOffset++) {
+ status = U_ZERO_ERROR;
+ ulen1 = udat_format(udat, baseDate + dayOffsets[iDayOffset], ubuf1, kUbufMax, NULL, &status);
+ if ( U_FAILURE(status) ) {
+ log_err("udat_format fails for locale %s, skeleton %s, iDayOffset %d: status %s\n",
+ itemPtr->locale, itemPtr->skeleton, iDayOffset, u_errorName(status));
+ } else {
+ ulen2 = u_unescape(itemPtr->expected[iDayOffset], ubuf2, kUbufMax);
+ if (ulen1 != ulen2 || u_strncmp(ubuf1, ubuf2, ulen2) != 0) {
+ char bbuf1[kBbufMax], bbuf2[kBbufMax];
+ u_austrncpy(bbuf1, ubuf1, ulen1);
+ u_austrncpy(bbuf2, ubuf2, ulen2);
+ log_err("udat_format fails for locale %s, skeleton %s, iDayOffset %d:\n expect %s\n get %s\n",
+ itemPtr->locale, itemPtr->skeleton, iDayOffset, bbuf2, bbuf1);
+ }
+ }
+
+ }
+ udat_close(udat);
+ }
+ }
+ udatpg_close(udatpg);
+ }
+ }
+ ucal_close(ucal);
+ }
+ }
+}
+