-1, // 'U' - UDAT_YEAR_NAME_FIELD
};
+// When calendar uses hebr numbering (i.e. he@calendar=hebrew),
+// offset the years within the current millenium down to 1-999
+static const int32_t HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000;
+static const int32_t HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000;
+
+
static UMTX LOCK;
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleDateFormat)
}
currentNumberFormat = getNumberFormatByIndex(patternCharIndex);
+ UnicodeString hebr("hebr", 4, US_INV);
+
switch (patternCharIndex) {
// for any "G" symbol, write out the appropriate era string
//AD 12345 12345 45 12345 12345 12345
case UDAT_YEAR_FIELD:
case UDAT_YEAR_WOY_FIELD:
+ if (fDateOverride.compare(hebr)==0 && value>HEBREW_CAL_CUR_MILLENIUM_START_YEAR && value<HEBREW_CAL_CUR_MILLENIUM_END_YEAR) {
+ value-=HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
+ }
if(count == 2)
zeroPaddingNumber(currentNumberFormat, appendTo, value, 2, 2);
else
patternCharIndex = (UDateFormatField)(patternCharPtr - DateFormatSymbols::getPatternUChars());
currentNumberFormat = getNumberFormatByIndex(patternCharIndex);
UCalendarDateFields field = fgPatternIndexToCalendarField[patternCharIndex];
+ UnicodeString hebr("hebr", 4, US_INV);
if (numericLeapMonthFormatter != NULL) {
numericLeapMonthFormatter->setFormats((const Format **)¤tNumberFormat, 1);
// we made adjustments to place the 2-digit year in the proper
// century, for parsed strings from "00" to "99". Any other string
// is treated literally: "2250", "-1", "1", "002".
- if ((pos.getIndex() - start) == 2 && !isChineseCalendar
+ if (fDateOverride.compare(hebr)==0 && value < 1000) {
+ value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
+ } else if ((pos.getIndex() - start) == 2 && !isChineseCalendar
&& u_isdigit(text.charAt(start))
&& u_isdigit(text.charAt(start+1)))
{
case UDAT_YEAR_WOY_FIELD:
// Comment is the same as for UDAT_Year_FIELDs - look above
- if ((pos.getIndex() - start) == 2
+ if (fDateOverride.compare(hebr)==0 && value < 1000) {
+ value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
+ } else if ((pos.getIndex() - start) == 2
&& u_isdigit(text.charAt(start))
&& u_isdigit(text.charAt(start+1))
&& fHaveDefaultCentury )
TESTCASE(46,TestParsePosition);
TESTCASE(47,TestMonthPatterns);
TESTCASE(48,TestContext);
+ TESTCASE(49,TestNonGregoFmtParse);
/*
- TESTCASE(49,TestRelativeError);
- TESTCASE(50,TestRelativeOther);
+ TESTCASE(50,TestRelativeError);
+ TESTCASE(51,TestRelativeOther);
*/
default: name = ""; break;
}
}
}
+// test item for a particular locale + calendar and date format
+typedef struct {
+ int32_t year;
+ int32_t month;
+ int32_t day;
+ int32_t hour;
+ int32_t minute;
+ UnicodeString formattedDate;
+} CalAndFmtTestItem;
+
+// test item giving locale + calendar, date format, and CalAndFmtTestItems
+typedef struct {
+ const char * locale; // with calendar
+ DateFormat::EStyle style;
+ const CalAndFmtTestItem *caftItems;
+} TestNonGregoItem;
+
+void DateFormatTest::TestNonGregoFmtParse()
+{
+ // test items for he@calendar=hebrew, long date format
+ const CalAndFmtTestItem cafti_he_hebrew_long[] = {
+ { 4999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05D3\\u05F3\\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") },
+ { 5100, 0, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05E7\\u05F3") },
+ { 5774, 5, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05D0\\u05D3\\u05E8 \\u05D0\\u05F3 \\u05EA\\u05E9\\u05E2\\u05F4\\u05D3") },
+ { 5999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") },
+ { 6100, 0, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05D5\\u05F3\\u05E7\\u05F3") },
+ { 0, 0, 0, 0, 0, UnicodeString("") } // terminator
+ };
+ // overal test items
+ const TestNonGregoItem items[] = {
+ { "he@calendar=hebrew", DateFormat::kLong, cafti_he_hebrew_long },
+ { NULL, DateFormat::kNone, NULL } // terminator
+ };
+ const TestNonGregoItem * itemPtr;
+ for (itemPtr = items; itemPtr->locale != NULL; itemPtr++) {
+ Locale locale = Locale::createFromName(itemPtr->locale);
+ DateFormat * dfmt = DateFormat::createDateInstance(itemPtr->style, locale);
+ if (dfmt == NULL) {
+ dataerrln("DateFormat::createDateInstance fails for locale %s", itemPtr->locale);
+ } else {
+ Calendar * cal = (dfmt->getCalendar())->clone();
+ if (cal == NULL) {
+ dataerrln("(DateFormat::getCalendar)->clone() fails for locale %s", itemPtr->locale);
+ } else {
+ const CalAndFmtTestItem * caftItemPtr;
+ for (caftItemPtr = itemPtr->caftItems; caftItemPtr->year != 0; caftItemPtr++) {
+ cal->clear();
+ cal->set(UCAL_YEAR, caftItemPtr->year);
+ cal->set(UCAL_MONTH, caftItemPtr->month);
+ cal->set(UCAL_DATE, caftItemPtr->day);
+ cal->set(UCAL_HOUR_OF_DAY, caftItemPtr->hour);
+ cal->set(UCAL_MINUTE, caftItemPtr->minute);
+ UnicodeString result;
+ FieldPosition fpos(0);
+ dfmt->format(*cal, result, fpos);
+ if ( result.compare(caftItemPtr->formattedDate) != 0 ) {
+ errln( UnicodeString("FAIL: date format for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
+ ", expected \"" + caftItemPtr->formattedDate + "\", got \"" + result + "\"");
+ } else {
+ // formatted OK, try parse
+ ParsePosition ppos(0);
+ dfmt->parse(result, *cal, ppos);
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t year = cal->get(UCAL_YEAR, status);
+ int32_t month = cal->get(UCAL_MONTH, status);
+ int32_t day = cal->get(UCAL_DATE, status);
+ if ( U_FAILURE(status) || ppos.getIndex() < result.length() || year != caftItemPtr->year || month != caftItemPtr->month || day != caftItemPtr->day ) {
+ errln( UnicodeString("FAIL: date parse for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
+ ", string \"" + result + "\", expected " + caftItemPtr->year +"-"+caftItemPtr->month+"-"+caftItemPtr->day + ", got pos " +
+ ppos.getIndex() + " " + year +"-"+month+"-"+day + " status " + UnicodeString(u_errorName(status)) );
+ }
+ }
+ }
+ delete cal;
+ }
+ delete dfmt;
+ }
+ }
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */
//eof