+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
/********************************************************************
* COPYRIGHT:
- * Copyright (c) 1997-2015, International Business Machines
+ * Copyright (c) 1997-2016, International Business Machines
* Corporation and others. All Rights Reserved.
********************************************************************/
#include "caltest.h" // for fieldName
#include <stdio.h> // for sprintf
-#if U_PLATFORM_HAS_WIN32_API
+#if U_PLATFORM_USES_ONLY_WIN32_API
#include "windttst.h"
#endif
-#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
-
#define ASSERT_OK(status) if(U_FAILURE(status)) {errcheckln(status, #status " = %s @ %s:%d", u_errorName(status), __FILE__, __LINE__); return; }
// *****************************************************************************
TESTCASE_AUTO(TestMonthPatterns);
TESTCASE_AUTO(TestContext);
TESTCASE_AUTO(TestNonGregoFmtParse);
+ TESTCASE_AUTO(TestFormatsWithNumberSystems);
/*
TESTCASE_AUTO(TestRelativeError);
TESTCASE_AUTO(TestRelativeOther);
TESTCASE_AUTO(TestDFSCreateForLocaleWithCalendarInLocale);
TESTCASE_AUTO(TestChangeCalendar);
+ TESTCASE_AUTO(TestPatternFromSkeleton);
+
+ TESTCASE_AUTO(TestAmPmMidnightNoon);
+ TESTCASE_AUTO(TestFlexibleDayPeriod);
+ TESTCASE_AUTO(TestDayPeriodWithLocales);
+ TESTCASE_AUTO(TestMinuteSecondFieldsInOddPlaces);
+ TESTCASE_AUTO(TestDayPeriodParsing);
+
TESTCASE_AUTO_END;
}
{UDAT_QUARTER, "QQQQ", "en", "QQQQ"},
{UDAT_ABBR_QUARTER, "QQQ", "en", "QQQ"},
- {UDAT_YEAR_QUARTER, "yQQQQ", "en", "QQQQ y"},
+ {UDAT_YEAR_QUARTER, "yQQQQ", "en", "QQQQ y"},
{UDAT_YEAR_ABBR_QUARTER, "yQQQ", "en", "QQQ y"},
{UDAT_NUM_MONTH, "M", "en", "L"},
{UDAT_ABBR_MONTH, "MMM", "en", "LLL"},
{UDAT_MONTH, "MMMM", "en", "LLLL"},
- {UDAT_YEAR_NUM_MONTH, "yM","en","M/y"},
+ {UDAT_YEAR_NUM_MONTH, "yM","en","M/y"},
{UDAT_YEAR_ABBR_MONTH, "yMMM","en","MMM y"},
{UDAT_YEAR_MONTH, "yMMMM","en","MMMM y"},
{UDAT_DAY, "d","en","d"},
- {UDAT_YEAR_NUM_MONTH_DAY, "yMd", "en", "M/d/y"},
+ {UDAT_YEAR_NUM_MONTH_DAY, "yMd", "en", "M/d/y"},
{UDAT_YEAR_ABBR_MONTH_DAY, "yMMMd", "en", "MMM d, y"},
{UDAT_YEAR_MONTH_DAY, "yMMMMd", "en", "MMMM d, y"},
- {UDAT_YEAR_NUM_MONTH_WEEKDAY_DAY, "yMEd", "en", "EEE, M/d/y"},
+ {UDAT_YEAR_NUM_MONTH_WEEKDAY_DAY, "yMEd", "en", "EEE, M/d/y"},
{UDAT_YEAR_ABBR_MONTH_WEEKDAY_DAY, "yMMMEd", "en", "EEE, MMM d, y"},
{UDAT_YEAR_MONTH_WEEKDAY_DAY, "yMMMMEEEEd", "en", "EEEE, MMMM d, y"},
UnicodeString expectedPattern(EXPECTED[i].expectedPattern, -1, US_INV);
Locale locale(EXPECTED[i].localeID);
if (actualPattern != expectedPattern) {
- errln("FAILURE! Expected pattern: " + expectedPattern +
+ errln("FAILURE! Expected pattern: " + expectedPattern +
" but was: " + actualPattern);
}
- // Verify that DataFormat instances produced contain the correct
+ // Verify that DataFormat instances produced contain the correct
// localized patterns
// TODO: use DateFormat::getInstanceForSkeleton(), ticket #9029
// Java test code:
- // DateFormat date1 = DateFormat.getPatternInstance(actualPattern,
+ // DateFormat date1 = DateFormat.getPatternInstance(actualPattern,
// locale);
// DateFormat date2 = DateFormat.getPatternInstance(Calendar.getInstance(locale),
// actualPattern, locale);
date1.toLocalizedPattern(actualLocalPattern1, errorCode);
date2.toLocalizedPattern(actualLocalPattern2, errorCode);
if (actualLocalPattern1 != expectedLocalPattern) {
- errln("FAILURE! Expected local pattern: " + expectedLocalPattern
+ errln("FAILURE! Expected local pattern: " + expectedLocalPattern
+ " but was: " + actualLocalPattern1);
}
if (actualLocalPattern2 != expectedLocalPattern) {
- errln("FAILURE! Expected local pattern: " + expectedLocalPattern
+ errln("FAILURE! Expected local pattern: " + expectedLocalPattern
+ " but was: " + actualLocalPattern2);
}
}
* Format the output.
*/
UnicodeString fmtOffset;
- FieldPosition pos(0);
+ FieldPosition pos(FieldPosition::DONT_CARE);
sdf->format(today,fmtOffset, pos);
// UnicodeString fmtOffset = tzS.toString();
UnicodeString *fmtDstOffset = 0;
/**
* This MUST be kept in sync with DateFormatSymbols.gPatternChars.
*/
-static const char* PATTERN_CHARS = "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxr:";
+#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
+static const char* PATTERN_CHARS = "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB:";
+#else
+static const char* PATTERN_CHARS = "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB";
+#endif
/**
* A list of the names of all the fields in DateFormat.
"TIMEZONE_ISO_FIELD",
"TIMEZONE_ISO_LOCAL_FIELD",
"RELATED_YEAR_FIELD",
+ "AM_PM_MIDNIGHT_NOON_FIELD",
+ "FLEXIBLE_DAY_PERIOD_FIELD",
"UDAT_TIME_SEPARATOR_FIELD",
};
static const int32_t DATEFORMAT_FIELD_NAMES_LENGTH =
- sizeof(DATEFORMAT_FIELD_NAMES) / sizeof(DATEFORMAT_FIELD_NAMES[0]);
+ UPRV_LENGTHOF(DATEFORMAT_FIELD_NAMES);
/**
* Verify that returned field position indices are correct.
assertEquals("patternChars", PATTERN_CHARS, rootSyms.getLocalPatternChars(buf));
assertEquals("patternChars", PATTERN_CHARS, DateFormatSymbols::getPatternUChars());
assertTrue("DATEFORMAT_FIELD_NAMES", DATEFORMAT_FIELD_NAMES_LENGTH == UDAT_FIELD_COUNT);
+#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
assertTrue("Data", UDAT_FIELD_COUNT == uprv_strlen(PATTERN_CHARS));
+#else
+ assertTrue("Data", UDAT_FIELD_COUNT == uprv_strlen(PATTERN_CHARS) + 1); // +1 for missing TIME_SEPARATOR pattern char
+#endif
// Create test formatters
const int32_t COUNT = 4;
const char* EXPECTED[] = {
"", "1997", "August", "13", "", "", "34", "12", "", "Wednesday",
"", "", "", "", "PM", "2", "", "Pacific Daylight Time", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", ":",
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
+ ":",
+#else
+ "",
+#endif
"", "1997", "ao\\u00FBt", "13", "", "14", "34", "12", "", "mercredi",
"", "", "", "", "", "", "", "heure d\\u2019\\u00E9t\\u00E9 du Pacifique", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", ":",
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
+ ":",
+#else
+ "",
+#endif
"AD", "1997", "8", "13", "14", "14", "34", "12", "5", "Wed",
"225", "2", "33", "3", "PM", "2", "2", "PDT", "1997", "4",
"1997", "2450674", "52452513", "-0700", "PT", "4", "8", "3", "3", "uslax",
- "1997", "GMT-7", "-07", "-07", "1997", ":",
+ "1997", "GMT-7", "-07", "-07", "1997", "PM", "in the afternoon",
+#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
+ ":",
+#else
+ "",
+#endif
"Anno Domini", "1997", "August", "0013", "0014", "0014", "0034", "0012", "5130", "Wednesday",
"0225", "0002", "0033", "0003", "PM", "0002", "0002", "Pacific Daylight Time", "1997", "Wednesday",
"1997", "2450674", "52452513", "GMT-07:00", "Pacific Time", "Wednesday", "August", "3rd quarter", "3rd quarter", "Los Angeles Time",
- "1997", "GMT-07:00", "-0700", "-0700", "1997", ":",
+ "1997", "GMT-07:00", "-0700", "-0700", "1997", "PM", "in the afternoon",
+#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
+ ":",
+#else
+ "",
+#endif
};
- const int32_t EXPECTED_LENGTH = sizeof(EXPECTED)/sizeof(EXPECTED[0]);
+ const int32_t EXPECTED_LENGTH = UPRV_LENGTHOF(EXPECTED);
assertTrue("data size", EXPECTED_LENGTH == COUNT * UDAT_FIELD_COUNT);
"y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567",
"y/M/d H:mm:ss.SSSS", "pf", "2004/3/10 16:36:31.5679", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.5670",
};
- expect(DATA, ARRAY_SIZE(DATA), Locale("en", "", ""));
+ expect(DATA, UPRV_LENGTHOF(DATA), Locale("en", "", ""));
}
// -------------------------------------
DateFormat::EStyle looks[] = {
DateFormat::SHORT, DateFormat::MEDIUM, DateFormat::LONG, DateFormat::FULL
};
- int32_t looks_length = (int32_t)(sizeof(looks) / sizeof(looks[0]));
+ int32_t looks_length = UPRV_LENGTHOF(looks);
const char* strings[] = {
"Mar 15", "Mar 15 1997", "asdf", "3/1/97 1:23:", "3/1/00 1:23:45 AM"
};
- int32_t strings_length = (int32_t)(sizeof(strings) / sizeof(strings[0]));
+ int32_t strings_length = UPRV_LENGTHOF(strings);
DateFormat *full = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::LONG);
if(full==NULL) {
dataerrln("could not create date time instance");
"3:00 pm Jan 1, 1997", 0, 0, 0, 0, 0, 0, 0, "0003", "3:00 PM January 1, 1997",
};
#endif
-
+
// -------------------------------------
/**
}
const char* s;
UDate date;
- const uint32_t PF_LENGTH = (int32_t)(sizeof(parseFormats)/sizeof(parseFormats[0]));
- const uint32_t INPUT_LENGTH = (int32_t)(sizeof(inputStrings)/sizeof(inputStrings[0]));
+ const uint32_t PF_LENGTH = UPRV_LENGTHOF(parseFormats);
+ const uint32_t INPUT_LENGTH = UPRV_LENGTHOF(inputStrings);
dateParse->applyPattern("d MMMM, yyyy");
dateParse->adoptTimeZone(TimeZone::createDefault());
UnicodeString("short format: "), UnicodeString("4/4/97 11:00 PM"),
UnicodeString("M/d/yy h:mm a")
};
- int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0]));
+ int32_t DATA_length = UPRV_LENGTHOF(DATA);
for (int32_t i=0; i<DATA_length; i+=3) {
DateFormat *fmt = new SimpleDateFormat(DATA[i+2], Locale::getEnglish(), status);
DateFormat::FULL, Locale::getFrench());
DateFormat *dfUS = DateFormat::createDateTimeInstance(DateFormat::FULL,
DateFormat::FULL, Locale::getUS());
- UnicodeString expectedFRENCH ( "lundi 15 septembre 1997 00:00:00 heure d\\u2019\\u00E9t\\u00E9 du Pacifique", -1, US_INV );
+ UnicodeString expectedFRENCH ( "lundi 15 septembre 1997 \\u00E0 00:00:00 heure d\\u2019\\u00E9t\\u00E9 du Pacifique", -1, US_INV );
expectedFRENCH = expectedFRENCH.unescape();
UnicodeString expectedUS ( "Monday, September 15, 1997 at 12:00:00 AM Pacific Daylight Time" );
logln((UnicodeString)"Date set to : " + dateToString(testDate));
void
DateFormatTest::TestFormattingLocaleTimeSeparator()
{
+ // This test not as useful is it once was, since timeSeparator
+ // in the Arabic is changed back to ":" in CLDR 28.
const UDate testDate = 874266720000.; // Sun Sep 14 21:52:00 CET 1997
logln((UnicodeString)"Date set to : " + dateToString(testDate));
dfLatn->setTimeZone(*tz);
const UnicodeString expectedArab = UnicodeString(
- "\\u0669:\\u0665\\u0662 \\u0645", -1, US_INV).unescape();
+ "\\u0669:\\u0665\\u0662\\u00A0\\u0645", -1, US_INV).unescape();
const UnicodeString expectedLatn = UnicodeString(
- "9:52 \\u0645", -1, US_INV).unescape();
+ "9:52\\u00A0\\u0645", -1, US_INV).unescape();
UnicodeString actualArab;
UnicodeString actualLatn;
NULL, "12:34:56PM", "1970 01 01 12:34:56",
NULL, "12.34.56PM", "1970 01 01 12:34:56",
NULL, "12 : 34 : 56 PM", "1970 01 01 12:34:56",
-
+
"MM d yy 'at' hh:mm:ss a", "04/05/06 12:34:56 PM", "2006 04 05 12:34:56",
-
+
"MMMM dd yyyy hh:mm a", "September 27, 1964 21:56 PM", "1964 09 28 09:56:00",
NULL, "November 4, 2008 0:13 AM", "2008 11 04 00:13:00",
-
+
"HH'h'mm'min'ss's'", "12h34min56s", "1970 01 01 12:34:56",
NULL, "12h34mi56s", "1970 01 01 12:34:56",
NULL, "12h34m56s", "1970 01 01 12:34:56",
NULL, "12:34:56", "1970 01 01 12:34:56"
};
- const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
+ const int32_t DATA_len = UPRV_LENGTHOF(DATA);
expectParse(DATA, DATA_len, Locale("en"));
}
NULL, "00+05", NULL,
"ahhmm", "PM730", "1970 01 01 19:30:00",
};
- const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
+ const int32_t DATA_len = UPRV_LENGTHOF(DATA);
expectParse(DATA, DATA_len, Locale("en"));
}
"MM d yy", " 04 01 03", "2003 04 01",
NULL, " 04 01 03 ", "2003 04 01",
};
- const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
+ const int32_t DATA_len = UPRV_LENGTHOF(DATA);
expectParse(DATA, DATA_len, Locale("en"));
}
"LLL", "fp", "1970 12 01 0:00:00", "pro", "1970 12 01 0:00:00",
};
- expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
- expect(CS_DATA, ARRAY_SIZE(CS_DATA), Locale("cs", "", ""));
+ expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
+ expect(CS_DATA, UPRV_LENGTHOF(CS_DATA), Locale("cs", "", ""));
}
void DateFormatTest::TestStandAloneDays()
"ccc", "fp", "1970 01 03 0:00:00", "so", "1970 01 03 0:00:00",
};
- expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
- expect(CS_DATA, ARRAY_SIZE(CS_DATA), Locale("cs", "", ""));
+ expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
+ expect(CS_DATA, UPRV_LENGTHOF(CS_DATA), Locale("cs", "", ""));
}
void DateFormatTest::TestShortDays()
"EEEEEE d MMM y", "fp", "2013 01 13 0:00:00", "s\\u00F6 13 jan. 2013", "2013 01 13 0:00:00",
"EEEEEE d MMM y", "fp", "2013 01 16 0:00:00", "on 16 jan. 2013", "2013 01 16 0:00:00",
"EEEEEE d", "fp", "1970 01 17 0:00:00", "l\\u00F6 17", "1970 01 17 0:00:00",
- "cccccc d", "fp", "1970 01 17 0:00:00", "L\\u00F6 17", "1970 01 17 0:00:00",
- "cccccc", "fp", "1970 01 03 0:00:00", "L\\u00F6", "1970 01 03 0:00:00",
+ "cccccc d", "fp", "1970 01 17 0:00:00", "l\\u00F6 17", "1970 01 17 0:00:00",
+ "cccccc", "fp", "1970 01 03 0:00:00", "l\\u00F6", "1970 01 03 0:00:00",
};
- expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
- expect(SV_DATA, ARRAY_SIZE(SV_DATA), Locale("sv", "", ""));
+ expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
+ expect(SV_DATA, UPRV_LENGTHOF(SV_DATA), Locale("sv", "", ""));
}
void DateFormatTest::TestNarrowNames()
"ccccc", "1970 01 01 0:00:00", "T",
"ccccc", "1970 01 02 0:00:00", "F",
"ccccc", "1970 01 03 0:00:00", "S",
-
+
"h:mm a", "2015 01 01 10:00:00", "10:00 AM",
"h:mm a", "2015 01 01 22:00:00", "10:00 PM",
"h:mm aaaaa", "2015 01 01 10:00:00", "10:00 a",
"ccccc", "1970 01 01 0:00:00", "\\u010C",
"ccccc", "1970 01 02 0:00:00", "P",
"ccccc", "1970 01 03 0:00:00", "S",
-
- "h:mm a", "2015 01 01 10:00:00", "10:00 dopoledne",
- "h:mm a", "2015 01 01 22:00:00", "10:00 odpoledne",
+
+ "h:mm a", "2015 01 01 10:00:00", "10:00 dop.",
+ "h:mm a", "2015 01 01 22:00:00", "10:00 odp.",
"h:mm aaaaa", "2015 01 01 10:00:00", "10:00 dop.",
"h:mm aaaaa", "2015 01 01 22:00:00", "10:00 odp.",
};
"h:mm aaaaa", "2015 01 01 22:00:00", "10:00 p.m.",
};
- expectFormat(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
- expectFormat(CS_DATA, ARRAY_SIZE(CS_DATA), Locale("cs", "", ""));
- expectFormat(CA_DATA, ARRAY_SIZE(CA_DATA), Locale("ca", "", ""));
+ expectFormat(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
+ expectFormat(CS_DATA, UPRV_LENGTHOF(CS_DATA), Locale("cs", "", ""));
+ expectFormat(CA_DATA, UPRV_LENGTHOF(CA_DATA), Locale("ca", "", ""));
}
void DateFormatTest::TestEras()
"MMMM dd yyyy GGGG", "fp", "-438 07 17", "July 17 0439 Before Christ", "-438 07 17",
};
- expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
+ expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
}
void DateFormatTest::TestQuarters()
"qq", "fp", "1970 04 01", "02", "1970 04 01",
"qqq", "fp", "1970 07 01", "Q3", "1970 07 01",
"qqqq", "fp", "1970 10 01", "4th quarter", "1970 10 01",
+
+ "Qyy", "fp", "2015 04 01", "215", "2015 04 01",
+ "QQyy", "fp", "2015 07 01", "0315", "2015 07 01",
};
- expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
+ expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
}
/**
"y/M/d H:mm", "pf", "2004/10/31 1:30", "2004 10 31 01:30 PST", "2004/10/31 1:30",
};
- const int32_t ZDATA_length = sizeof(ZDATA)/ sizeof(ZDATA[0]);
+ const int32_t ZDATA_length = UPRV_LENGTHOF(ZDATA);
expect(ZDATA, ZDATA_length, en);
UErrorCode status = U_ZERO_ERROR;
dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(status));
return;
}
- const int32_t formats_length = sizeof(formats)/sizeof(formats[0]);
+ const int32_t formats_length = UPRV_LENGTHOF(formats);
UnicodeString test;
SimpleDateFormat univ("yyyy MM dd HH:mm zzz", en, status);
"2004 01 02 03:04 PST",
"2004 07 08 09:10 PDT"
};
- int32_t times_length = sizeof(times)/sizeof(times[0]);
+ int32_t times_length = UPRV_LENGTHOF(times);
for (int i = 0; i < times_length; ++i) {
UDate d = univ.parse(times[i], status);
logln(UnicodeString("\ntime: ") + d);
"y/M/d v H:mm", "pf", "2004/7/1 PT 1:00", "2004 07 01 01:00 PDT", "2004/7/1 PT 1:00",
"v y/M/d H:mm", "pf", "PT 2004/7/1 1:00", "2004 07 01 01:00 PDT", "PT 2004/7/1 1:00",
};
- const int32_t XDATA_length = sizeof(XDATA)/sizeof(XDATA[0]);
+ const int32_t XDATA_length = UPRV_LENGTHOF(XDATA);
Locale en("en");
expect(XDATA, XDATA_length, en);
}
};
UnicodeString result;
- int32_t tests_length = sizeof(tests)/sizeof(tests[0]);
+ int32_t tests_length = UPRV_LENGTHOF(tests);
for (int i = 0; i < tests_length; ++i) {
pp.setIndex(0);
UDate d = univ.parse(tests[i].input, pp);
if(pp.getIndex() != tests[i].input.length()){
errln("Test %i: setZoneString() did not succeed. Consumed: %i instead of %i",
- i, pp.getIndex(), tests[i].input.length());
+ i, pp.getIndex(), tests[i].input.length());
return;
}
result.remove();
void DateFormatTest::TestHost(void)
{
-#if U_PLATFORM_HAS_WIN32_API
+#if U_PLATFORM_USES_ONLY_WIN32_API
Win32DateTimeTest::testLocales(this);
#endif
}
UErrorCode status = U_ZERO_ERROR;
- FieldPosition pos(0);
+ FieldPosition pos(FieldPosition::DONT_CARE);
UnicodeString test;
Locale en("en");
DateFormat *fullrelative = DateFormat::createDateInstance(DateFormat::kFullRelative, loc);
Locale loc("de_CH_LUCERNE");
LocalPointer<DateFormat> fmt(
DateFormat::createDateInstance(DateFormat::kDefault, loc));
+ if (fmt.isNull()) {
+ dataerrln("FAIL: DateFormat::createDateInstance failed for %s", loc.getName());
+ return;
+ }
Locale valid1;
Locale actual1;
if (!getActualAndValidLocales(*fmt, valid1, actual1)) {
{ "bg", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+01:00", "+1:00" },
{ "bg", "Europe/London", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+1", "+1:00" },
{ "bg", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u0411\\u0440\\u0438\\u0442\\u0430\\u043d\\u0441\\u043a\\u043e \\u043b\\u044f\\u0442\\u043d\\u043e \\u0447\\u0430\\u0441\\u043e\\u0432\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "+1:00" },
- { "bg", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u0412\\u0435\\u043b\\u0438\\u043a\\u043e\\u0431\\u0440\\u0438\\u0442\\u0430\\u043d\\u0438\\u044f", "Europe/London" },
- { "bg", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u0412\\u0435\\u043b\\u0438\\u043a\\u043e\\u0431\\u0440\\u0438\\u0442\\u0430\\u043d\\u0438\\u044f", "Europe/London" },
+ { "bg", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u041E\\u0431\\u0435\\u0434\\u0438\\u043D\\u0435\\u043D\\u043E\\u0442\\u043E \\u043A\\u0440\\u0430\\u043B\\u0441\\u0442\\u0432\\u043E", "Europe/London" },
+ { "bg", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u041E\\u0431\\u0435\\u0434\\u0438\\u043D\\u0435\\u043D\\u043E\\u0442\\u043E \\u043A\\u0440\\u0430\\u043B\\u0441\\u0442\\u0432\\u043E", "Europe/London" },
{ "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
{ "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
ASSERT_OK(status);
cal->adoptTimeZone(tz);
UnicodeString result;
- FieldPosition pos(0);
+ FieldPosition pos(FieldPosition::DONT_CARE);
fmt.format(*cal,result,pos);
if (result != info[4]) {
errln(info[0] + ";" + info[1] + ";" + info[2] + ";" + info[3] + " expected: '" +
"HH:mm:ssZZZZZ", "14:25:45Z", "14:25:45 +0000",
"HH:mm:ssZZZZZ", "15:00:00-08:00", "15:00:00 -0800",
};
- const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
+ const int32_t DATA_len = UPRV_LENGTHOF(DATA);
expectParse(DATA, DATA_len, Locale("en"));
}
TimeZone *tz = TimeZone::createTimeZone("Asia/Shanghai");
GregorianCalendar gcal(*tz, status);
if (failure(status, "construct GregorianCalendar", TRUE)) return;
-
+
gcal.clear();
gcal.set(1900, UCAL_JULY, 1, 12, 00); // offset 8:05:43
d1 = gcal.getTime(status);
}
}
-void DateFormatTest::TestISOEra() {
-
- const char* data[] = {
- // input, output
- "BC 4004-10-23T07:00:00Z", "BC 4004-10-23T07:00:00Z",
- "AD 4004-10-23T07:00:00Z", "AD 4004-10-23T07:00:00Z",
- "-4004-10-23T07:00:00Z" , "BC 4005-10-23T07:00:00Z",
- "4004-10-23T07:00:00Z" , "AD 4004-10-23T07:00:00Z",
- };
-
- int32_t numData = 8;
-
- UErrorCode status = U_ZERO_ERROR;
-
- // create formatter
- SimpleDateFormat *fmt1 = new SimpleDateFormat(UnicodeString("GGG yyyy-MM-dd'T'HH:mm:ss'Z"), status);
- failure(status, "new SimpleDateFormat", TRUE);
+void DateFormatTest::TestISOEra() {
+
+ const char* data[] = {
+ // input, output
+ "BC 4004-10-23T07:00:00Z", "BC 4004-10-23T07:00:00Z",
+ "AD 4004-10-23T07:00:00Z", "AD 4004-10-23T07:00:00Z",
+ "-4004-10-23T07:00:00Z" , "BC 4005-10-23T07:00:00Z",
+ "4004-10-23T07:00:00Z" , "AD 4004-10-23T07:00:00Z",
+ };
+
+ int32_t numData = 8;
+
+ UErrorCode status = U_ZERO_ERROR;
+
+ // create formatter
+ SimpleDateFormat *fmt1 = new SimpleDateFormat(UnicodeString("GGG yyyy-MM-dd'T'HH:mm:ss'Z"), status);
+ failure(status, "new SimpleDateFormat", TRUE);
if (status == U_MISSING_RESOURCE_ERROR) {
if (fmt1 != NULL) {
delete fmt1;
}
return;
}
- for(int i=0; i < numData; i+=2) {
- // create input string
- UnicodeString in = data[i];
-
- // parse string to date
- UDate dt1 = fmt1->parse(in, status);
- failure(status, "fmt->parse", TRUE);
-
- // format date back to string
- UnicodeString out;
- out = fmt1->format(dt1, out);
- logln(out);
-
- // check that roundtrip worked as expected
- UnicodeString expected = data[i+1];
- if (out != expected) {
- dataerrln((UnicodeString)"FAIL: " + in + " -> " + out + " expected -> " + expected);
- }
- }
-
- delete fmt1;
-}
-void DateFormatTest::TestFormalChineseDate() {
-
- UErrorCode status = U_ZERO_ERROR;
+ for(int i=0; i < numData; i+=2) {
+ // create input string
+ UnicodeString in = data[i];
+
+ // parse string to date
+ UDate dt1 = fmt1->parse(in, status);
+ failure(status, "fmt->parse", TRUE);
+
+ // format date back to string
+ UnicodeString out;
+ out = fmt1->format(dt1, out);
+ logln(out);
+
+ // check that roundtrip worked as expected
+ UnicodeString expected = data[i+1];
+ if (out != expected) {
+ dataerrln((UnicodeString)"FAIL: " + in + " -> " + out + " expected -> " + expected);
+ }
+ }
+
+ delete fmt1;
+}
+void DateFormatTest::TestFormalChineseDate() {
+
+ UErrorCode status = U_ZERO_ERROR;
UnicodeString pattern ("y\\u5e74M\\u6708d\\u65e5", -1, US_INV );
pattern = pattern.unescape();
UnicodeString override ("y=hanidec;M=hans;d=hans", -1, US_INV );
-
- // create formatter
+
+ // create formatter
SimpleDateFormat *sdf = new SimpleDateFormat(pattern,override,Locale::getChina(),status);
if (failure(status, "new SimpleDateFormat with override", TRUE)) {
return;
}
UDate thedate = date(2009-1900, UCAL_JULY, 28);
- FieldPosition pos(0);
+ FieldPosition pos(FieldPosition::DONT_CARE);
UnicodeString result;
sdf->format(thedate,result,pos);
-
- UnicodeString expected = "\\u4e8c\\u3007\\u3007\\u4e5d\\u5e74\\u4e03\\u6708\\u4e8c\\u5341\\u516b\\u65e5";
+
+ UnicodeString expected = "\\u4e8c\\u3007\\u3007\\u4e5d\\u5e74\\u4e03\\u6708\\u4e8c\\u5341\\u516b\\u65e5";
expected = expected.unescape();
- if (result != expected) {
- dataerrln((UnicodeString)"FAIL: -> " + result + " expected -> " + expected);
- }
-
+ if (result != expected) {
+ dataerrln((UnicodeString)"FAIL: -> " + result + " expected -> " + expected);
+ }
+
UDate parsedate = sdf->parse(expected,status);
if ( parsedate != thedate ) {
UnicodeString pat1 ("yyyy-MM-dd'T'HH:mm:ss'Z'", -1, US_INV );
UnicodeString parsedres,expres;
usf->format(parsedate,parsedres,pos);
usf->format(thedate,expres,pos);
- dataerrln((UnicodeString)"FAIL: parsed -> " + parsedres + " expected -> " + expres);
+ dataerrln((UnicodeString)"FAIL: parsed -> " + parsedres + " expected -> " + expres);
delete usf;
}
delete sdf;
void DateFormatTest::TestStandAloneGMTParse() {
UErrorCode status = U_ZERO_ERROR;
SimpleDateFormat *sdf = new SimpleDateFormat("ZZZZ", Locale(""), status);
-
+
if (U_SUCCESS(status)) {
UnicodeString inText("GMT$$$");
{ "root@calendar=chinese", -3, { UnicodeString("ren-chen-4-2"), UnicodeString("ren-chen-4bis-2"), UnicodeString("ren-chen-5-2") } },
{ "root@calendar=chinese", -4, { UnicodeString("ren-chen M04 2"), UnicodeString("ren-chen M04bis 2"), UnicodeString("ren-chen M05 2") } },
{ "en@calendar=gregorian", -3, { UnicodeString("2012-4-22"), UnicodeString("2012-5-22"), UnicodeString("2012-6-20") } },
- { "en@calendar=chinese", DateFormat::kLong, { UnicodeString("Month4 2, 2012(ren-chen)"), UnicodeString("Month4bis 2, 2012(ren-chen)"), UnicodeString("Month5 2, 2012(ren-chen)") } },
+ { "en@calendar=chinese", DateFormat::kLong, { UnicodeString("Fourth Month 2, 2012(ren-chen)"), UnicodeString("Fourth Monthbis 2, 2012(ren-chen)"), UnicodeString("Fifth Month 2, 2012(ren-chen)") } },
{ "en@calendar=chinese", DateFormat::kShort, { UnicodeString("4/2/2012"), UnicodeString("4bis/2/2012"), UnicodeString("5/2/2012") } },
{ "zh@calendar=chinese", DateFormat::kLong, { CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u56DB\\u6708\\u521D\\u4E8C"),
CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u95F0\\u56DB\\u6708\\u521D\\u4E8C"),
CharsToUnicodeString("2 s\\u00ECyu\\u00E8bis ren-chen"),
CharsToUnicodeString("2 w\\u01D4yu\\u00E8 ren-chen") } },
{ "fr@calendar=chinese", DateFormat::kShort, { UnicodeString("2/4/29"), UnicodeString("2/4bis/29"), UnicodeString("2/5/29") } },
- { "en@calendar=dangi", DateFormat::kLong, { UnicodeString("Month3bis 2, 2012(29)"), UnicodeString("Month4 2, 2012(29)"), UnicodeString("Month5 1, 2012(29)") } },
+ { "en@calendar=dangi", DateFormat::kLong, { UnicodeString("Third Monthbis 2, 2012(ren-chen)"), UnicodeString("Fourth Month 2, 2012(ren-chen)"), UnicodeString("Fifth Month 1, 2012(ren-chen)") } },
{ "en@calendar=dangi", DateFormat::kShort, { UnicodeString("3bis/2/2012"), UnicodeString("4/2/2012"), UnicodeString("5/1/2012") } },
{ "en@calendar=dangi", -2, { UnicodeString("78x29-3bis-2"), UnicodeString("78x29-4-2"), UnicodeString("78x29-5-1") } },
{ "ko@calendar=dangi", DateFormat::kLong, { CharsToUnicodeString("\\uC784\\uC9C4\\uB144 \\uC7243\\uC6D4 2\\uC77C"),
// terminator
{ NULL, 0, { UnicodeString(""), UnicodeString(""), UnicodeString("") } }
};
-
+
//. style: -1 -2 -3 -4
const UnicodeString customPatterns[] = { "y-Ml-d", "G'x'y-Ml-d", "U-M-d", "U MMM d" }; // like old root pattern, using 'l'
rootChineseCalendar->set(datePtr->year, datePtr->month-1, datePtr->day);
rootChineseCalendar->set(UCAL_IS_LEAP_MONTH, datePtr->isLeapMonth);
UnicodeString result;
- FieldPosition fpos(0);
+ FieldPosition fpos(FieldPosition::DONT_CARE);
dmft->format(*rootChineseCalendar, result, fpos);
if ( result.compare(itemPtr->dateString[idate]) != 0 ) {
errln( UnicodeString("FAIL: Chinese calendar format for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
} else {
sdmft->setContext(itemPtr->capitalizationContext, status);
UnicodeString result;
- FieldPosition pos(0);
+ FieldPosition pos(FieldPosition::DONT_CARE);
sdmft->format(*cal, result, pos);
if (result.compare(itemPtr->expectedFormat) != 0) {
errln(UnicodeString("FAIL: format for locale ") + UnicodeString(itemPtr->locale) +
cal->set(UCAL_HOUR_OF_DAY, caftItemPtr->hour);
cal->set(UCAL_MINUTE, caftItemPtr->minute);
UnicodeString result;
- FieldPosition fpos(0);
+ FieldPosition fpos(FieldPosition::DONT_CARE);
dfmt->format(*cal, result, fpos);
if ( result.compare(caftItemPtr->formattedDate) != 0 ) {
errln( UnicodeString("FAIL: date format for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
}
}
+typedef struct {
+ const char* localeID;
+ DateFormat::EStyle style;
+ UnicodeString expectPattern;
+ UnicodeString expectFormat;
+} TestFmtWithNumSysItem;
+enum { kBBufMax = 128 };
+void DateFormatTest::TestFormatsWithNumberSystems()
+{
+ LocalPointer<TimeZone> zone(TimeZone::createTimeZone(UnicodeString("UTC")));
+ const UDate date = 1451556000000.0; // for UTC: grego 31-Dec-2015 10 AM, hebrew 19 tevet 5776, chinese yi-wei 11mo 21day
+ const TestFmtWithNumSysItem items[] = {
+ { "haw@calendar=gregorian", DateFormat::kShort, UnicodeString("d/M/yy"), UnicodeString("31/xii/15") },
+ { "he@calendar=hebrew", DateFormat::kLong, CharsToUnicodeString("d \\u05D1MMMM y"), CharsToUnicodeString("\\u05D9\\u05F4\\u05D8 \\u05D1\\u05D8\\u05D1\\u05EA \\u05EA\\u05E9\\u05E2\\u05F4\\u05D5") }, // "י״ט בטבת תשע״ו"
+ { "zh@calendar=chinese", DateFormat::kLong, CharsToUnicodeString("rU\\u5E74MMMd"), CharsToUnicodeString("2015\\u4E59\\u672A\\u5E74\\u51AC\\u6708\\u5EFF\\u4E00") }, // "2015乙未年冬月廿一"
+ { "zh_Hant@calendar=chinese", DateFormat::kLong, CharsToUnicodeString("rU\\u5E74MMMd"), CharsToUnicodeString("2015\\u4E59\\u672A\\u5E74\\u51AC\\u6708\\u5EFF\\u4E00") }, // "2015乙未年冬月廿一"
+ { "ja@calendar=chinese", DateFormat::kLong, CharsToUnicodeString("U\\u5E74MMMd\\u65E5"), CharsToUnicodeString("\\u4E59\\u672A\\u5E74\\u5341\\u4E00\\u6708\\u4E8C\\u5341\\u4E00\\u65E5") }, // "乙未年十一月二十一日"
+ { NULL, DateFormat::kNone, UnicodeString(""), UnicodeString("") },
+ };
+ const TestFmtWithNumSysItem * itemPtr;
+ for (itemPtr = items; itemPtr->localeID != NULL; itemPtr++) {
+ char bExpected[kBBufMax];
+ char bResult[kBBufMax];
+ UErrorCode status = U_ZERO_ERROR;
+ Locale locale = Locale::createFromName(itemPtr->localeID);
+ LocalPointer<Calendar> cal(Calendar::createInstance(zone.orphan(), locale, status));
+ if (U_FAILURE(status)) {
+ dataerrln("Calendar::createInstance fails for locale %s, status %s", itemPtr->localeID, u_errorName(status));
+ continue;
+ }
+ cal->setTime(date, status);
+ if (U_FAILURE(status)) {
+ dataerrln("Calendar::setTime fails for locale %s, date %.1f, status %s", itemPtr->localeID, date, u_errorName(status));
+ continue;
+ }
+ LocalPointer<SimpleDateFormat> sdfmt(static_cast<SimpleDateFormat *>(DateFormat::createDateInstance(itemPtr->style, locale)));
+ if (sdfmt.isNull()) {
+ dataerrln("DateFormat::createDateInstance fails for locale %s", itemPtr->localeID);
+ continue;
+ }
+ UnicodeString getFormat;
+ sdfmt->format(*(cal.getAlias()), getFormat, NULL, status);
+ if (U_FAILURE(status)) {
+ errln("DateFormat::format fails for locale %s, status %s", itemPtr->localeID, u_errorName(status));
+ continue;
+ }
+ if (getFormat.compare(itemPtr->expectFormat) != 0) {
+ itemPtr->expectFormat.extract(0, itemPtr->expectFormat.length(), bExpected, kBBufMax);
+ getFormat.extract(0, getFormat.length(), bResult, kBBufMax);
+ errln("DateFormat::format for locale %s, expected \"%s\", got \"%s\"", itemPtr->localeID, bExpected, bResult);
+ }
+ UnicodeString getPattern;
+ sdfmt->toPattern(getPattern);
+ if (getPattern.compare(itemPtr->expectPattern) != 0) {
+ itemPtr->expectPattern.extract(0, itemPtr->expectPattern.length(), bExpected, kBBufMax);
+ getPattern.extract(0, getPattern.length(), bResult, kBBufMax);
+ errln("DateFormat::toPattern() for locale %s, expected \"%s\", got \"%s\"", itemPtr->localeID, bExpected, bResult);
+ }
+ }
+}
+
static const UDate TEST_DATE = 1326585600000.; // 2012-jan-15
void DateFormatTest::TestDotAndAtLeniency() {
void DateFormatTest::TestDateFormatLeniency() {
// For details see http://bugs.icu-project.org/trac/ticket/10261
-
+
const UDate july022008 = 1215000001979.0;
const TestDateFormatLeniencyItem items[] = {
//locale leniency parse String pattern expected result
{ "en", true, UnicodeString("2008-Jan--02"), UnicodeString("yyyy-MMM' -- 'dd"), UnicodeString("2008-Jan -- 02") },
{ "en", false, UnicodeString("2008-Jan--02"), UnicodeString("yyyy-MMM' -- 'dd"), UnicodeString("") },
// terminator
- { NULL, true, UnicodeString(""), UnicodeString(""), UnicodeString("") }
+ { NULL, true, UnicodeString(""), UnicodeString(""), UnicodeString("") }
};
UErrorCode status = U_ZERO_ERROR;
LocalPointer<Calendar> cal(Calendar::createInstance(status));
const TestDateFormatLeniencyItem * itemPtr;
LocalPointer<SimpleDateFormat> sdmft;
for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
-
+
Locale locale = Locale::createFromName(itemPtr->locale);
status = U_ZERO_ERROR;
ParsePosition pos(0);
}
sdmft->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->leniency, status).
setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->leniency, status).
- setBooleanAttribute(UDAT_PARSE_PARTIAL_MATCH, itemPtr->leniency, status);
- UDate d = sdmft->parse(itemPtr->parseString, pos);
+ setBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, itemPtr->leniency, status);
+ UDate d = sdmft->parse(itemPtr->parseString, pos);
if(itemPtr->expectedResult.length() == 0) {
if(pos.getErrorIndex() != -1) {
continue;
} else {
- errln("error: unexpected parse success - " + itemPtr->parseString +
- " - pattern " + itemPtr->pattern +
- " - error index " + pos.getErrorIndex() +
+ errln("error: unexpected parse success - " + itemPtr->parseString +
+ " - pattern " + itemPtr->pattern +
+ " - error index " + pos.getErrorIndex() +
" - leniency " + itemPtr->leniency);
continue;
}
}
- if(pos.getErrorIndex() != -1) {
- errln("error: parse error for string - " + itemPtr->parseString +
- " - pattern " + itemPtr->pattern +
- " - idx " + pos.getIndex() +
- " - error index "+pos.getErrorIndex() +
- " - leniency " + itemPtr->leniency);
- continue;
+ if(pos.getErrorIndex() != -1) {
+ errln("error: parse error for string - " + itemPtr->parseString +
+ " - pattern " + itemPtr->pattern +
+ " - idx " + pos.getIndex() +
+ " - error index "+pos.getErrorIndex() +
+ " - leniency " + itemPtr->leniency);
+ continue;
}
- UnicodeString formatResult("");
+ UnicodeString formatResult("");
sdmft->format(d, formatResult);
- if(formatResult.compare(itemPtr->expectedResult) != 0) {
- errln("error: unexpected format result. pattern["+itemPtr->pattern+"] expected[" + itemPtr->expectedResult + "] but result was[" + formatResult + "]");
+ if(formatResult.compare(itemPtr->expectedResult) != 0) {
+ errln("error: unexpected format result. pattern["+itemPtr->pattern+"] expected[" + itemPtr->expectedResult + "] but result was[" + formatResult + "]");
continue;
- } else {
- logln("formatted results match! - " + formatResult);
- }
+ } else {
+ logln("formatted results match! - " + formatResult);
+ }
}
}
} TestMultiPatternMatchItem;
void DateFormatTest::TestParseMultiPatternMatch() {
- // For details see http://bugs.icu-project.org/trac/ticket/10336
+ // For details see http://bugs.icu-project.org/trac/ticket/10336
const TestMultiPatternMatchItem items[] = {
- // leniency parse String pattern expected result
- {true, UnicodeString("2013-Sep 13"), UnicodeString("yyyy-MMM dd"), UnicodeString("2013-Sep 13")},
- {true, UnicodeString("2013-September 14"), UnicodeString("yyyy-MMM dd"), UnicodeString("2013-Sep 14")},
- {false, UnicodeString("2013-September 15"), UnicodeString("yyyy-MMM dd"), UnicodeString("")},
- {false, UnicodeString("2013-September 16"), UnicodeString("yyyy-MMMM dd"), UnicodeString("2013-September 16")},
- {true, UnicodeString("2013-Sep 17"), UnicodeString("yyyy-LLL dd"), UnicodeString("2013-Sep 17")},
- {true, UnicodeString("2013-September 18"), UnicodeString("yyyy-LLL dd"), UnicodeString("2013-Sep 18")},
- {false, UnicodeString("2013-September 19"), UnicodeString("yyyy-LLL dd"), UnicodeString("")},
- {false, UnicodeString("2013-September 20"), UnicodeString("yyyy-LLLL dd"), UnicodeString("2013-September 20")},
- {true, UnicodeString("2013 Sat Sep 21"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("2013 Sat Sep 21")},
- {true, UnicodeString("2013 Sunday Sep 22"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("2013 Sun Sep 22")},
- {false, UnicodeString("2013 Monday Sep 23"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("")},
- {false, UnicodeString("2013 Tuesday Sep 24"), UnicodeString("yyyy EEEE MMM dd"), UnicodeString("2013 Tuesday Sep 24")},
- {true, UnicodeString("2013 Wed Sep 25"), UnicodeString("yyyy eee MMM dd"), UnicodeString("2013 Wed Sep 25")},
- {true, UnicodeString("2013 Thu Sep 26"), UnicodeString("yyyy eee MMM dd"), UnicodeString("2013 Thu Sep 26")},
- {false, UnicodeString("2013 Friday Sep 27"), UnicodeString("yyyy eee MMM dd"), UnicodeString("")},
- {false, UnicodeString("2013 Saturday Sep 28"), UnicodeString("yyyy eeee MMM dd"), UnicodeString("2013 Saturday Sep 28")},
- {true, UnicodeString("2013 Sun Sep 29"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("2013 Sun Sep 29")},
- {true, UnicodeString("2013 Monday Sep 30"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("2013 Mon Sep 30")},
- {false, UnicodeString("2013 Sunday Oct 13"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("")},
- {false, UnicodeString("2013 Monday Oct 14"), UnicodeString("yyyy cccc MMM dd"), UnicodeString("2013 Monday Oct 14")},
- {true, UnicodeString("2013 Oct 15 Q4"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 15 Q4")},
- {true, UnicodeString("2013 Oct 16 4th quarter"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 16 Q4")},
- {false, UnicodeString("2013 Oct 17 4th quarter"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("")},
- {false, UnicodeString("2013 Oct 18 Q4"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 18 Q4")},
- {true, UnicodeString("2013 Oct 19 Q4"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 19 4th quarter")},
- {true, UnicodeString("2013 Oct 20 4th quarter"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 20 4th quarter")},
- {false, UnicodeString("2013 Oct 21 Q4"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("")},
+ // leniency parse String pattern expected result
+ {true, UnicodeString("2013-Sep 13"), UnicodeString("yyyy-MMM dd"), UnicodeString("2013-Sep 13")},
+ {true, UnicodeString("2013-September 14"), UnicodeString("yyyy-MMM dd"), UnicodeString("2013-Sep 14")},
+ {false, UnicodeString("2013-September 15"), UnicodeString("yyyy-MMM dd"), UnicodeString("")},
+ {false, UnicodeString("2013-September 16"), UnicodeString("yyyy-MMMM dd"), UnicodeString("2013-September 16")},
+ {true, UnicodeString("2013-Sep 17"), UnicodeString("yyyy-LLL dd"), UnicodeString("2013-Sep 17")},
+ {true, UnicodeString("2013-September 18"), UnicodeString("yyyy-LLL dd"), UnicodeString("2013-Sep 18")},
+ {false, UnicodeString("2013-September 19"), UnicodeString("yyyy-LLL dd"), UnicodeString("")},
+ {false, UnicodeString("2013-September 20"), UnicodeString("yyyy-LLLL dd"), UnicodeString("2013-September 20")},
+ {true, UnicodeString("2013 Sat Sep 21"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("2013 Sat Sep 21")},
+ {true, UnicodeString("2013 Sunday Sep 22"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("2013 Sun Sep 22")},
+ {false, UnicodeString("2013 Monday Sep 23"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("")},
+ {false, UnicodeString("2013 Tuesday Sep 24"), UnicodeString("yyyy EEEE MMM dd"), UnicodeString("2013 Tuesday Sep 24")},
+ {true, UnicodeString("2013 Wed Sep 25"), UnicodeString("yyyy eee MMM dd"), UnicodeString("2013 Wed Sep 25")},
+ {true, UnicodeString("2013 Thu Sep 26"), UnicodeString("yyyy eee MMM dd"), UnicodeString("2013 Thu Sep 26")},
+ {false, UnicodeString("2013 Friday Sep 27"), UnicodeString("yyyy eee MMM dd"), UnicodeString("")},
+ {false, UnicodeString("2013 Saturday Sep 28"), UnicodeString("yyyy eeee MMM dd"), UnicodeString("2013 Saturday Sep 28")},
+ {true, UnicodeString("2013 Sun Sep 29"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("2013 Sun Sep 29")},
+ {true, UnicodeString("2013 Monday Sep 30"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("2013 Mon Sep 30")},
+ {false, UnicodeString("2013 Sunday Oct 13"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("")},
+ {false, UnicodeString("2013 Monday Oct 14"), UnicodeString("yyyy cccc MMM dd"), UnicodeString("2013 Monday Oct 14")},
+ {true, UnicodeString("2013 Oct 15 Q4"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 15 Q4")},
+ {true, UnicodeString("2013 Oct 16 4th quarter"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 16 Q4")},
+ {false, UnicodeString("2013 Oct 17 4th quarter"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("")},
+ {false, UnicodeString("2013 Oct 18 Q4"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 18 Q4")},
+ {true, UnicodeString("2013 Oct 19 Q4"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 19 4th quarter")},
+ {true, UnicodeString("2013 Oct 20 4th quarter"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 20 4th quarter")},
+ {false, UnicodeString("2013 Oct 21 Q4"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("")},
{false, UnicodeString("2013 Oct 22 4th quarter"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 22 4th quarter")},
{false, UnicodeString("--end--"), UnicodeString(""), UnicodeString("")},
};
continue;
}
sdmft->setBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, itemPtr->leniency, status);
- UDate d = sdmft->parse(itemPtr->parseString, pos);
-
+ UDate d = sdmft->parse(itemPtr->parseString, pos);
+
if(itemPtr->expectedResult.length() == 0) {
if(pos.getErrorIndex() != -1) {
continue;
} else {
- errln("error: unexpected parse success - " + itemPtr->parseString +
- " - error index " + pos.getErrorIndex() +
+ errln("error: unexpected parse success - " + itemPtr->parseString +
+ " - error index " + pos.getErrorIndex() +
" - leniency " + itemPtr->leniency);
continue;
}
}
- if(pos.getErrorIndex() != -1) {
- errln("error: parse error for string - " +itemPtr->parseString + " -- idx["+pos.getIndex()+"] errIdx["+pos.getErrorIndex()+"]");
- continue;
+ if(pos.getErrorIndex() != -1) {
+ errln("error: parse error for string - " +itemPtr->parseString + " -- idx["+pos.getIndex()+"] errIdx["+pos.getErrorIndex()+"]");
+ continue;
}
- UnicodeString formatResult("");
+ UnicodeString formatResult("");
sdmft->format(d, formatResult);
- if(formatResult.compare(itemPtr->expectedResult) != 0) {
- errln("error: unexpected format result. expected[" + itemPtr->expectedResult + "] but result was[" + formatResult + "]");
- } else {
- logln("formatted results match! - " + formatResult);
- }
+ if(formatResult.compare(itemPtr->expectedResult) != 0) {
+ errln("error: unexpected format result. expected[" + itemPtr->expectedResult + "] but result was[" + formatResult + "]");
+ } else {
+ logln("formatted results match! - " + formatResult);
+ }
}
delete sdmft;
}
assertTrue("isCalendarLenient default", fmt->isCalendarLenient());
assertTrue("ALLOW_WHITESPACE default", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status));
assertTrue("ALLOW_NUMERIC default", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status));
- assertTrue("PARTIAL_MATCH default", fmt->getBooleanAttribute(UDAT_PARSE_PARTIAL_MATCH, status));
+ assertTrue("PARTIAL_MATCH default", fmt->getBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, status));
assertTrue("MULTIPLE_PATTERNS default", fmt->getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status));
// Set calendar to strict
assertFalse("ALLOW_WHITESPACE after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status));
assertFalse("ALLOW_NUMERIC after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status));
// These two boolean attributes are NOT affected according to the API specification
- assertTrue("PARTIAL_MATCH after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_PARTIAL_MATCH, status));
+ assertTrue("PARTIAL_MATCH after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, status));
assertTrue("MULTIPLE_PATTERNS after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status));
// Allow white space leniency
fmt->adoptNumberFormat(fields, check_nf, status);
assertSuccess("adoptNumberFormat check_nf", status);
- const NumberFormat* get_nf = fmt->getNumberFormatForField('M');
+ const NumberFormat* get_nf = fmt->getNumberFormatForField((UChar)0x004D /*'M'*/);
if (get_nf != check_nf) errln("FAIL: getter and setter do not work");
}
NumberFormat* check_nf = NumberFormat::createInstance(Locale("en_US"), status);
{ "MdMMd", "\\u521D\\u516D \\u5341\\u4E94"},
{ "mixed", "\\u521D\\u516D \\u5341\\u4E94"}
};
-
+
UDate test_date = date(97, 6 - 1, 15);
- for(int i=0; i < (int)(sizeof(DATA)/sizeof(DATA[0])); i++){
+ for(int i=0; i < UPRV_LENGTHOF(DATA); i++){
fields = DATA[i][0];
-
+
LocalPointer<SimpleDateFormat> fmt;
fmt.adoptInsteadAndCheckErrorCode(new SimpleDateFormat((UnicodeString)"MM d", status), status);
assertSuccess("SimpleDateFormat with pattern MM d", status);
fields = (UnicodeString) "M";
fmt->adoptNumberFormat(fields, singleOverrideNF, status);
assertSuccess("adoptNumberFormat singleOverrideNF", status);
-
+
fmt->adoptNumberFormat(overrideNF);
} else if (fields == (UnicodeString) "Mo"){ // o is invlid field
fmt->adoptNumberFormat(fields, overrideNF, status);
}
UnicodeString result;
- FieldPosition pos(0);
+ FieldPosition pos(FieldPosition::DONT_CARE);
fmt->format(test_date,result, pos);
UnicodeString expected = ((UnicodeString)DATA[i][1]).unescape();;
- if (result != expected)
+ if (result != expected)
errln("FAIL: Expected " + expected + " get: " + result);
}
}
return;
}
UnicodeString result;
- FieldPosition pos(0);
+ FieldPosition pos(FieldPosition::DONT_CARE);
fmt->format(date(98, 5-1, 25), result, pos);
assertEquals("format yMMMMd", "May 25, 1998", result);
fmt.adoptInstead(DateFormat::createInstanceForSkeleton(
return;
}
UnicodeString result;
- FieldPosition pos(0);
+ FieldPosition pos(FieldPosition::DONT_CARE);
fmt->format(date(98, 5-1, 25), result, pos);
assertEquals("format yMMMd", "May 25, 1998", result);
}
return;
}
UnicodeString result;
- FieldPosition pos(0);
+ FieldPosition pos(FieldPosition::DONT_CARE);
LocalPointer<Calendar> cal(Calendar::createInstance(
TimeZone::createTimeZone("GMT-7:00"),
return;
}
UnicodeString result;
- FieldPosition pos(0);
+ FieldPosition pos(FieldPosition::DONT_CARE);
fmt->format(date(98, 5-1, 25), result, pos);
assertEquals("format yMMMd", "Iyar 29, 5758", result);
}
+void DateFormatTest::TestPatternFromSkeleton() {
+ static const struct {
+ const Locale& locale;
+ const char* const skeleton;
+ const char* const pattern;
+ } TESTDATA[] = {
+ // Ticket #11985
+ {Locale::getEnglish(), "jjmm", "h:mm a"},
+ {Locale::getEnglish(), "JJmm", "hh:mm"},
+ {Locale::getGerman(), "jjmm", "HH:mm"},
+ {Locale::getGerman(), "JJmm", "HH:mm"}
+ };
+
+ for (size_t i = 0; i < UPRV_LENGTHOF(TESTDATA); i++) {
+ UErrorCode status = U_ZERO_ERROR;
+ LocalPointer<DateFormat> fmt(
+ DateFormat::createInstanceForSkeleton(
+ TESTDATA[i].skeleton, TESTDATA[i].locale, status));
+ if (!assertSuccess("createInstanceForSkeleton", status)) {
+ return;
+ }
+ UnicodeString pattern;
+ static_cast<const SimpleDateFormat*>(fmt.getAlias())->toPattern(pattern);
+ assertEquals("Format pattern", TESTDATA[i].pattern, pattern);
+ }
+}
+
+void DateFormatTest::TestAmPmMidnightNoon() {
+ // Some times on 2015-11-13 (UTC+0).
+ UDate k000000 = 1447372800000.0;
+ UDate k000030 = 1447372830000.0;
+ UDate k003000 = 1447374600000.0;
+ UDate k060000 = 1447394400000.0;
+ UDate k120000 = 1447416000000.0;
+ UDate k180000 = 1447437600000.0;
+
+ UErrorCode errorCode = U_ZERO_ERROR;
+ SimpleDateFormat sdf(UnicodeString(), errorCode);
+ if (U_FAILURE(errorCode)) {
+ dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
+ return;
+ }
+ const TimeZone *tz = TimeZone::getGMT();
+ sdf.setTimeZone(*tz);
+ UnicodeString out;
+
+ // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
+ // For ICU 57 output of "midnight" is temporarily suppressed.
+
+ // Short.
+ sdf.applyPattern(UnicodeString("hh:mm:ss bbb"));
+
+ // assertEquals("hh:mm:ss bbb | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss bbb | 00:00:00", "12:00:00 AM", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss bbb | 00:00:30", "12:00:30 AM", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm:ss bbb | 00:30:00", "12:30:00 AM", sdf.format(k003000, out.remove()));
+ assertEquals("hh:mm:ss bbb | 06:00:00", "06:00:00 AM", sdf.format(k060000, out.remove()));
+ assertEquals("hh:mm:ss bbb | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove()));
+ assertEquals("hh:mm:ss bbb | 18:00:00", "06:00:00 PM", sdf.format(k180000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh:mm bbb"));
+
+ // assertEquals("hh:mm bbb | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm bbb | 00:00:00", "12:00 AM", sdf.format(k000000, out.remove()));
+ // assertEquals("hh:mm bbb | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm bbb | 00:00:30", "12:00 AM", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm bbb | 00:30:00", "12:30 AM", sdf.format(k003000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh bbb"));
+
+ // assertEquals("hh bbb | 00:00:00", "12 midnight", sdf.format(k000000, out.remove()));
+ assertEquals("hh bbb | 00:00:00", "12 AM", sdf.format(k000000, out.remove()));
+ // assertEquals("hh bbb | 00:00:30", "12 midnight", sdf.format(k000030, out.remove()));
+ assertEquals("hh bbb | 00:00:30", "12 AM", sdf.format(k000030, out.remove()));
+ // assertEquals("hh bbb | 00:30:00", "12 midnight", sdf.format(k003000, out.remove()));
+ assertEquals("hh bbb | 00:30:00", "12 AM", sdf.format(k003000, out.remove()));
+
+ // Wide.
+ sdf.applyPattern(UnicodeString("hh:mm:ss bbbb"));
+
+ // assertEquals("hh:mm:ss bbbb | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss bbbb | 00:00:00", "12:00:00 AM", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss bbbb | 00:00:30", "12:00:30 AM", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm:ss bbbb | 00:30:00", "12:30:00 AM", sdf.format(k003000, out.remove()));
+ assertEquals("hh:mm:ss bbbb | 06:00:00", "06:00:00 AM", sdf.format(k060000, out.remove()));
+ assertEquals("hh:mm:ss bbbb | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove()));
+ assertEquals("hh:mm:ss bbbb | 18:00:00", "06:00:00 PM", sdf.format(k180000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh:mm bbbb"));
+
+ // assertEquals("hh:mm bbbb | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm bbbb | 00:00:00", "12:00 AM", sdf.format(k000000, out.remove()));
+ // assertEquals("hh:mm bbbb | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm bbbb | 00:00:30", "12:00 AM", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm bbbb | 00:30:00", "12:30 AM", sdf.format(k003000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh bbbb"));
+
+ // assertEquals("hh bbbb | 00:00:00", "12 midnight", sdf.format(k000000, out.remove()));
+ assertEquals("hh bbbb | 00:00:00", "12 AM", sdf.format(k000000, out.remove()));
+ // assertEquals("hh bbbb | 00:00:30", "12 midnight", sdf.format(k000030, out.remove()));
+ assertEquals("hh bbbb | 00:00:30", "12 AM", sdf.format(k000030, out.remove()));
+ // assertEquals("hh bbbb | 00:30:00", "12 midnight", sdf.format(k003000, out.remove()));
+ assertEquals("hh bbbb | 00:30:00", "12 AM", sdf.format(k003000, out.remove()));
+
+ // Narrow.
+ sdf.applyPattern(UnicodeString("hh:mm:ss bbbbb"));
+
+ // assertEquals("hh:mm:ss bbbbb | 00:00:00", "12:00:00 mi", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss bbbbb | 00:00:00", "12:00:00 a", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss bbbbb | 00:00:30", "12:00:30 a", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm:ss bbbbb | 00:30:00", "12:30:00 a", sdf.format(k003000, out.remove()));
+ assertEquals("hh:mm:ss bbbbb | 06:00:00", "06:00:00 a", sdf.format(k060000, out.remove()));
+ assertEquals("hh:mm:ss bbbbb | 12:00:00", "12:00:00 n", sdf.format(k120000, out.remove()));
+ assertEquals("hh:mm:ss bbbbb | 18:00:00", "06:00:00 p", sdf.format(k180000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh:mm bbbbb"));
+
+ // assertEquals("hh:mm bbbbb | 00:00:00", "12:00 mi", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm bbbbb | 00:00:00", "12:00 a", sdf.format(k000000, out.remove()));
+ // assertEquals("hh:mm bbbbb | 00:00:30", "12:00 mi", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm bbbbb | 00:00:30", "12:00 a", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm bbbbb | 00:30:00", "12:30 a", sdf.format(k003000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh bbbbb"));
+
+ // assertEquals("hh bbbbb | 00:00:00", "12 mi", sdf.format(k000000, out.remove()));
+ assertEquals("hh bbbbb | 00:00:00", "12 a", sdf.format(k000000, out.remove()));
+ // assertEquals("hh bbbbb | 00:00:30", "12 mi", sdf.format(k000030, out.remove()));
+ assertEquals("hh bbbbb | 00:00:30", "12 a", sdf.format(k000030, out.remove()));
+ // assertEquals("hh bbbbb | 00:30:00", "12 mi", sdf.format(k003000, out.remove()));
+ assertEquals("hh bbbbb | 00:30:00", "12 a", sdf.format(k003000, out.remove()));
+}
+
+void DateFormatTest::TestFlexibleDayPeriod() {
+ // Some times on 2015-11-13 (UTC+0).
+ UDate k000000 = 1447372800000.0;
+ UDate k000030 = 1447372830000.0;
+ UDate k003000 = 1447374600000.0;
+ UDate k060000 = 1447394400000.0;
+ UDate k120000 = 1447416000000.0;
+ UDate k180000 = 1447437600000.0;
+
+ UErrorCode errorCode = U_ZERO_ERROR;
+ SimpleDateFormat sdf(UnicodeString(), errorCode);
+ if (U_FAILURE(errorCode)) {
+ dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
+ return;
+ }
+ const TimeZone *tz = TimeZone::getGMT();
+ sdf.setTimeZone(*tz);
+ UnicodeString out;
+
+ // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
+ // For ICU 57 output of "midnight" is temporarily suppressed.
+
+ // Short.
+ sdf.applyPattern(UnicodeString("hh:mm:ss BBB"));
+
+ // assertEquals("hh:mm:ss BBB | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss BBB | 00:00:00", "12:00:00 at night", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss BBB | 00:00:30", "12:00:30 at night", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm:ss BBB | 00:30:00", "12:30:00 at night", sdf.format(k003000, out.remove()));
+ assertEquals("hh:mm:ss BBB | 06:00:00", "06:00:00 in the morning", sdf.format(k060000, out.remove()));
+ assertEquals("hh:mm:ss BBB | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove()));
+ assertEquals("hh:mm:ss BBB | 18:00:00", "06:00:00 in the evening", sdf.format(k180000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh:mm BBB"));
+
+ // assertEquals("hh:mm BBB | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm BBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove()));
+ // assertEquals("hh:mm BBB | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm BBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm BBB | 00:30:00", "12:30 at night", sdf.format(k003000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh BBB"));
+
+ // assertEquals("hh BBB | 00:00:00", "12 midnight", sdf.format(k000000, out.remove()));
+ assertEquals("hh BBB | 00:00:30", "12 at night", sdf.format(k000030, out.remove()));
+ // assertEquals("hh BBB | 00:00:30", "12 midnight", sdf.format(k000030, out.remove()));
+ assertEquals("hh BBB | 00:00:30", "12 at night", sdf.format(k000030, out.remove()));
+ // assertEquals("hh BBB | 00:30:00", "12 midnight", sdf.format(k003000, out.remove()));
+ assertEquals("hh BBB | 00:30:00", "12 at night", sdf.format(k003000, out.remove()));
+
+ // Wide.
+ sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
+
+ // assertEquals("hh:mm:ss BBBB | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 00:00:00", "12:00:00 at night", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 00:00:30", "12:00:30 at night", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 00:30:00", "12:30:00 at night", sdf.format(k003000, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 06:00:00", "06:00:00 in the morning", sdf.format(k060000, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 18:00:00", "06:00:00 in the evening", sdf.format(k180000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh:mm BBBB"));
+
+ // assertEquals("hh:mm BBBB | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm BBBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove()));
+ // assertEquals("hh:mm BBBB | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm BBBB | 00:00:30", "12:00 at night", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm BBBB | 00:30:00", "12:30 at night", sdf.format(k003000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh BBBB"));
+
+ // assertEquals("hh BBBB | 00:00:00", "12 midnight", sdf.format(k000000, out.remove()));
+ assertEquals("hh BBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove()));
+ // assertEquals("hh BBBB | 00:00:30", "12 midnight", sdf.format(k000030, out.remove()));
+ assertEquals("hh BBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove()));
+ // assertEquals("hh BBBB | 00:80:00", "12 midnight", sdf.format(k003000, out.remove()));
+ assertEquals("hh BBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove()));
+
+ // Narrow.
+ sdf.applyPattern(UnicodeString("hh:mm:ss BBBBB"));
+
+ // assertEquals("hh:mm:ss BBBBB | 00:00:00", "12:00:00 mi", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss BBBBB | 00:00:00", "12:00:00 at night", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss BBBBB | 00:00:30", "12:00:30 at night", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm:ss BBBBB | 00:30:00", "12:30:00 at night", sdf.format(k003000, out.remove()));
+ assertEquals("hh:mm:ss BBBBB | 06:00:00", "06:00:00 in the morning", sdf.format(k060000, out.remove()));
+ assertEquals("hh:mm:ss BBBBB | 12:00:00", "12:00:00 n", sdf.format(k120000, out.remove()));
+ assertEquals("hh:mm:ss BBBBB | 18:00:00", "06:00:00 in the evening", sdf.format(k180000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh:mm BBBBB"));
+
+ // assertEquals("hh:mm BBBBB | 00:00:00", "12:00 mi", sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm BBBBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove()));
+ // assertEquals("hh:mm BBBBB | 00:00:30", "12:00 mi", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm BBBBB | 00:00:30", "12:00 at night", sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm BBBBB | 00:30:00", "12:30 at night", sdf.format(k003000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh BBBBB"));
+
+ // assertEquals("hh BBBBB | 00:00:00", "12 mi", sdf.format(k000000, out.remove()));
+ assertEquals("hh BBBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove()));
+ // assertEquals("hh BBBBB | 00:00:30", "12 mi", sdf.format(k000030, out.remove()));
+ assertEquals("hh BBBBB | 00:00:30", "12 at night", sdf.format(k000030, out.remove()));
+ // assertEquals("hh BBBBB | 00:30:00", "12 mi", sdf.format(k003000, out.remove()));
+ assertEquals("hh BBBBB | 00:30:00", "12 at night", sdf.format(k003000, out.remove()));
+}
+
+void DateFormatTest::TestDayPeriodWithLocales() {
+ // Some times on 2015-11-13 (UTC+0).
+ UDate k000000 = 1447372800000.0;
+ UDate k010000 = 1447376400000.0;
+ UDate k120000 = 1447416000000.0;
+ UDate k220000 = 1447452000000.0;
+
+ UErrorCode errorCode = U_ZERO_ERROR;
+ const TimeZone *tz = TimeZone::getGMT();
+ UnicodeString out;
+
+ // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
+ // For ICU 57 output of "midnight" and its localized equivalentns is temporarily suppressed.
+
+ // Locale de has a word for midnight, but not noon.
+ SimpleDateFormat sdf(UnicodeString(), Locale::getGermany(), errorCode);
+ if (U_FAILURE(errorCode)) {
+ dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
+ return;
+ }
+ sdf.setTimeZone(*tz);
+
+ sdf.applyPattern(UnicodeString("hh:mm:ss bbbb"));
+
+ // assertEquals("hh:mm:ss bbbb | 00:00:00 | de", "12:00:00 Mitternacht",
+ // sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss bbbb | 00:00:00 | de", "12:00:00 AM" /* change for Apple data */,
+ sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss bbbb | 12:00:00 | de", "12:00:00 PM" /* change for Apple data */,
+ sdf.format(k120000, out.remove()));
+
+ // Locale ee has a rule that wraps around midnight (21h - 4h).
+ sdf = SimpleDateFormat(UnicodeString(), Locale("ee"), errorCode);
+ sdf.setTimeZone(*tz);
+
+ sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
+
+ assertEquals("hh:mm:ss BBBB | 22:00:00 | ee", UnicodeString("10:00:00 z\\u00E3").unescape(),
+ sdf.format(k220000, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 00:00:00 | ee", UnicodeString("12:00:00 z\\u00E3").unescape(),
+ sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 01:00:00 | ee", UnicodeString("01:00:00 z\\u00E3").unescape(),
+ sdf.format(k010000, out.remove()));
+
+ // Locale root has rules for AM/PM only.
+ sdf = SimpleDateFormat(UnicodeString(), Locale("root"), errorCode);
+ sdf.setTimeZone(*tz);
+
+ sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
+
+ assertEquals("hh:mm:ss BBBB | 00:00:00 | root", "12:00:00 AM",
+ sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 12:00:00 | root", "12:00:00 PM",
+ sdf.format(k120000, out.remove()));
+
+ // Empty string should behave exactly as root.
+ sdf = SimpleDateFormat(UnicodeString(), Locale(""), errorCode);
+ sdf.setTimeZone(*tz);
+
+ sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
+
+ assertEquals("hh:mm:ss BBBB | 00:00:00 | \"\" (root)", "12:00:00 AM",
+ sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 12:00:00 | \"\" (root)", "12:00:00 PM",
+ sdf.format(k120000, out.remove()));
+
+ // Locale en_US should fall back to en.
+ sdf = SimpleDateFormat(UnicodeString(), Locale("en_US"), errorCode);
+ sdf.setTimeZone(*tz);
+
+ sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
+
+ // assertEquals("hh:mm:ss BBBB | 00:00:00 | en_US", "12:00:00 midnight",
+ // sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 00:00:00 | en_US", "12:00:00 at night",
+ sdf.format(k000000, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 01:00:00 | en_US", "01:00:00 at night",
+ sdf.format(k010000, out.remove()));
+ assertEquals("hh:mm:ss BBBB | 12:00:00 | en_US", "12:00:00 noon",
+ sdf.format(k120000, out.remove()));
+
+ // Locale es_CO should not fall back to es and should have a
+ // different string for 1 in the morning.
+ // (es_CO: "de la manana" (first n has a tilde) vs. es: "de la madrugada")
+ sdf = SimpleDateFormat(UnicodeString(), Locale("es_CO"), errorCode);
+ sdf.setTimeZone(*tz);
+
+ sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
+ assertEquals("hh:mm:ss BBBB | 01:00:00 | es_CO", UnicodeString("01:00:00 de la ma\\u00F1ana").unescape(),
+ sdf.format(k010000, out.remove()));
+
+ sdf = SimpleDateFormat(UnicodeString(), Locale("es"), errorCode);
+ sdf.setTimeZone(*tz);
+
+ sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
+ assertEquals("hh:mm:ss BBBB | 01:00:00 | es", "01:00:00 de la madrugada",
+ sdf.format(k010000, out.remove()));
+}
+
+void DateFormatTest::TestMinuteSecondFieldsInOddPlaces() {
+ // Some times on 2015-11-13 (UTC+0).
+ UDate k000000 = 1447372800000.0;
+ UDate k000030 = 1447372830000.0;
+ UDate k003000 = 1447374600000.0;
+ UDate k060030 = 1447394430000.0;
+ UDate k063000 = 1447396200000.0;
+
+ UErrorCode errorCode = U_ZERO_ERROR;
+ const TimeZone *tz = TimeZone::getGMT();
+ UnicodeString out;
+
+ // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
+ // For ICU 57 output of "midnight" is temporarily suppressed.
+
+ // Seconds field is not present.
+
+ // Apply pattern through constructor to make sure parsePattern() is called during initialization.
+ SimpleDateFormat sdf(UnicodeString("hh:mm 'ss' bbbb"), errorCode);
+ if (U_FAILURE(errorCode)) {
+ dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
+ return;
+ }
+ sdf.setTimeZone(*tz);
+
+ // assertEquals("hh:mm 'ss' bbbb | 00:00:30", "12:00 ss midnight",
+ // sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm 'ss' bbbb | 00:00:30", "12:00 ss AM",
+ sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm 'ss' bbbb | 06:00:30", "06:00 ss AM",
+ sdf.format(k060030, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh:mm 'ss' BBBB"));
+
+ // assertEquals("hh:mm 'ss' BBBB | 00:00:30", "12:00 ss midnight",
+ // sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm 'ss' BBBB | 00:00:30", "12:00 ss at night",
+ sdf.format(k000030, out.remove()));
+ assertEquals("hh:mm 'ss' BBBB | 06:00:30", "06:00 ss in the morning",
+ sdf.format(k060030, out.remove()));
+
+ // Minutes field is not present.
+ sdf.applyPattern(UnicodeString("hh 'mm ss' bbbb"));
+
+ // assertEquals("hh 'mm ss' bbbb | 00:30:00", "12 mm ss midnight",
+ // sdf.format(k003000, out.remove()));
+ assertEquals("hh 'mm ss' bbbb | 00:30:00", "12 mm ss AM",
+ sdf.format(k003000, out.remove()));
+ assertEquals("hh 'mm ss' bbbb | 06:30:00", "06 mm ss AM",
+ sdf.format(k063000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("hh 'mm ss' BBBB"));
+
+ // assertEquals("hh 'mm ss' BBBB | 00:30:00", "12 mm ss midnight",
+ // sdf.format(k003000, out.remove()));
+ assertEquals("hh 'mm ss' BBBB | 00:30:00", "12 mm ss at night",
+ sdf.format(k003000, out.remove()));
+ assertEquals("hh 'mm ss' BBBB | 06:30:00", "06 mm ss in the morning",
+ sdf.format(k063000, out.remove()));
+
+ // Minutes and seconds fields appear after day periods.
+ sdf.applyPattern(UnicodeString("bbbb hh:mm:ss"));
+
+ // assertEquals("bbbb hh:mm:ss | 00:00:00", "midnight 12:00:00",
+ // sdf.format(k000000, out.remove()));
+ assertEquals("bbbb hh:mm:ss | 00:00:00", "AM 12:00:00",
+ sdf.format(k000000, out.remove()));
+ assertEquals("bbbb hh:mm:ss | 00:00:30", "AM 12:00:30",
+ sdf.format(k000030, out.remove()));
+ assertEquals("bbbb hh:mm:ss | 00:30:00", "AM 12:30:00",
+ sdf.format(k003000, out.remove()));
+
+ sdf.applyPattern(UnicodeString("BBBB hh:mm:ss"));
+
+ // assertEquals("BBBB hh:mm:ss | 00:00:00", "midnight 12:00:00",
+ // sdf.format(k000000, out.remove()));
+ assertEquals("BBBB hh:mm:ss | 00:00:00", "at night 12:00:00",
+ sdf.format(k000000, out.remove()));
+ assertEquals("BBBB hh:mm:ss | 00:00:30", "at night 12:00:30",
+ sdf.format(k000030, out.remove()));
+ assertEquals("BBBB hh:mm:ss | 00:30:00", "at night 12:30:00",
+ sdf.format(k003000, out.remove()));
+
+ // Confirm applyPattern() reparses the pattern string.
+ sdf.applyPattern(UnicodeString("BBBB hh"));
+ // assertEquals("BBBB hh | 00:00:30", "midnight 12",
+ // sdf.format(k000030, out.remove()));
+ assertEquals("BBBB hh | 00:00:30", "at night 12",
+ sdf.format(k000030, out.remove()));
+
+ sdf.applyPattern(UnicodeString("BBBB hh:mm:'ss'"));
+ // assertEquals("BBBB hh:mm:'ss' | 00:00:30", "midnight 12:00:ss",
+ // sdf.format(k000030, out.remove()));
+ assertEquals("BBBB hh | 00:00:30", "at night 12:00:ss",
+ sdf.format(k000030, out.remove()));
+
+ sdf.applyPattern(UnicodeString("BBBB hh:mm:ss"));
+ assertEquals("BBBB hh:mm:ss | 00:00:30", "at night 12:00:30",
+ sdf.format(k000030, out.remove()));
+}
+
+void DateFormatTest::TestDayPeriodParsing() {
+ // Some times on 2015-11-13 (UTC+0).
+ UDate k000000 = 1447372800000.0;
+ UDate k003700 = 1447375020000.0;
+ UDate k010000 = 1447376400000.0;
+ UDate k013000 = 1447378200000.0;
+ UDate k030000 = 1447383600000.0;
+ UDate k090000 = 1447405200000.0;
+ UDate k120000 = 1447416000000.0;
+ UDate k130000 = 1447419600000.0;
+ UDate k133700 = 1447421820000.0;
+ UDate k150000 = 1447426800000.0;
+ UDate k190000 = 1447441200000.0;
+ UDate k193000 = 1447443000000.0;
+ UDate k200000 = 1447444800000.0;
+ UDate k210000 = 1447448400000.0;
+
+ UErrorCode errorCode = U_ZERO_ERROR;
+ SimpleDateFormat sdf(UnicodeString(), errorCode);
+ if (U_FAILURE(errorCode)) {
+ dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
+ return;
+ }
+ const TimeZone *tz = TimeZone::getGMT();
+ sdf.setTimeZone(*tz);
+ UnicodeString out;
+
+ // 'B' -- flexible day periods
+ // A day period on its own parses to the center of that period.
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd B"));
+ assertEquals("yyyy-MM-dd B | 2015-11-13 midnight",
+ k000000, sdf.parse(UnicodeString("2015-11-13 midnight"), errorCode));
+ assertEquals("yyyy-MM-dd B | 2015-11-13 noon",
+ k120000, sdf.parse(UnicodeString("2015-11-13 noon"), errorCode));
+ assertEquals("yyyy-MM-dd B | 2015-11-13 in the afternoon",
+ k150000, sdf.parse(UnicodeString("2015-11-13 in the afternoon"), errorCode));
+ assertEquals("yyyy-MM-dd B | 2015-11-13 in the evening",
+ k193000, sdf.parse(UnicodeString("2015-11-13 in the evening"), errorCode));
+ assertEquals("yyyy-MM-dd B | 2015-11-13 at night",
+ k013000, sdf.parse(UnicodeString("2015-11-13 at night"), errorCode));
+
+ // If time and day period are consistent with each other then time is parsed accordingly.
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm B"));
+ assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 12:00 midnight",
+ k000000, sdf.parse(UnicodeString("2015-11-13 12:00 midnight"), errorCode));
+ assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 12:00 noon",
+ k120000, sdf.parse(UnicodeString("2015-11-13 12:00 noon"), errorCode));
+ assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 01:00 at night",
+ k010000, sdf.parse(UnicodeString("2015-11-13 01:00 at night"), errorCode));
+ assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 01:00 in the afternoon",
+ k130000, sdf.parse(UnicodeString("2015-11-13 01:00 in the afternoon"), errorCode));
+ assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 09:00 in the morning",
+ k090000, sdf.parse(UnicodeString("2015-11-13 09:00 in the morning"), errorCode));
+ assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 09:00 at night",
+ k210000, sdf.parse(UnicodeString("2015-11-13 09:00 at night"), errorCode));
+
+ // If the hour is 13 thru 23 then day period has no effect on time (since time is assumed
+ // to be in 24-hour format).
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm B"));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 midnight",
+ k133700, sdf.parse(UnicodeString("2015-11-13 13:37 midnight"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 noon",
+ k133700, sdf.parse(UnicodeString("2015-11-13 13:37 noon"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 at night",
+ k133700, sdf.parse(UnicodeString("2015-11-13 13:37 at night"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 in the afternoon",
+ k133700, sdf.parse(UnicodeString("2015-11-13 13:37 in the afternoon"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 in the morning",
+ k133700, sdf.parse(UnicodeString("2015-11-13 13:37 in the morning"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 at night",
+ k133700, sdf.parse(UnicodeString("2015-11-13 13:37 at night"), errorCode));
+
+ // Hour 0 is synonymous with hour 12 when parsed with 'h'.
+ // This unfortunately means we have to tolerate "0 noon" as it's synonymous with "12 noon".
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm B"));
+ assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 00:00 midnight",
+ k000000, sdf.parse(UnicodeString("2015-11-13 00:00 midnight"), errorCode));
+ assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 00:00 noon",
+ k120000, sdf.parse(UnicodeString("2015-11-13 00:00 noon"), errorCode));
+
+ // But when parsed with 'H', 0 indicates a 24-hour time, therefore we disregard the day period.
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm B"));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 midnight",
+ k003700, sdf.parse(UnicodeString("2015-11-13 00:37 midnight"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 noon",
+ k003700, sdf.parse(UnicodeString("2015-11-13 00:37 noon"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 at night",
+ k003700, sdf.parse(UnicodeString("2015-11-13 00:37 at night"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 in the afternoon",
+ k003700, sdf.parse(UnicodeString("2015-11-13 00:37 in the afternoon"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 in the morning",
+ k003700, sdf.parse(UnicodeString("2015-11-13 00:37 in the morning"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 at night",
+ k003700, sdf.parse(UnicodeString("2015-11-13 00:37 at night"), errorCode));
+
+ // Even when parsed with 'H', hours 1 thru 12 are considered 12-hour time and takes
+ // day period into account in parsing.
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm B"));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 12:00 midnight",
+ k000000, sdf.parse(UnicodeString("2015-11-13 12:00 midnight"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 12:00 noon",
+ k120000, sdf.parse(UnicodeString("2015-11-13 12:00 noon"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 01:00 at night",
+ k010000, sdf.parse(UnicodeString("2015-11-13 01:00 at night"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 01:00 in the afternoon",
+ k130000, sdf.parse(UnicodeString("2015-11-13 01:00 in the afternoon"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 09:00 in the morning",
+ k090000, sdf.parse(UnicodeString("2015-11-13 09:00 in the morning"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 09:00 at night",
+ k210000, sdf.parse(UnicodeString("2015-11-13 09:00 at night"), errorCode));
+
+ // If a 12-hour time and the day period don't agree with each other, time is parsed as close
+ // to the given day period as possible.
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm B"));
+
+ // AFTERNOON1 is [12, 18), but "7 in the afternoon" parses to 19:00.
+ assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 07:00 in the afternoon",
+ k190000, sdf.parse(UnicodeString("2015-11-13 07:00 in the afternoon"), errorCode));
+ // NIGHT1 is [21, 6), but "8 at night" parses to 20:00.
+ assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 08:00 at night",
+ k200000, sdf.parse(UnicodeString("2015-11-13 08:00 at night"), errorCode));
+
+ // 'b' -- fixed day periods (AM, PM, midnight, noon)
+ // On their own, "midnight" parses to 00:00 and "noon" parses to 12:00.
+ // AM and PM are handled by the 'a' parser (which doesn't handle this case well).
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd b"));
+ assertEquals("yyyy-MM-dd b | 2015-11-13 midnight",
+ k000000, sdf.parse(UnicodeString("2015-11-13 midnight"), errorCode));
+ assertEquals("yyyy-MM-dd b | 2015-11-13 noon",
+ k120000, sdf.parse(UnicodeString("2015-11-13 noon"), errorCode));
+
+ // For 12-hour times, AM and PM should be parsed as if with pattern character 'a'.
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm b"));
+ assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 01:00 AM",
+ k010000, sdf.parse(UnicodeString("2015-11-13 01:00 AM"), errorCode));
+ assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 01:00 PM",
+ k130000, sdf.parse(UnicodeString("2015-11-13 01:00 PM"), errorCode));
+
+ // 12 midnight parses to 00:00, and 12 noon parses to 12:00.
+ assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 12:00 midnight",
+ k000000, sdf.parse(UnicodeString("2015-11-13 12:00 midnight"), errorCode));
+ assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 12:00 noon",
+ k120000, sdf.parse(UnicodeString("2015-11-13 12:00 noon"), errorCode));
+
+ // Hours 13-23 indicate 24-hour time so we disregard "midnight" or "noon".
+ // Again, AM and PM are handled by the 'a' parser which doesn't handle this case well.
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm b"));
+ assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 13:37 midnight",
+ k133700, sdf.parse(UnicodeString("2015-11-13 13:37 midnight"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 13:37 noon",
+ k133700, sdf.parse(UnicodeString("2015-11-13 13:37 noon"), errorCode));
+
+ // Hour 0 is synonymous with hour 12 when parsed with 'h'.
+ // Again, this means we have to tolerate "0 noon" as it's synonymous with "12 noon".
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm b"));
+ assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 00:00 midnight",
+ k000000, sdf.parse(UnicodeString("2015-11-13 00:00 midnight"), errorCode));
+ assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 00:00 noon",
+ k120000, sdf.parse(UnicodeString("2015-11-13 00:00 noon"), errorCode));
+
+ // With 'H' though 0 indicates a 24-hour time, therefore we disregard the day period.
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm b"));
+ assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 00:37 midnight",
+ k003700, sdf.parse(UnicodeString("2015-11-13 00:37 midnight"), errorCode));
+ assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 00:37 noon",
+ k003700, sdf.parse(UnicodeString("2015-11-13 00:37 noon"), errorCode));
+
+ // If "midnight" or "noon" is parsed with a 12-hour time other than 12:00, choose
+ // the version that's closer to the period given.
+ sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm b"));
+ assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 03:00 midnight",
+ k030000, sdf.parse(UnicodeString("2015-11-13 03:00 midnight"), errorCode));
+ assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 03:00 noon",
+ k150000, sdf.parse(UnicodeString("2015-11-13 03:00 noon"), errorCode));
+}
#endif /* #if !UCONFIG_NO_FORMATTING */