}
}
+UDateFormatHourCycle
+DateTimePatternGenerator::getDefaultHourCycle(UErrorCode& /*status*/) const {
+ switch(fDefaultHourFormatChar) {
+ case CAP_K:
+ return UDAT_HOUR_CYCLE_11;
+ case LOW_H:
+ return UDAT_HOUR_CYCLE_12;
+ case CAP_H:
+ return UDAT_HOUR_CYCLE_23;
+ case LOW_K:
+ return UDAT_HOUR_CYCLE_24;
+ default:
+ UPRV_UNREACHABLE;
+ }
+}
+
UnicodeString
DateTimePatternGenerator::getSkeleton(const UnicodeString& pattern, UErrorCode&
/*status*/) {
return result.getBuffer();
}
+U_CAPI UDateFormatHourCycle U_EXPORT2
+udatpg_getDefaultHourCycle(const UDateTimePatternGenerator *dtpg, UErrorCode* pErrorCode) {
+ return ((const DateTimePatternGenerator *)dtpg)->getDefaultHourCycle(*pErrorCode);
+}
+
#endif
*/
const UnicodeString& getDecimal() const;
+#ifndef U_HIDE_DRAFT_API
+ /**
+ * Get the default hour cycle.
+ * @param status Output param set to success/failure code on exit,
+ * which must not indicate a failure before the function call.
+ * @return the default hour cycle.
+ * @draft ICU 67
+ */
+ UDateFormatHourCycle getDefaultHourCycle(UErrorCode& status) const;
+#endif /* U_HIDE_DRAFT_API */
+
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
U_CAPI void U_EXPORT2
udat_setBooleanAttribute(UDateFormat *fmt, UDateFormatBooleanAttribute attr, UBool newValue, UErrorCode* status);
+#ifndef U_HIDE_DRAFT_API
+/**
+ * Hour Cycle.
+ * @draft ICU 67
+ */
+typedef enum UDateFormatHourCycle {
+ /**
+ * Hour in am/pm (0~11)
+ * @draft ICU 67
+ */
+ UDAT_HOUR_CYCLE_11,
+
+ /**
+ * Hour in am/pm (1~12)
+ * @draft ICU 67
+ */
+ UDAT_HOUR_CYCLE_12,
+
+ /**
+ * Hour in day (0~23)
+ * @draft ICU 67
+ */
+ UDAT_HOUR_CYCLE_23,
+ /**
+ * Hour in day (1~24)
+ * @draft ICU 67
+ */
+ UDAT_HOUR_CYCLE_24
+} UDateFormatHourCycle;
+#endif /* U_HIDE_DRAFT_API */
#if U_SHOW_CPLUSPLUS_API
#define __UDATPG_H__
#include "unicode/utypes.h"
+#include "unicode/udat.h"
#include "unicode/uenum.h"
#include "unicode/localpointer.h"
const UChar *skeleton, int32_t skeletonLength,
int32_t *pLength);
+#ifndef U_HIDE_DRAFT_API
+/**
+ * Return the default hour cycle.
+ *
+ * @param dtpg a pointer to UDateTimePatternGenerator.
+ * @param pErrorCode a pointer to the UErrorCode which must not indicate a
+ * failure before the function call.
+ * @return the default hour cycle.
+ * @draft ICU 67
+ */
+U_DRAFT UDateFormatHourCycle U_EXPORT2
+udatpg_getDefaultHourCycle(const UDateTimePatternGenerator *dtpg, UErrorCode* pErrorCode);
+#endif /* U_HIDE_DRAFT_API */
+
#endif
static void TestBuilder(void);
static void TestOptions(void);
static void TestGetFieldDisplayNames(void);
+static void TestGetDefaultHourCycle(void);
void addDateTimePatternGeneratorTest(TestNode** root) {
TESTCASE(TestOpenClose);
TESTCASE(TestBuilder);
TESTCASE(TestOptions);
TESTCASE(TestGetFieldDisplayNames);
+ TESTCASE(TestGetDefaultHourCycle);
}
/*
}
}
+typedef struct HourCycleData {
+ const char * locale;
+ UDateFormatHourCycle expected;
+} HourCycleData;
+
+static void TestGetDefaultHourCycle() {
+ const HourCycleData testData[] = {
+ /*loc expected */
+ { "ar_EG", UDAT_HOUR_CYCLE_12 },
+ { "de_DE", UDAT_HOUR_CYCLE_23 },
+ { "en_AU", UDAT_HOUR_CYCLE_12 },
+ { "en_CA", UDAT_HOUR_CYCLE_12 },
+ { "en_US", UDAT_HOUR_CYCLE_12 },
+ { "es_ES", UDAT_HOUR_CYCLE_23 },
+ { "fi", UDAT_HOUR_CYCLE_23 },
+ { "fr", UDAT_HOUR_CYCLE_23 },
+ { "ja_JP", UDAT_HOUR_CYCLE_23 },
+ { "zh_CN", UDAT_HOUR_CYCLE_12 },
+ { "zh_HK", UDAT_HOUR_CYCLE_12 },
+ { "zh_TW", UDAT_HOUR_CYCLE_12 },
+ { "ko_KR", UDAT_HOUR_CYCLE_12 },
+ };
+ int count = UPRV_LENGTHOF(testData);
+ const HourCycleData * testDataPtr = testData;
+ for (; count-- > 0; ++testDataPtr) {
+ UErrorCode status = U_ZERO_ERROR;
+ UDateTimePatternGenerator * dtpgen =
+ udatpg_open(testDataPtr->locale, &status);
+ if ( U_FAILURE(status) ) {
+ log_data_err( "ERROR udatpg_open failed for locale %s : %s - (Are you missing data?)\n",
+ testDataPtr->locale, myErrorName(status));
+ } else {
+ UDateFormatHourCycle actual = udatpg_getDefaultHourCycle(dtpgen, &status);
+ if (U_FAILURE(status) || testDataPtr->expected != actual) {
+ log_err("ERROR dtpgen locale %s udatpg_getDefaultHourCycle expecte to get %d but get %d\n",
+ testDataPtr->locale, testDataPtr->expected, actual);
+ }
+ udatpg_close(dtpgen);
+ }
+ }
+}
+
#endif
const char* localeName;
const char16_t* expectedDtpgPattern;
const char16_t* expectedTimePattern;
+ UDateFormatHourCycle expectedDefaultHourCycle;
} cases[] = {
// ars is interesting because it does not have a region, but it aliases
// to ar_SA, which has a region.
- {"ars", u"h a", u"h:mm a"},
+ {"ars", u"h a", u"h:mm a", UDAT_HOUR_CYCLE_12},
// en_NH is interesting because NH is a deprecated region code;
// formerly New Hebrides, now Vanuatu => VU => h.
- {"en_NH", u"h a", u"h:mm a"},
+ {"en_NH", u"h a", u"h:mm a", UDAT_HOUR_CYCLE_12},
// ch_ZH is a typo (should be zh_CN), but we should fail gracefully.
// {"cn_ZH", u"HH", u"H:mm"}, // TODO(ICU-20653): Desired behavior
- {"cn_ZH", u"HH", u"h:mm a"}, // Actual behavior
+ {"cn_ZH", u"HH", u"h:mm a", UDAT_HOUR_CYCLE_23 }, // Actual behavior
// a non-BCP47 locale without a country code should not fail
- {"ja_TRADITIONAL", u"H時", u"H:mm"},
+ {"ja_TRADITIONAL", u"H時", u"H:mm", UDAT_HOUR_CYCLE_23},
};
for (auto& cas : cases) {
if (status.errIfFailureAndReset()) {
return;
}
+ UDateFormatHourCycle defaultHourCycle = dtpg->getDefaultHourCycle(status);
+ if (status.errIfFailureAndReset()) {
+ return;
+ }
assertEquals(UnicodeString("dtpgPattern ") + cas.localeName,
cas.expectedDtpgPattern, dtpgPattern);
assertEquals(UnicodeString("timePattern ") + cas.localeName,
cas.expectedTimePattern, timePattern);
+ assertEquals(UnicodeString("defaultHour ") + cas.localeName,
+ cas.expectedDefaultHourCycle, defaultHourCycle);
}
}
*/
private EnumSet<BooleanAttribute> booleanAttributes = EnumSet.allOf(BooleanAttribute.class);
+ /**
+ * Hour Cycle
+ * @draft ICU 67
+ */
+ public enum HourCycle {
+ /**
+ * hour in am/pm (0~11)
+ * @draft ICU 67
+ */
+ HOUR_CYCLE_11,
+
+ /**
+ * hour in am/pm (1~12)
+ * @draft ICU 67
+ */
+ HOUR_CYCLE_12,
+
+ /**
+ * hour in day (0~23)
+ * @draft ICU 67
+ */
+ HOUR_CYCLE_23,
+
+ /**
+ * hour in day (1~24)
+ * @draft ICU 67
+ */
+ HOUR_CYCLE_24;
+ };
+
/*
* Capitalization setting, hoisted to DateFormat ICU 53
* Note that SimpleDateFormat serialization may call getContext/setContext to read/write
private static final int APPENDITEM_WIDTH_INT = APPENDITEM_WIDTH.ordinal();
private static final DisplayWidth[] CLDR_FIELD_WIDTH = DisplayWidth.values();
-
// Option masks for getBestPattern, replaceFieldTypes (individual masks may be ORed together)
/**
return getFieldDisplayName(field, APPENDITEM_WIDTH);
}
+ /**
+ * Return the default hour cycle.
+ * @draft ICU 67
+ */
+ public DateFormat.HourCycle getDefaultHourCycle() {
+ switch(getDefaultHourFormatChar()) {
+ case 'h': return DateFormat.HourCycle.HOUR_CYCLE_12;
+ case 'H': return DateFormat.HourCycle.HOUR_CYCLE_23;
+ case 'k': return DateFormat.HourCycle.HOUR_CYCLE_24;
+ case 'K': return DateFormat.HourCycle.HOUR_CYCLE_11;
+ default: throw new AssertionError("should be unreachable");
+ }
+ }
+
/**
* The private interface to set a display name for a particular date/time field,
* in one of several possible display widths.
String[][] cases = new String[][]{
// ars is interesting because it does not have a region, but it aliases
// to ar_SA, which has a region.
- {"ars", "h a", "h:mm a"},
+ {"ars", "h a", "h:mm a", "HOUR_CYCLE_12"},
// en_NH is interesting because NH is a depregated region code.
- {"en_NH", "h a", "h:mm a"},
+ {"en_NH", "h a", "h:mm a", "HOUR_CYCLE_12"},
// ch_ZH is a typo (should be zh_CN), but we should fail gracefully.
// {"cn_ZH", "HH", "H:mm"}, // TODO(ICU-20653): Desired behavior
- {"cn_ZH", "HH", "h:mm a"}, // Actual behavior
+ {"cn_ZH", "HH", "h:mm a", "HOUR_CYCLE_23"}, // Actual behavior
// a non-BCP47 locale without a country code should not fail
- {"ja_TRADITIONAL", "H時", "H:mm"},
+ {"ja_TRADITIONAL", "H時", "H:mm", "HOUR_CYCLE_23"},
};
for (String[] cas : cases) {
cas[1], dtpgPattern);
assertEquals("timePattern " + cas[1],
cas[2], timePattern);
+ assertEquals("default hour cycle " + cas[3],
+ cas[3], dtpg.getDefaultHourCycle().toString());
}
}
}