X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/efa1e6592fb03ce23b15276b2b91d885a3ee7da5..2ca993e82fb37b597a3c73ecd1586a139a6579c5:/icuSources/test/intltest/dtfmttst.cpp diff --git a/icuSources/test/intltest/dtfmttst.cpp b/icuSources/test/intltest/dtfmttst.cpp index 773cd9eb..d3e697bf 100644 --- a/icuSources/test/intltest/dtfmttst.cpp +++ b/icuSources/test/intltest/dtfmttst.cpp @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 1997-2013, International Business Machines + * Copyright (c) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************/ @@ -27,10 +27,6 @@ #include "windttst.h" #endif -#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) - -#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; } // ***************************************************************************** @@ -60,6 +56,7 @@ void DateFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &nam TESTCASE_AUTO(TestDateFormatZone061); TESTCASE_AUTO(TestDateFormatZone146); TESTCASE_AUTO(TestLocaleDateFormat); + TESTCASE_AUTO(TestFormattingLocaleTimeSeparator); TESTCASE_AUTO(TestWallyWedel); TESTCASE_AUTO(TestDateFormatCalendar); TESTCASE_AUTO(TestSpaceParsing); @@ -81,6 +78,8 @@ void DateFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &nam TESTCASE_AUTO(TestRelative); TESTCASE_AUTO(TestRelativeClone); TESTCASE_AUTO(TestHostClone); + TESTCASE_AUTO(TestHebrewClone); + TESTCASE_AUTO(TestDateFormatSymbolsClone); TESTCASE_AUTO(TestTimeZoneDisplayName); TESTCASE_AUTO(TestRoundtripWithCalendar); TESTCASE_AUTO(Test6338); @@ -95,11 +94,32 @@ void DateFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &nam TESTCASE_AUTO(TestMonthPatterns); TESTCASE_AUTO(TestContext); TESTCASE_AUTO(TestNonGregoFmtParse); + TESTCASE_AUTO(TestFormatsWithNumberSystems); /* TESTCASE_AUTO(TestRelativeError); TESTCASE_AUTO(TestRelativeOther); */ TESTCASE_AUTO(TestDotAndAtLeniency); + TESTCASE_AUTO(TestDateFormatLeniency); + TESTCASE_AUTO(TestParseMultiPatternMatch); + + TESTCASE_AUTO(TestParseLeniencyAPIs); + TESTCASE_AUTO(TestNumberFormatOverride); + TESTCASE_AUTO(TestCreateInstanceForSkeleton); + TESTCASE_AUTO(TestCreateInstanceForSkeletonDefault); + TESTCASE_AUTO(TestCreateInstanceForSkeletonWithCalendar); + TESTCASE_AUTO(TestDFSCreateForLocaleNonGregorianLocale); + 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; } @@ -114,21 +134,21 @@ void DateFormatTest::TestPatterns() { {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"}, @@ -163,21 +183,21 @@ void DateFormatTest::TestPatterns() { }; IcuTestErrorCode errorCode(*this, "TestPatterns()"); - for (int32_t i = 0; i < LENGTHOF(EXPECTED); i++) { + for (int32_t i = 0; i < UPRV_LENGTHOF(EXPECTED); i++) { // Verify that patterns have the correct values UnicodeString actualPattern(EXPECTED[i].actualPattern, -1, US_INV); 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); @@ -202,11 +222,11 @@ void DateFormatTest::TestPatterns() { 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); } } @@ -420,7 +440,11 @@ DateFormatTest::escape(UnicodeString& s) /** * This MUST be kept in sync with DateFormatSymbols.gPatternChars. */ -static const char* PATTERN_CHARS = "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXx"; +#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. @@ -461,10 +485,14 @@ static const char* DATEFORMAT_FIELD_NAMES[] = { "TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD", "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. @@ -486,7 +514,11 @@ void DateFormatTest::TestFieldPosition() { 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; @@ -515,26 +547,44 @@ void DateFormatTest::TestFieldPosition() { 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 avanc\\u00e9e du Pacifique", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", + "", "", "", "", "", "", "", "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", "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", "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); @@ -610,7 +660,7 @@ void DateFormatTest::TestGeneral() { "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", "", "")); } // ------------------------------------- @@ -927,11 +977,11 @@ DateFormatTest::TestBadInput135() 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"); @@ -1029,7 +1079,7 @@ static const char* const inputStrings[] = { "3:00 pm Jan 1, 1997", 0, 0, 0, 0, 0, 0, 0, "0003", "3:00 PM January 1, 1997", }; #endif - + // ------------------------------------- /** @@ -1049,8 +1099,8 @@ DateFormatTest::TestBadInput135a() } 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()); @@ -1234,7 +1284,7 @@ DateFormatTest::TestDateFormatZone146() 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 tz(TimeZone::createTimeZone("CET")); + + const LocalPointer dfArab(DateFormat::createTimeInstance( + DateFormat::SHORT, Locale("ar"))); + + const LocalPointer dfLatn(DateFormat::createTimeInstance( + DateFormat::SHORT, Locale("ar", NULL, NULL, "numbers=latn"))); + + if (dfLatn.isNull() || dfArab.isNull()) { + dataerrln("Error calling DateFormat::createTimeInstance()"); + return; + } + + dfArab->setTimeZone(*tz); + dfLatn->setTimeZone(*tz); + + const UnicodeString expectedArab = UnicodeString( + "\\u0669:\\u0665\\u0662 \\u0645", -1, US_INV).unescape(); + + const UnicodeString expectedLatn = UnicodeString( + "9:52 \\u0645", -1, US_INV).unescape(); + + UnicodeString actualArab; + UnicodeString actualLatn; + + dfArab->format(testDate, actualArab); + dfLatn->format(testDate, actualLatn); + + assertEquals("Arab", expectedArab, actualArab); + assertEquals("Latn", expectedLatn, actualLatn); +} + /** * Test DateFormat(Calendar) API */ @@ -1412,20 +1502,19 @@ void DateFormatTest::TestSpaceParsing() { "hh:mm:ss a", "12:34:56 PM", "1970 01 01 12:34:56", 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", 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")); } @@ -1446,7 +1535,7 @@ void DateFormatTest::TestExactCountFormat() { 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")); } @@ -1464,7 +1553,7 @@ void DateFormatTest::TestWhiteSpaceParsing() { "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")); } @@ -1577,8 +1666,8 @@ void DateFormatTest::TestStandAloneMonths() "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() @@ -1623,8 +1712,8 @@ 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() @@ -1641,14 +1730,14 @@ void DateFormatTest::TestShortDays() const char *SV_DATA[] = { "yyyy MM dd HH:mm:ss", - "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 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() @@ -1700,12 +1789,17 @@ 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", + "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 p", }; const char *CS_DATA[] = { "yyyy MM dd HH:mm:ss", - "yyyy LLLLL dd H:mm:ss", "2004 04 10 16:36:31", "2004 d 10 16:36:31", + "yyyy LLLLL dd H:mm:ss", "2004 04 10 16:36:31", "2004 4 10 16:36:31", "yyyy MMMMM dd H:mm:ss", "2004 04 10 16:36:31", "2004 4 10 16:36:31", "MMMMM", "1970 01 01 0:00:00", "1", @@ -1721,18 +1815,18 @@ void DateFormatTest::TestNarrowNames() "MMMMM", "1970 11 01 0:00:00", "11", "MMMMM", "1970 12 01 0:00:00", "12", - "LLLLL", "1970 01 01 0:00:00", "l", - "LLLLL", "1970 02 01 0:00:00", "\\u00FA", - "LLLLL", "1970 03 01 0:00:00", "b", - "LLLLL", "1970 04 01 0:00:00", "d", - "LLLLL", "1970 05 01 0:00:00", "k", - "LLLLL", "1970 06 01 0:00:00", "\\u010D", - "LLLLL", "1970 07 01 0:00:00", "\\u010D", - "LLLLL", "1970 08 01 0:00:00", "s", - "LLLLL", "1970 09 01 0:00:00", "z", - "LLLLL", "1970 10 01 0:00:00", "\\u0159", - "LLLLL", "1970 11 01 0:00:00", "l", - "LLLLL", "1970 12 01 0:00:00", "p", + "LLLLL", "1970 01 01 0:00:00", "1", + "LLLLL", "1970 02 01 0:00:00", "2", + "LLLLL", "1970 03 01 0:00:00", "3", + "LLLLL", "1970 04 01 0:00:00", "4", + "LLLLL", "1970 05 01 0:00:00", "5", + "LLLLL", "1970 06 01 0:00:00", "6", + "LLLLL", "1970 07 01 0:00:00", "7", + "LLLLL", "1970 08 01 0:00:00", "8", + "LLLLL", "1970 09 01 0:00:00", "9", + "LLLLL", "1970 10 01 0:00:00", "10", + "LLLLL", "1970 11 01 0:00:00", "11", + "LLLLL", "1970 12 01 0:00:00", "12", "EEEEE", "1970 01 04 0:00:00", "N", "EEEEE", "1970 01 05 0:00:00", "P", @@ -1749,10 +1843,25 @@ void DateFormatTest::TestNarrowNames() "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 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.", }; - expectFormat(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", "")); - expectFormat(CS_DATA, ARRAY_SIZE(CS_DATA), Locale("cs", "", "")); + const char *CA_DATA[] = { + "yyyy MM dd HH:mm:ss", + + "h:mm a", "2015 01 01 10:00:00", "10:00 a. m.", + "h:mm a", "2015 01 01 22:00:00", "10:00 p. m.", + "h:mm aaaaa", "2015 01 01 10:00:00", "10:00 a.m.", + "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 p.m.", + }; + + 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() @@ -1771,7 +1880,7 @@ 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() @@ -1788,9 +1897,12 @@ 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", "", "")); } /** @@ -2104,7 +2216,7 @@ void DateFormatTest::TestGenericTime() { "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; @@ -2121,7 +2233,7 @@ void DateFormatTest::TestGenericTime() { 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); @@ -2130,7 +2242,7 @@ void DateFormatTest::TestGenericTime() { "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); @@ -2208,7 +2320,7 @@ void DateFormatTest::TestGenericTimeZoneOrder() { "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); } @@ -2236,13 +2348,13 @@ void DateFormatTest::TestZTimeZoneParsing(void) { }; 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(); @@ -2365,9 +2477,9 @@ void DateFormatTest::TestRelative(int daysdelta, void DateFormatTest::TestRelative(void) { Locale en("en"); - TestRelative( 0, en, "Today"); - TestRelative(-1, en, "Yesterday"); - TestRelative( 1, en, "Tomorrow"); + TestRelative( 0, en, "today"); + TestRelative(-1, en, "yesterday"); + TestRelative( 1, en, "tomorrow"); TestRelative( 2, en, NULL); TestRelative( -2, en, NULL); TestRelative( 3, en, NULL); @@ -2417,7 +2529,7 @@ void DateFormatTest::TestHostClone(void) UDate now = Calendar::getNow(); DateFormat *full = DateFormat::createDateInstance(DateFormat::kFull, loc); if (full == NULL) { - dataerrln("FAIL: Can't create Relative date instance"); + dataerrln("FAIL: Can't create host date instance"); return; } UnicodeString result1; @@ -2435,6 +2547,82 @@ void DateFormatTest::TestHostClone(void) delete fullClone; } +void DateFormatTest::TestHebrewClone(void) +{ + /* + Verify that a cloned formatter gives the same results + and is useable after the original has been deleted. + */ + UErrorCode status = U_ZERO_ERROR; + Locale loc("he@calendar=hebrew"); + UDate now = Calendar::getNow(); + LocalPointer fmt( + DateFormat::createDateInstance(DateFormat::kLong, loc)); + if (fmt.isNull()) { + dataerrln("FAIL: Can't create Hebrew date instance"); + return; + } + UnicodeString result1; + fmt->format(now, result1, status); + LocalPointer fmtClone(fmt->clone()); + + // free fmt to be sure that fmtClone is independent of fmt. + fmt.adoptInstead(NULL); + + UnicodeString result2; + fmtClone->format(now, result2, status); + ASSERT_OK(status); + if (result1 != result2) { + errln("FAIL: Clone returned different result from non-clone."); + } +} + +static UBool getActualAndValidLocales( + const Format &fmt, Locale &valid, Locale &actual) { + const SimpleDateFormat* dat = dynamic_cast(&fmt); + if (dat == NULL) { + return FALSE; + } + const DateFormatSymbols *sym = dat->getDateFormatSymbols(); + if (sym == NULL) { + return FALSE; + } + UErrorCode status = U_ZERO_ERROR; + valid = sym->getLocale(ULOC_VALID_LOCALE, status); + actual = sym->getLocale(ULOC_ACTUAL_LOCALE, status); + return U_SUCCESS(status); +} + +void DateFormatTest::TestDateFormatSymbolsClone(void) +{ + /* + Verify that a cloned formatter gives the same results + and is useable after the original has been deleted. + */ + Locale loc("de_CH_LUCERNE"); + LocalPointer fmt( + DateFormat::createDateInstance(DateFormat::kDefault, loc)); + Locale valid1; + Locale actual1; + if (!getActualAndValidLocales(*fmt, valid1, actual1)) { + dataerrln("FAIL: Could not fetch valid + actual locales"); + return; + } + LocalPointer fmtClone(fmt->clone()); + + // Free fmt to be sure that fmtClone is really independent of fmt. + fmt.adoptInstead(NULL); + Locale valid2; + Locale actual2; + if (!getActualAndValidLocales(*fmtClone, valid2, actual2)) { + errln("FAIL: Could not fetch valid + actual locales"); + return; + } + if (valid1 != valid2 || actual1 != actual2) { + errln("Date format symbol locales of clone don't match original"); + } +} + void DateFormatTest::TestTimeZoneDisplayName() { // This test data was ported from ICU4J. Don't know why the 6th column in there because it's not being @@ -2673,11 +2861,11 @@ void DateFormatTest::TestTimeZoneDisplayName() // ========== { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, - { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-0800", "-8:00" }, + { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" }, { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "America/Los_Angeles" }, { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u6807\\u51c6\\u65f6\\u95f4", "America/Los_Angeles" }, { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" }, - { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-0700", "-7:00" }, + { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" }, { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "America/Los_Angeles" }, { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u590f\\u4ee4\\u65f6\\u95f4", "America/Los_Angeles" }, // icu zh.txt has exemplar city for this time zone @@ -2685,44 +2873,44 @@ void DateFormatTest::TestTimeZoneDisplayName() { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u65f6\\u95f4", "America/Los_Angeles" }, { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-0300", "-3:00" }, + { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" }, { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-0300", "-3:00" }, + { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" }, { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u5E03\\u5B9C\\u8BFA\\u65AF\\u827E\\u5229\\u65AF\\u65F6\\u95F4", "America/Buenos_Aires" }, { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "America/Buenos_Aires" }, { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-0300", "-3:00" }, + { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" }, { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-0300", "-3:00" }, + { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" }, { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u5E03\\u5B9C\\u8BFA\\u65AF\\u827E\\u5229\\u65AF\\u65F6\\u95F4", "America/Buenos_Aires" }, { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "America/Buenos_Aires" }, { "zh", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" }, - { "zh", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-0500", "-5:00" }, + { "zh", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" }, { "zh", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" }, { "zh", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u53e4\\u5df4\\u6807\\u51c6\\u65f6\\u95f4", "-5:00" }, { "zh", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" }, - { "zh", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-0400", "-4:00" }, + { "zh", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" }, { "zh", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" }, { "zh", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u53e4\\u5df4\\u590f\\u4ee4\\u65f6\\u95f4", "-4:00" }, { "zh", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u53e4\\u5df4\\u65f6\\u95f4", "America/Havana" }, { "zh", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u53e4\\u5df4\\u65f6\\u95f4", "America/Havana" }, { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, - { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+1100", "+11:00" }, + { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u590f\\u4ee4\\u65f6\\u95f4", "+11:00" }, { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, - { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+1000", "+10:00" }, + { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u6807\\u51c6\\u65f6\\u95f4", "+10:00" }, // icu zh.txt does not have info for this time zone @@ -2730,11 +2918,11 @@ void DateFormatTest::TestTimeZoneDisplayName() { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u65f6\\u95f4", "Australia/Sydney" }, { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, - { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+1100", "+11:00" }, + { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u590f\\u4ee4\\u65f6\\u95f4", "+11:00" }, { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, - { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+1000", "+10:00" }, + { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u6807\\u51c6\\u65f6\\u95f4", "+10:00" }, { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u6089\\u5C3C\\u65F6\\u95F4", "Australia/Sydney" }, @@ -2747,7 +2935,7 @@ void DateFormatTest::TestTimeZoneDisplayName() { "zh", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" }, { "zh", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u683C\\u6797\\u5C3C\\u6CBB\\u6807\\u51C6\\u65F6\\u95F4", "+0:00" }, { "zh", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" }, - { "zh", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+0100", "+1:00" }, + { "zh", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" }, { "zh", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" }, { "zh", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u82f1\\u56fd\\u590f\\u4ee4\\u65f6\\u95f4", "+1:00" }, { "zh", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" }, @@ -2755,24 +2943,24 @@ void DateFormatTest::TestTimeZoneDisplayName() { "zh", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" }, { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-0300", "-3:00" }, + { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, - { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-0300", "-3:00" }, + { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-0300", "-3:00" }, + { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, - { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-0300", "-3:00" }, + { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" }, - { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-0300", "-3:00" }, + { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" }, // JB#5150 { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" }, - { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+0530", "+5:30" }, - { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+530", "+5:30" }, + { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, + { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" }, { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u5370\\u5ea6\\u65f6\\u95f4", "+5:30" }, { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" }, - { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+0530", "+5:30" }, - { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+530", "+05:30" }, + { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, + { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" }, { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u5370\\u5ea6\\u65f6\\u95f4", "+5:30" }, { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u5370\\u5ea6\\u65f6\\u95f4", "Asia/Calcutta" }, { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u5370\\u5ea6\\u65f6\\u95f4", "Asia/Calcutta" }, @@ -2780,208 +2968,208 @@ void DateFormatTest::TestTimeZoneDisplayName() // ========== { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, - { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" }, - { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "-8:00" }, - { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u092a\\u094d\\u0930\\u0936\\u093e\\u0902\\u0924\\u0020\\u092e\\u093e\\u0928\\u0915\\u0020\\u0938\\u092e\\u092f", "-8:00" }, + { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-\\u0966\\u096E:\\u0966\\u0966", "-8:00" }, + { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-\\u096E", "-8:00" }, + { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u0909\\u0924\\u094d\\u0924\\u0930\\u0940 \\u0905\\u092e\\u0947\\u0930\\u093f\\u0915\\u0940 \\u092a\\u094d\\u0930\\u0936\\u093e\\u0902\\u0924 \\u092e\\u093e\\u0928\\u0915 \\u0938\\u092e\\u092f", "-8:00" }, { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" }, - { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" }, - { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "-7:00" }, - { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u092A\\u094D\\u0930\\u0936\\u093E\\u0902\\u0924 \\u0926\\u093F\\u0935\\u093E\\u0935\\u0932\\u094B\\u0915 \\u0938\\u092E\\u092F", "-7:00" }, - { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u0932\\u094B\\u0938 \\u090F\\u0902\\u091C\\u093F\\u0932\\u0947\\u0938 \\u0938\\u092E\\u092F", "America/Los_Angeles" }, - { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u092A\\u094D\\u0930\\u0936\\u093E\\u0902\\u0924 \\u0938\\u092E\\u092F", "America/Los_Angeles" }, + { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-\\u0966\\u096D:\\u0966\\u0966", "-7:00" }, + { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-\\u096D", "-7:00" }, + { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u0909\\u0924\\u094d\\u0924\\u0930\\u0940 \\u0905\\u092e\\u0947\\u0930\\u093f\\u0915\\u0940 \\u092a\\u094d\\u0930\\u0936\\u093e\\u0902\\u0924 \\u0921\\u0947\\u0932\\u093e\\u0907\\u091f \\u0938\\u092e\\u092f", "-7:00" }, + { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u0932\\u0949\\u0938 \\u090f\\u0902\\u091c\\u093f\\u0932\\u094d\\u0938 \\u0938\\u092e\\u092f", "America/Los_Angeles" }, + { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u0909\\u0924\\u094d\\u0924\\u0930\\u0940 \\u0905\\u092e\\u0947\\u0930\\u093f\\u0915\\u0940 \\u092a\\u094d\\u0930\\u0936\\u093e\\u0902\\u0924 \\u0938\\u092e\\u092f", "America/Los_Angeles" }, { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, - { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, + { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-\\u0966\\u0969:\\u0966\\u0966", "-3:00" }, + { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-\\u0969", "-3:00" }, { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u0905\\u0930\\u094D\\u091C\\u0947\\u0902\\u091F\\u0940\\u0928\\u093E \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "-3:00" }, { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, - { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, + { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-\\u0966\\u0969:\\u0966\\u0966", "-3:00" }, + { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-\\u0969", "-3:00" }, { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u0905\\u0930\\u094D\\u091C\\u0947\\u0902\\u091F\\u0940\\u0928\\u093E \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "-3:00" }, { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u092C\\u094D\\u092F\\u0942\\u0928\\u0938 \\u0906\\u092F\\u0930\\u0938 \\u0938\\u092E\\u092F", "America/Buenos_Aires" }, { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u0905\\u0930\\u094D\\u091C\\u0947\\u0902\\u091F\\u0940\\u0928\\u093E \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "America/Buenos_Aires" }, { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, - { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, + { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-\\u0966\\u0969:\\u0966\\u0966", "-3:00" }, + { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-\\u0969", "-3:00" }, { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u0905\\u0930\\u094D\\u091C\\u0947\\u0902\\u091F\\u0940\\u0928\\u093E \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "-3:00" }, { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, - { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, + { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-\\u0966\\u0969:\\u0966\\u0966", "-3:00" }, + { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-\\u0969", "-3:00" }, { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u0905\\u0930\\u094D\\u091C\\u0947\\u0902\\u091F\\u0940\\u0928\\u093E \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "-3:00" }, { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u092C\\u094D\\u092F\\u0942\\u0928\\u0938 \\u0906\\u092F\\u0930\\u0938 \\u0938\\u092E\\u092F", "America/Buenos_Aires" }, { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u0905\\u0930\\u094D\\u091C\\u0947\\u0902\\u091F\\u0940\\u0928\\u093E \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "America/Buenos_Aires" }, { "hi", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" }, - { "hi", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" }, - { "hi", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" }, - { "hi", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0915\\u093e \\u092e\\u093e\\u0928\\u0915 \\u0938\\u092e\\u092f", "-5:00" }, + { "hi", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-\\u0966\\u096B:\\u0966\\u0966", "-5:00" }, + { "hi", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-\\u096B", "-5:00" }, + { "hi", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u092e\\u093e\\u0928\\u0915 \\u0938\\u092e\\u092f", "-5:00" }, { "hi", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" }, - { "hi", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" }, - { "hi", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" }, - { "hi", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0915\\u093e \\u0921\\u0947\\u0932\\u093e\\u0907\\u091f \\u091f\\u093e\\u0907\\u092e", "-4:00" }, + { "hi", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-\\u0966\\u096A:\\u0966\\u0966", "-4:00" }, + { "hi", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-\\u096A", "-4:00" }, + { "hi", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0921\\u0947\\u0932\\u093e\\u0907\\u091f \\u0938\\u092e\\u092f", "-4:00" }, { "hi", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0938\\u092E\\u092F", "America/Havana" }, - { "hi", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0915\\u093e \\u0938\\u092E\\u092F", "America/Havana" }, + { "hi", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0938\\u092e\\u092f", "America/Havana" }, { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, - { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, - { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, - { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094D\\u200D\\u091F\\u094D\\u0930\\u0947\\u0932\\u093F\\u092F\\u093E\\u0908 \\u092A\\u0942\\u0930\\u094D\\u0935\\u0940 \\u0926\\u093F\\u0935\\u093E\\u0935\\u0932\\u094B\\u0915 \\u0938\\u092E\\u092F", "+11:00" }, + { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+\\u0967\\u0967:\\u0966\\u0966", "+11:00" }, + { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+\\u0967\\u0967", "+11:00" }, + { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094d\\u200d\\u091f\\u094d\\u0930\\u0947\\u0932\\u093f\\u092f\\u093e\\u0908 \\u092a\\u0942\\u0930\\u094d\\u0935\\u0940 \\u0921\\u0947\\u0932\\u093e\\u0907\\u091f \\u0938\\u092e\\u092f", "+11:00" }, { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, - { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, - { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, - { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094D\\u200D\\u091F\\u094D\\u0930\\u0947\\u0932\\u093F\\u092F\\u093E\\u0908 \\u092A\\u0942\\u0930\\u094D\\u0935\\u0940 \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "+10:00" }, + { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+\\u0967\\u0966:\\u0966\\u0966", "+10:00" }, + { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+\\u0967\\u0966", "+10:00" }, + { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094d\\u200d\\u091f\\u094d\\u0930\\u0947\\u0932\\u093f\\u092f\\u093e\\u0908 \\u092a\\u0942\\u0930\\u094d\\u0935\\u0940 \\u092e\\u093e\\u0928\\u0915 \\u0938\\u092e\\u092f", "+10:00" }, { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u0938\\u093F\\u0921\\u0928\\u0940 \\u0938\\u092E\\u092F", "Australia/Sydney" }, - { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u092A\\u0942\\u0930\\u094D\\u0935\\u0940 \\u0911\\u0938\\u094D\\u091F\\u094D\\u0930\\u0947\\u0932\\u093F\\u092F\\u093E\\u0908 \\u0938\\u092E\\u092F", "Australia/Sydney" }, + { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u092a\\u0942\\u0930\\u094d\\u0935\\u0940 \\u0911\\u0938\\u094d\\u091f\\u094d\\u0930\\u0947\\u0932\\u093f\\u092f\\u093e \\u0938\\u092e\\u092f", "Australia/Sydney" }, { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, - { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, - { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, - { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094D\\u200D\\u091F\\u094D\\u0930\\u0947\\u0932\\u093F\\u092F\\u093E\\u0908 \\u092A\\u0942\\u0930\\u094D\\u0935\\u0940 \\u0926\\u093F\\u0935\\u093E\\u0935\\u0932\\u094B\\u0915 \\u0938\\u092E\\u092F", "+11:00" }, + { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+\\u0967\\u0967:\\u0966\\u0966", "+11:00" }, + { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+\\u0967\\u0967", "+11:00" }, + { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094d\\u200d\\u091f\\u094d\\u0930\\u0947\\u0932\\u093f\\u092f\\u093e\\u0908 \\u092a\\u0942\\u0930\\u094d\\u0935\\u0940 \\u0921\\u0947\\u0932\\u093e\\u0907\\u091f \\u0938\\u092e\\u092f", "+11:00" }, { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, - { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, - { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, - { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094D\\u200D\\u091F\\u094D\\u0930\\u0947\\u0932\\u093F\\u092F\\u093E\\u0908 \\u092A\\u0942\\u0930\\u094D\\u0935\\u0940 \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "+10:00" }, + { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+\\u0967\\u0966:\\u0966\\u0966", "+10:00" }, + { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+\\u0967\\u0966", "+10:00" }, + { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094d\\u200d\\u091f\\u094d\\u0930\\u0947\\u0932\\u093f\\u092f\\u093e\\u0908 \\u092a\\u0942\\u0930\\u094d\\u0935\\u0940 \\u092e\\u093e\\u0928\\u0915 \\u0938\\u092e\\u092f", "+10:00" }, { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u0938\\u093F\\u0921\\u0928\\u0940 \\u0938\\u092E\\u092F", "Australia/Sydney" }, - { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u092A\\u0942\\u0930\\u094D\\u0935\\u0940 \\u0911\\u0938\\u094D\\u091F\\u094D\\u0930\\u0947\\u0932\\u093F\\u092F\\u093E\\u0908 \\u0938\\u092E\\u092F", "Australia/Sydney" }, + { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u092a\\u0942\\u0930\\u094d\\u0935\\u0940 \\u0911\\u0938\\u094d\\u091f\\u094d\\u0930\\u0947\\u0932\\u093f\\u092f\\u093e \\u0938\\u092e\\u092f", "Australia/Sydney" }, { "hi", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" }, { "hi", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" }, { "hi", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" }, { "hi", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u0917\\u094d\\u0930\\u0940\\u0928\\u0935\\u093f\\u091a \\u092e\\u0940\\u0928 \\u091f\\u093e\\u0907\\u092e", "+0:00" }, { "hi", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" }, - { "hi", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" }, - { "hi", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" }, - { "hi", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "GMT+01:00", "+1:00" }, - { "hi", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u092C\\u094D\\u0930\\u093F\\u091F\\u0947\\u0928 \\u0938\\u092E\\u092F", "Europe/London" }, - { "hi", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u092C\\u094D\\u0930\\u093F\\u091F\\u0947\\u0928 \\u0938\\u092E\\u092F", "Europe/London" }, + { "hi", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+\\u0966\\u0967:\\u0966\\u0966", "+1:00" }, + { "hi", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+\\u0967", "+1:00" }, + { "hi", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u092c\\u094d\\u0930\\u093f\\u091f\\u093f\\u0936 \\u0917\\u094d\\u0930\\u0940\\u0937\\u094d\\u092e\\u0915\\u093e\\u0932\\u0940\\u0928 \\u0938\\u092e\\u092f", "+1:00" }, + { "hi", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u092f\\u0942\\u0928\\u093e\\u0907\\u091f\\u0947\\u0921 \\u0915\\u093f\\u0902\\u0917\\u0921\\u092e \\u0938\\u092e\\u092f", "Europe/London" }, + { "hi", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u092f\\u0942\\u0928\\u093e\\u0907\\u091f\\u0947\\u0921 \\u0915\\u093f\\u0902\\u0917\\u0921\\u092e \\u0938\\u092e\\u092f", "Europe/London" }, { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, - { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, - { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, + { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-\\u0966\\u0969:\\u0966\\u0966", "-3:00" }, + { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-\\u0969", "-3:00" }, + { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-\\u0966\\u0969:\\u0966\\u0966", "-3:00" }, { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, - { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, - { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, - { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" }, - { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" }, + { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-\\u0966\\u0969:\\u0966\\u0966", "-3:00" }, + { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-\\u0969", "-3:00" }, + { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-\\u0966\\u0969:\\u0966\\u0966", "-3:00" }, + { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-\\u0969", "-3:00" }, + { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-\\u0966\\u0969:\\u0966\\u0966", "-3:00" }, { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" }, - { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, + { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+\\u0966\\u096B:\\u0969\\u0966", "+5:30" }, { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "IST", "+5:30" }, - { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u0938\\u092E\\u092F", "+5:30" }, + { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "+5:30" }, { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" }, - { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, + { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+\\u0966\\u096B:\\u0969\\u0966", "+5:30" }, { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "IST", "+05:30" }, - { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u0938\\u092E\\u092F", "+5:30" }, + { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "+5:30" }, { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "IST", "Asia/Calcutta" }, - { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u0938\\u092E\\u092F", "Asia/Calcutta" }, + { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "Asia/Calcutta" }, // ========== { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, - { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0800", "-8:00" }, - { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-8", "America/Los_Angeles" }, - { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u0422\\u0438\\u0445\\u043E\\u043E\\u043A\\u0435\\u0430\\u043D\\u0441\\u043A\\u0430 \\u0447\\u0430\\u0441\\u043E\\u0432\\u0430 \\u0437\\u043E\\u043D\\u0430", "America/Los_Angeles" }, + { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-08:00", "-8:00" }, + { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-8", "America/Los_Angeles" }, + { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u0421\\u0435\\u0432\\u0435\\u0440\\u043d\\u043e\\u0430\\u043c\\u0435\\u0440\\u0438\\u043a\\u0430\\u043d\\u0441\\u043a\\u043e \\u0442\\u0438\\u0445\\u043e\\u043e\\u043a\\u0435\\u0430\\u043d\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Los_Angeles" }, { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" }, - { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0700", "-7:00" }, - { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-7", "America/Los_Angeles" }, - { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u0422\\u0438\\u0445\\u043E\\u043E\\u043A\\u0435\\u0430\\u043D\\u0441\\u043A\\u0430 \\u043B\\u044F\\u0442\\u043D\\u0430 \\u0447\\u0430\\u0441\\u043E\\u0432\\u0430 \\u0437\\u043E\\u043D\\u0430", "America/Los_Angeles" }, + { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-07:00", "-7:00" }, + { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-7", "America/Los_Angeles" }, + { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u0421\\u0435\\u0432\\u0435\\u0440\\u043d\\u043e\\u0430\\u043c\\u0435\\u0440\\u0438\\u043a\\u0430\\u043d\\u0441\\u043a\\u043e \\u0442\\u0438\\u0445\\u043e\\u043e\\u043a\\u0435\\u0430\\u043d\\u0441\\u043a\\u043e \\u043b\\u044f\\u0442\\u043d\\u043e \\u0447\\u0430\\u0441\\u043e\\u0432\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Los_Angeles" }, // icu bg.txt has exemplar city for this time zone - { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u041B\\u043E\\u0441 \\u0410\\u043D\\u0436\\u0435\\u043B\\u0438\\u0441 \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Los_Angeles" }, - { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u0422\\u0438\\u0445\\u043E\\u043E\\u043A\\u0435\\u0430\\u043D\\u0441\\u043A\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Los_Angeles" }, - { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "\\u041B\\u043E\\u0441 \\u0410\\u043D\\u0436\\u0435\\u043B\\u0438\\u0441 \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Los_Angeles" }, + { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u041B\\u043E\\u0441 \\u0410\\u043D\\u0434\\u0436\\u0435\\u043B\\u0438\\u0441", "America/Los_Angeles" }, + { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u0421\\u0435\\u0432\\u0435\\u0440\\u043d\\u043e\\u0430\\u043c\\u0435\\u0440\\u0438\\u043a\\u0430\\u043d\\u0441\\u043a\\u043e \\u0442\\u0438\\u0445\\u043e\\u043e\\u043a\\u0435\\u0430\\u043d\\u0441\\u043a\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Los_Angeles" }, + { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "\\u041B\\u043E\\u0441 \\u0410\\u043D\\u0434\\u0436\\u0435\\u043B\\u0438\\u0441", "America/Los_Angeles" }, { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" }, - { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, - { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0430 \\u2013 \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" }, + { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, + { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, + { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" }, { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" }, - { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, - { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0430 \\u2013 \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" }, - { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u0411\\u0443\\u0435\\u043D\\u043E\\u0441 \\u0410\\u0439\\u0440\\u0435\\u0441 \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Buenos_Aires" }, - { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0430 \\u2013 \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Buenos_Aires" }, + { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, + { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, + { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" }, + { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u0411\\u0443\\u0435\\u043D\\u043E\\u0441 \\u0410\\u0439\\u0440\\u0435\\u0441", "America/Buenos_Aires" }, + { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Buenos_Aires" }, { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" }, - { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, - { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0430 \\u2013 \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" }, + { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, + { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, + { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" }, { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" }, - { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, - { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0430 \\u2013 \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" }, + { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, + { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, + { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" }, // icu bg.txt does not have info for this time zone - { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u0411\\u0443\\u0435\\u043D\\u043E\\u0441 \\u0410\\u0439\\u0440\\u0435\\u0441 \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Buenos_Aires" }, - { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0430 \\u2013 \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Buenos_Aires" }, + { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u0411\\u0443\\u0435\\u043D\\u043E\\u0441 \\u0410\\u0439\\u0440\\u0435\\u0441", "America/Buenos_Aires" }, + { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Buenos_Aires" }, { "bg", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" }, - { "bg", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0500", "-5:00" }, - { "bg", "America/Havana", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-5", "-5:00" }, + { "bg", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-05:00", "-5:00" }, + { "bg", "America/Havana", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-5", "-5:00" }, { "bg", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u041a\\u0443\\u0431\\u0438\\u043d\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-5:00" }, { "bg", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" }, - { "bg", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0400", "-4:00" }, - { "bg", "America/Havana", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-4", "-4:00" }, + { "bg", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-04:00", "-4:00" }, + { "bg", "America/Havana", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-4", "-4:00" }, { "bg", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u041a\\u0443\\u0431\\u0438\\u043d\\u0441\\u043a\\u043e \\u043b\\u044f\\u0442\\u043d\\u043e \\u0447\\u0430\\u0441\\u043e\\u0432\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-4:00" }, - { "bg", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u041a\\u0443\\u0431\\u0430 \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Havana" }, + { "bg", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u041a\\u0443\\u0431\\u0430", "America/Havana" }, { "bg", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u041a\\u0443\\u0431\\u0438\\u043d\\u0441\\u043a\\u043e \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Havana" }, { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, - { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+1100", "+11:00" }, - { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+11", "+11:00" }, + { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11:00", "+11:00" }, + { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11", "+11:00" }, { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u0410\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u044F \\u2013 \\u0438\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E \\u043B\\u044F\\u0442\\u043D\\u043E \\u0447\\u0430\\u0441\\u043E\\u0432\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "+11:00" }, { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, - { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+1000", "+10:00" }, - { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+10", "+10:00" }, + { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10:00", "+10:00" }, + { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10", "+10:00" }, { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u0410\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u044F \\u2013 \\u0438\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E \\u0441\\u0442\\u0430\\u043D\\u0434\\u0430\\u0440\\u0442\\u043D\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "+10:00" }, - { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u0421\\u0438\\u0434\\u043D\\u0438 \\u0432\\u0440\\u0435\\u043C\\u0435", "Australia/Sydney" }, + { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u0421\\u0438\\u0434\\u043D\\u0438", "Australia/Sydney" }, { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u0410\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u044F \\u2013 \\u0438\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "Australia/Sydney" }, { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, - { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+1100", "+11:00" }, - { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+11", "+11:00" }, + { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11:00", "+11:00" }, + { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11", "+11:00" }, { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u0410\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u044F \\u2013 \\u0438\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E \\u043B\\u044F\\u0442\\u043D\\u043E \\u0447\\u0430\\u0441\\u043E\\u0432\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "+11:00" }, { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, - { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+1000", "+10:00" }, - { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+10", "+10:00" }, + { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10:00", "+10:00" }, + { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10", "+10:00" }, { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u0410\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u044F \\u2013 \\u0438\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E \\u0441\\u0442\\u0430\\u043D\\u0434\\u0430\\u0440\\u0442\\u043D\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "+10:00" }, - { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u0421\\u0438\\u0434\\u043D\\u0438 \\u0432\\u0440\\u0435\\u043C\\u0435", "Australia/Sydney" }, + { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u0421\\u0438\\u0434\\u043D\\u0438", "Australia/Sydney" }, { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u0410\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u044F \\u2013 \\u0438\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "Australia/Sydney" }, { "bg", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" }, - { "bg", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" }, - { "bg", "Europe/London", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" }, - { "bg", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u0427\\u0430\\u0441\\u043E\\u0432\\u0430 \\u0437\\u043E\\u043D\\u0430 \\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" }, + { "bg", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" }, + { "bg", "Europe/London", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" }, + { "bg", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u0421\\u0440\\u0435\\u0434\\u043d\\u043e \\u0433\\u0440\\u0438\\u043d\\u0443\\u0438\\u0447\\u043a\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "+0:00" }, { "bg", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" }, - { "bg", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+0100", "+1:00" }, - { "bg", "Europe/London", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+1", "+1:00" }, - { "bg", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+0100", "+1:00" }, - { "bg", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u041e\\u0431\\u0435\\u0434\\u0438\\u043d\\u0435\\u043d\\u043e \\u043a\\u0440\\u0430\\u043b\\u0441\\u0442\\u0432\\u043e \\u0432\\u0440\\u0435\\u043C\\u0435", "Europe/London" }, - { "bg", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u041e\\u0431\\u0435\\u0434\\u0438\\u043d\\u0435\\u043d\\u043e \\u043a\\u0440\\u0430\\u043b\\u0441\\u0442\\u0432\\u043e \\u0432\\u0440\\u0435\\u043C\\u0435", "Europe/London" }, + { "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", "\\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\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" }, - { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, - { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" }, + { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, + { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, + { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, - { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" }, - { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, - { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" }, - { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, - { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" }, + { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, + { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, + { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, + { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, + { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, // JB#5150 { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" }, - { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+0530", "+5:30" }, - { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+530", "+5:30" }, - { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u0418\\u043d\\u0434\\u0438\\u0439\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "+5:30" }, + { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+05:30", "+5:30" }, + { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+5:30", "+5:30" }, + { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u0418\\u043d\\u0434\\u0438\\u0439\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043D\\u0434\\u0430\\u0440\\u0442\\u043D\\u043E \\u0432\\u0440\\u0435\\u043c\\u0435", "+5:30" }, { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" }, - { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+0530", "+5:30" }, - { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+530", "+05:30" }, - { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u0418\\u043d\\u0434\\u0438\\u0439\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "+5:30" }, - { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u0418\\u043D\\u0434\\u0438\\u044F \\u0432\\u0440\\u0435\\u043C\\u0435", "Asia/Calcutta" }, - { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u0418\\u043d\\u0434\\u0438\\u0439\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "Asia/Calcutta" }, + { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+05:30", "+5:30" }, + { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+5:30", "+05:30" }, + { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u0418\\u043d\\u0434\\u0438\\u0439\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043D\\u0434\\u0430\\u0440\\u0442\\u043D\\u043E \\u0432\\u0440\\u0435\\u043c\\u0435", "+5:30" }, + { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u0418\\u043D\\u0434\\u0438\\u044F", "Asia/Calcutta" }, + { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u0418\\u043d\\u0434\\u0438\\u0439\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043D\\u0434\\u0430\\u0440\\u0442\\u043D\\u043E \\u0432\\u0440\\u0435\\u043c\\u0435", "Asia/Calcutta" }, // ========== { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, @@ -3081,13 +3269,13 @@ void DateFormatTest::TestTimeZoneDisplayName() { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" }, { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" }, - { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u30A4\\u30F3\\u30C9\\u6642\\u9593", "+5:30" }, + { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u30A4\\u30F3\\u30C9\\u6A19\\u6E96\\u6642", "+5:30" }, { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" }, { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" }, - { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u30A4\\u30F3\\u30C9\\u6642\\u9593", "+5:30" }, + { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u30A4\\u30F3\\u30C9\\u6A19\\u6E96\\u6642", "+5:30" }, { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u30A4\\u30F3\\u30C9\\u6642\\u9593", "Asia/Calcutta" }, - { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u30A4\\u30F3\\u30C9\\u6642\\u9593", "Asia/Calcutta" }, + { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u30A4\\u30F3\\u30C9\\u6A19\\u6E96\\u6642", "Asia/Calcutta" }, // ========== @@ -3563,7 +3751,7 @@ void DateFormatTest::TestGMTParsing() { "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")); } @@ -3577,7 +3765,7 @@ void DateFormatTest::Test6880() { 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); @@ -3669,6 +3857,7 @@ void DateFormatTest::TestNumberAsStringParsing() } formatter->setLenient(itemPtr->lenient); + formatter->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->lenient, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->lenient, status); UDate date1 = formatter->parse(itemPtr->dateString, status); if (U_FAILURE(status)) { if (!itemPtr->expectFail) { @@ -3691,73 +3880,75 @@ void DateFormatTest::TestNumberAsStringParsing() } } -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); - failure(status, "new SimpleDateFormat with override", TRUE); + if (failure(status, "new SimpleDateFormat with override", TRUE)) { + return; + } UDate thedate = date(2009-1900, UCAL_JULY, 28); FieldPosition pos(0); 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 ); @@ -3765,7 +3956,7 @@ void DateFormatTest::TestFormalChineseDate() { 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; @@ -3776,7 +3967,7 @@ void DateFormatTest::TestFormalChineseDate() { void DateFormatTest::TestStandAloneGMTParse() { UErrorCode status = U_ZERO_ERROR; SimpleDateFormat *sdf = new SimpleDateFormat("ZZZZ", Locale(""), status); - + if (U_SUCCESS(status)) { UnicodeString inText("GMT$$$"); @@ -3870,49 +4061,50 @@ void DateFormatTest::TestMonthPatterns() const MonthPatternItem items[] = { // locale date style; expected formats for the 3 dates above - { "root@calendar=chinese", DateFormat::kLong, { UnicodeString("ren-chen Month4 2"), UnicodeString("ren-chen Month4bis 2"), UnicodeString("ren-chen Month5 2") } }, - { "root@calendar=chinese", DateFormat::kShort, { UnicodeString("29-04-02"), UnicodeString("29-04bis-02"), UnicodeString("29-05-02") } }, + { "root@calendar=chinese", DateFormat::kLong, { UnicodeString("2012(ren-chen) M04 2"), UnicodeString("2012(ren-chen) M04bis 2"), UnicodeString("2012(ren-chen) M05 2") } }, + { "root@calendar=chinese", DateFormat::kShort, { UnicodeString("2012-04-02"), UnicodeString("2012-04bis-02"), UnicodeString("2012-05-02") } }, { "root@calendar=chinese", -1, { UnicodeString("29-4-2"), UnicodeString("29-4bis-2"), UnicodeString("29-5-2") } }, { "root@calendar=chinese", -2, { UnicodeString("78x29-4-2"), UnicodeString("78x29-4bis-2"), UnicodeString("78x29-5-2") } }, { "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 Month4 2"), UnicodeString("ren-chen Month4bis 2"), UnicodeString("ren-chen Month5 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, ren-chen"), UnicodeString("Month4bis 2, ren-chen"), UnicodeString("Month5 2, ren-chen") } }, - { "en@calendar=chinese", DateFormat::kShort, { UnicodeString("4/2/29"), UnicodeString("4bis/2/29"), UnicodeString("5/2/29") } }, - { "zh@calendar=chinese", DateFormat::kLong, { CharsToUnicodeString("\\u58EC\\u8FB0\\u5E74\\u56DB\\u6708\\u4E8C\\u65E5"), - CharsToUnicodeString("\\u58EC\\u8FB0\\u5E74\\u95F0\\u56DB\\u6708\\u4E8C\\u65E5"), - CharsToUnicodeString("\\u58EC\\u8FB0\\u5E74\\u4E94\\u6708\\u4E8C\\u65E5") } }, - { "zh@calendar=chinese", DateFormat::kShort, { CharsToUnicodeString("\\u58EC\\u8FB0-4-2"), - CharsToUnicodeString("\\u58EC\\u8FB0-\\u95F04-2"), - CharsToUnicodeString("\\u58EC\\u8FB0-5-2") } }, + { "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("2012\\u58EC\\u8FB0\\u5E74\\u4E94\\u6708\\u521D\\u4E8C") } }, + { "zh@calendar=chinese", DateFormat::kShort, { CharsToUnicodeString("2012-4-2"), + CharsToUnicodeString("2012-\\u95F04-2"), + CharsToUnicodeString("2012-5-2") } }, { "zh@calendar=chinese", -3, { CharsToUnicodeString("\\u58EC\\u8FB0-4-2"), CharsToUnicodeString("\\u58EC\\u8FB0-\\u95F04-2"), CharsToUnicodeString("\\u58EC\\u8FB0-5-2") } }, { "zh@calendar=chinese", -4, { CharsToUnicodeString("\\u58EC\\u8FB0 \\u56DB\\u6708 2"), CharsToUnicodeString("\\u58EC\\u8FB0 \\u95F0\\u56DB\\u6708 2"), CharsToUnicodeString("\\u58EC\\u8FB0 \\u4E94\\u6708 2") } }, - { "zh_Hant@calendar=chinese", DateFormat::kLong, { CharsToUnicodeString("\\u58EC\\u8FB0\\u5E74\\u56DB\\u6708\\u4E8C\\u65E5"), - CharsToUnicodeString("\\u58EC\\u8FB0\\u5E74\\u958F\\u56DB\\u6708\\u4E8C\\u65E5"), - CharsToUnicodeString("\\u58EC\\u8FB0\\u5E74\\u4E94\\u6708\\u4E8C\\u65E5") } }, - { "zh_Hant@calendar=chinese", DateFormat::kShort, { CharsToUnicodeString("\\u58EC\\u8FB0/4/2"), - CharsToUnicodeString("\\u58EC\\u8FB0/\\u958F4/2"), - CharsToUnicodeString("\\u58EC\\u8FB0/5/2") } }, + { "zh_Hant@calendar=chinese", DateFormat::kLong, { CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u56DB\\u6708\\u521D\\u4E8C"), + CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u958F\\u56DB\\u6708\\u521D\\u4E8C"), + CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u4E94\\u6708\\u521D\\u4E8C") } }, + { "zh_Hant@calendar=chinese", DateFormat::kShort, { CharsToUnicodeString("2012/4/2"), + CharsToUnicodeString("2012/\\u958F4/2"), + CharsToUnicodeString("2012/5/2") } }, { "fr@calendar=chinese", DateFormat::kLong, { CharsToUnicodeString("2 s\\u00ECyu\\u00E8 ren-chen"), 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, 29"), UnicodeString("Month4 2, 29"), UnicodeString("Month5 1, 29") } }, - { "en@calendar=dangi", DateFormat::kShort, { UnicodeString("3bis/2/29"), UnicodeString("4/2/29"), UnicodeString("5/1/29") } }, - { "ko@calendar=dangi", DateFormat::kLong, { CharsToUnicodeString("\\uC784\\uC9C4\\uB144 3bis\\uC6D4 2\\uC77C"), + { "en@calendar=dangi", DateFormat::kLong, { UnicodeString("Third Monthbis 2, 2012(29)"), UnicodeString("Fourth Month 2, 2012(29)"), UnicodeString("Fifth Month 1, 2012(29)") } }, + { "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"), CharsToUnicodeString("\\uC784\\uC9C4\\uB144 4\\uC6D4 2\\uC77C"), CharsToUnicodeString("\\uC784\\uC9C4\\uB144 5\\uC6D4 1\\uC77C") } }, - { "ko@calendar=dangi", DateFormat::kShort, { CharsToUnicodeString("29. 3bis. 2."), + { "ko@calendar=dangi", DateFormat::kShort, { CharsToUnicodeString("29. \\uC7243. 2."), CharsToUnicodeString("29. 4. 2."), CharsToUnicodeString("29. 5. 1.") } }, // 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' @@ -4042,6 +4234,7 @@ void DateFormatTest::TestContext() // test item for a particular locale + calendar and date format typedef struct { + int32_t era; int32_t year; int32_t month; int32_t day; @@ -4054,6 +4247,7 @@ typedef struct { typedef struct { const char * locale; // with calendar DateFormat::EStyle style; + UnicodeString pattern; // ignored unless style == DateFormat::kNone const CalAndFmtTestItem *caftItems; } TestNonGregoItem; @@ -4061,23 +4255,62 @@ 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 + { 0, 4999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05D3\\u05F3\\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") }, + { 0, 5100, 0, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05E7\\u05F3") }, + { 0, 5774, 5, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05D0\\u05D3\\u05E8 \\u05D0\\u05F3 \\u05EA\\u05E9\\u05E2\\u05F4\\u05D3") }, + { 0, 5999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") }, + { 0, 6100, 0, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05D5\\u05F3\\u05E7\\u05F3") }, + { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator + }; + const CalAndFmtTestItem cafti_zh_chinese_custU[] = { + { 78, 31, 0, 1, 12, 0, CharsToUnicodeString("2014\\u7532\\u5348\\u5E74\\u6B63\\u67081") }, + { 77, 31, 0, 1, 12, 0, CharsToUnicodeString("1954\\u7532\\u5348\\u5E74\\u6B63\\u67081") }, + { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator + }; + const CalAndFmtTestItem cafti_zh_chinese_custNoU[] = { + { 78, 31, 0, 1, 12, 0, CharsToUnicodeString("2014\\u5E74\\u6B63\\u67081") }, + { 77, 31, 0, 1, 12, 0, CharsToUnicodeString("1954\\u5E74\\u6B63\\u67081") }, + { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator + }; + const CalAndFmtTestItem cafti_ja_japanese_custGy[] = { + {235, 26, 2, 5, 12, 0, CharsToUnicodeString("2014(\\u5E73\\u621026)\\u5E743\\u67085\\u65E5") }, + {234, 60, 2, 5, 12, 0, CharsToUnicodeString("1985(\\u662D\\u548C60)\\u5E743\\u67085\\u65E5") }, + { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator + }; + const CalAndFmtTestItem cafti_ja_japanese_custNoGy[] = { + {235, 26, 2, 5, 12, 0, CharsToUnicodeString("2014\\u5E743\\u67085\\u65E5") }, + {234, 60, 2, 5, 12, 0, CharsToUnicodeString("1985\\u5E743\\u67085\\u65E5") }, + { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator + }; + const CalAndFmtTestItem cafti_en_islamic_cust[] = { + { 0, 1384, 0, 1, 12, 0, UnicodeString("1 Muh. 1384 AH, 1964") }, + { 0, 1436, 0, 1, 12, 0, UnicodeString("1 Muh. 1436 AH, 2014") }, + { 0, 1487, 0, 1, 12, 0, UnicodeString("1 Muh. 1487 AH, 2064") }, + { 0, 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 + { "he@calendar=hebrew", DateFormat::kLong, UnicodeString(""), cafti_he_hebrew_long }, + { "zh@calendar=chinese", DateFormat::kNone, CharsToUnicodeString("rU\\u5E74MMMd"), cafti_zh_chinese_custU }, + { "zh@calendar=chinese", DateFormat::kNone, CharsToUnicodeString("r\\u5E74MMMd"), cafti_zh_chinese_custNoU }, + { "ja@calendar=japanese", DateFormat::kNone, CharsToUnicodeString("r(Gy)\\u5E74M\\u6708d\\u65E5"), cafti_ja_japanese_custGy }, + { "ja@calendar=japanese", DateFormat::kNone, CharsToUnicodeString("r\\u5E74M\\u6708d\\u65E5"), cafti_ja_japanese_custNoGy }, + { "en@calendar=islamic", DateFormat::kNone, UnicodeString("d MMM y G, r"), cafti_en_islamic_cust }, + { NULL, DateFormat::kNone, UnicodeString(""), 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) { + DateFormat * dfmt = NULL; + UErrorCode status = U_ZERO_ERROR; + if (itemPtr->style != DateFormat::kNone) { + dfmt = DateFormat::createDateInstance(itemPtr->style, locale); + } else { + dfmt = new SimpleDateFormat(itemPtr->pattern, locale, status); + } + if (U_FAILURE(status)) { + dataerrln("new SimpleDateFormat fails for locale %s", itemPtr->locale); + } else if (dfmt == NULL) { dataerrln("DateFormat::createDateInstance fails for locale %s", itemPtr->locale); } else { Calendar * cal = (dfmt->getCalendar())->clone(); @@ -4087,6 +4320,7 @@ void DateFormatTest::TestNonGregoFmtParse() const CalAndFmtTestItem * caftItemPtr; for (caftItemPtr = itemPtr->caftItems; caftItemPtr->year != 0; caftItemPtr++) { cal->clear(); + cal->set(UCAL_ERA, caftItemPtr->era); cal->set(UCAL_YEAR, caftItemPtr->year); cal->set(UCAL_MONTH, caftItemPtr->month); cal->set(UCAL_DATE, caftItemPtr->day); @@ -4102,13 +4336,16 @@ void DateFormatTest::TestNonGregoFmtParse() // formatted OK, try parse ParsePosition ppos(0); dfmt->parse(result, *cal, ppos); - UErrorCode status = U_ZERO_ERROR; + status = U_ZERO_ERROR; + int32_t era = cal->get(UCAL_ERA, status); 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 " + + if ( U_FAILURE(status) || ppos.getIndex() < result.length() || era != caftItemPtr->era || + 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->era +":"+caftItemPtr->year +"-"+caftItemPtr->month+"-"+caftItemPtr->day + ", got pos " + ppos.getIndex() + " " + year +"-"+month+"-"+day + " status " + UnicodeString(u_errorName(status)) ); } } @@ -4120,13 +4357,74 @@ void DateFormatTest::TestNonGregoFmtParse() } } +typedef struct { + const char* localeID; + DateFormat::EStyle style; + UnicodeString expectPattern; + UnicodeString expectFormat; +} TestFmtWithNumSysItem; +enum { kBBufMax = 128 }; +void DateFormatTest::TestFormatsWithNumberSystems() +{ + LocalPointer 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 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 sdfmt(static_cast(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() { // Test for date/time parsing regression with CLDR 22.1/ICU 50 pattern strings. // For details see http://bugs.icu-project.org/trac/ticket/9789 static const char *locales[] = { "en", "fr" }; - for (int32_t i = 0; i < LENGTHOF(locales); ++i) { + for (int32_t i = 0; i < UPRV_LENGTHOF(locales); ++i) { Locale locale(locales[i]); for (DateFormat::EStyle dateStyle = DateFormat::FULL; dateStyle <= DateFormat::SHORT; @@ -4186,6 +4484,1046 @@ UBool DateFormatTest::showParse(DateFormat &format, const UnicodeString &formatt return ok; } + +typedef struct { + const char * locale; + UBool leniency; + UnicodeString parseString; + UnicodeString pattern; + UnicodeString expectedResult; // empty string indicates expected error +} TestDateFormatLeniencyItem; + +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-07 02"), UnicodeString("yyyy-LLLL dd"), UnicodeString("2008-July 02") }, + { "en", false, UnicodeString("2008-07 02"), UnicodeString("yyyy-LLLL dd"), UnicodeString("") }, + { "en", true, UnicodeString("2008-Jan 02"), UnicodeString("yyyy-LLL. dd"), UnicodeString("2008-Jan. 02") }, + { "en", false, UnicodeString("2008-Jan 02"), UnicodeString("yyyy-LLL. dd"), UnicodeString("") }, + { "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("") } + }; + UErrorCode status = U_ZERO_ERROR; + LocalPointer cal(Calendar::createInstance(status)); + if (U_FAILURE(status)) { + dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale.")); + return; + } + cal->setTime(july022008, status); + const TestDateFormatLeniencyItem * itemPtr; + LocalPointer sdmft; + for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) { + + Locale locale = Locale::createFromName(itemPtr->locale); + status = U_ZERO_ERROR; + ParsePosition pos(0); + sdmft.adoptInsteadAndCheckErrorCode(new SimpleDateFormat(itemPtr->pattern, locale, status), status); + if (U_FAILURE(status)) { + dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status)); + continue; + } + sdmft->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->leniency, status). + setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->leniency, status). + 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() + + " - 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(""); + 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 + "]"); + continue; + } else { + logln("formatted results match! - " + formatResult); + } + + } +} + + +typedef struct { + UBool leniency; + UnicodeString parseString; + UnicodeString pattern; + UnicodeString expectedResult; // empty string indicates expected error +} TestMultiPatternMatchItem; + +void DateFormatTest::TestParseMultiPatternMatch() { + // 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("")}, + {false, UnicodeString("2013 Oct 22 4th quarter"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 22 4th quarter")}, + {false, UnicodeString("--end--"), UnicodeString(""), UnicodeString("")}, + }; + + UErrorCode status = U_ZERO_ERROR; + LocalPointer cal(Calendar::createInstance(status)); + if (U_FAILURE(status)) { + dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale.")); + return; + } + const TestMultiPatternMatchItem * itemPtr; + DateFormat* sdmft = DateFormat::createDateInstance(); + if (sdmft == NULL) { + dataerrln(UnicodeString("FAIL: Unable to create DateFormat")); + return; + } + for (itemPtr = items; itemPtr->parseString != "--end--"; itemPtr++ ) { + status = U_ZERO_ERROR; + ParsePosition pos(0); + ((SimpleDateFormat*) sdmft)->applyPattern(itemPtr->pattern); + if (U_FAILURE(status)) { + dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status)); + continue; + } + sdmft->setBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_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 + + " - 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; + } + + 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); + } + } + delete sdmft; +} + +void DateFormatTest::TestParseLeniencyAPIs() { + UErrorCode status = U_ZERO_ERROR; + LocalPointer dateFormat(DateFormat::createDateInstance()); + DateFormat *fmt = dateFormat.getAlias(); + if (fmt == NULL) { + dataerrln("Failed calling dateFormat.getAlias()"); + return; + } + + assertTrue("isLenient default", fmt->isLenient()); + 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_LITERAL_MATCH, status)); + assertTrue("MULTIPLE_PATTERNS default", fmt->getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status)); + + // Set calendar to strict + fmt->setCalendarLenient(FALSE); + + assertFalse("isLeninent after setCalendarLenient(FALSE)", fmt->isLenient()); + assertFalse("isCalendarLenient after setCalendarLenient(FALSE)", fmt->isCalendarLenient()); + assertTrue("ALLOW_WHITESPACE after setCalendarLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)); + assertTrue("ALLOW_NUMERIC after setCalendarLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)); + + // Set to strict + fmt->setLenient(FALSE); + + assertFalse("isLeninent after setLenient(FALSE)", fmt->isLenient()); + assertFalse("isCalendarLenient after setLenient(FALSE)", fmt->isCalendarLenient()); + 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_LITERAL_MATCH, status)); + assertTrue("MULTIPLE_PATTERNS after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status)); + + // Allow white space leniency + fmt->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, TRUE, status); + + assertFalse("isLeninent after ALLOW_WHITESPACE/TRUE", fmt->isLenient()); + assertFalse("isCalendarLenient after ALLOW_WHITESPACE/TRUE", fmt->isCalendarLenient()); + assertTrue("ALLOW_WHITESPACE after ALLOW_WHITESPACE/TRUE", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)); + assertFalse("ALLOW_NUMERIC after ALLOW_WHITESPACE/TRUE", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)); + + // Set to lenient + fmt->setLenient(TRUE); + + assertTrue("isLenient after setLenient(TRUE)", fmt->isLenient()); + assertTrue("isCalendarLenient after setLenient(TRUE)", fmt->isCalendarLenient()); + assertTrue("ALLOW_WHITESPACE after setLenient(TRUE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)); + assertTrue("ALLOW_NUMERIC after setLenient(TRUE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)); +} + +void DateFormatTest::TestNumberFormatOverride() { + UErrorCode status = U_ZERO_ERROR; + UnicodeString fields = (UnicodeString) "M"; + + LocalPointer fmt; + fmt.adoptInsteadAndCheckErrorCode(new SimpleDateFormat((UnicodeString)"MM d", status), status); + if (!assertSuccess("SimpleDateFormat with pattern MM d", status)) { + return; + } + + + for(int i=0; i<3; i++){ + NumberFormat* check_nf = NumberFormat::createInstance(Locale("en_US"), status); + assertSuccess("NumberFormat en_US", status); + fmt->adoptNumberFormat(fields, check_nf, status); + assertSuccess("adoptNumberFormat check_nf", status); + + const NumberFormat* get_nf = fmt->getNumberFormatForField('M'); + if (get_nf != check_nf) errln("FAIL: getter and setter do not work"); + } + NumberFormat* check_nf = NumberFormat::createInstance(Locale("en_US"), status); + assertSuccess("NumberFormat en_US", status); + fmt->adoptNumberFormat(check_nf); // make sure using the same NF will not crash + + const char * DATA [][2] = { + { "", "\\u521D\\u516D \\u5341\\u4E94"}, + { "M", "\\u521D\\u516D 15"}, + { "Mo", "\\u521D\\u516D 15"}, + { "Md", "\\u521D\\u516D \\u5341\\u4E94"}, + { "MdMMd", "\\u521D\\u516D \\u5341\\u4E94"}, + { "mixed", "\\u521D\\u516D \\u5341\\u4E94"} + }; + + UDate test_date = date(97, 6 - 1, 15); + + for(int i=0; i < UPRV_LENGTHOF(DATA); i++){ + fields = DATA[i][0]; + + LocalPointer fmt; + fmt.adoptInsteadAndCheckErrorCode(new SimpleDateFormat((UnicodeString)"MM d", status), status); + assertSuccess("SimpleDateFormat with pattern MM d", status); + NumberFormat* overrideNF = NumberFormat::createInstance(Locale::createFromName("zh@numbers=hanidays"),status); + assertSuccess("NumberFormat zh@numbers=hanidays", status); + + if (fields == (UnicodeString) "") { // use the one w/o fields + fmt->adoptNumberFormat(overrideNF); + } else if (fields == (UnicodeString) "mixed") { // set 1 field at first but then full override, both(M & d) should be override + NumberFormat* singleOverrideNF = NumberFormat::createInstance(Locale::createFromName("en@numbers=hebr"),status); + assertSuccess("NumberFormat en@numbers=hebr", 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); + if(status == U_INVALID_FORMAT_ERROR) { + status = U_ZERO_ERROR; + continue; + } + } else { + fmt->adoptNumberFormat(fields, overrideNF, status); + assertSuccess("adoptNumberFormat overrideNF", status); + } + + UnicodeString result; + FieldPosition pos(0); + fmt->format(test_date,result, pos); + + UnicodeString expected = ((UnicodeString)DATA[i][1]).unescape();; + + if (result != expected) + errln("FAIL: Expected " + expected + " get: " + result); + } +} + +void DateFormatTest::TestCreateInstanceForSkeleton() { + UErrorCode status = U_ZERO_ERROR; + LocalPointer fmt(DateFormat::createInstanceForSkeleton( + "yMMMMd", "en", status)); + if (!assertSuccess("Create with pattern yMMMMd", status)) { + return; + } + UnicodeString result; + FieldPosition pos(0); + fmt->format(date(98, 5-1, 25), result, pos); + assertEquals("format yMMMMd", "May 25, 1998", result); + fmt.adoptInstead(DateFormat::createInstanceForSkeleton( + "yMd", "en", status)); + if (!assertSuccess("Create with pattern yMd", status)) { + return; + } + result.remove(); + fmt->format(date(98, 5-1, 25), result, pos); + assertEquals("format yMd", "5/25/1998", result); +} + +void DateFormatTest::TestCreateInstanceForSkeletonDefault() { + UErrorCode status = U_ZERO_ERROR; + Locale savedLocale; + Locale::setDefault(Locale::getUS(), status); + LocalPointer fmt(DateFormat::createInstanceForSkeleton( + "yMMMd", status)); + Locale::setDefault(savedLocale, status); + if (!assertSuccess("Create with pattern yMMMd", status)) { + return; + } + UnicodeString result; + FieldPosition pos(0); + fmt->format(date(98, 5-1, 25), result, pos); + assertEquals("format yMMMd", "May 25, 1998", result); +} + +void DateFormatTest::TestCreateInstanceForSkeletonWithCalendar() { + UErrorCode status = U_ZERO_ERROR; + LocalPointer fmt( + DateFormat::createInstanceForSkeleton( + Calendar::createInstance( + TimeZone::createTimeZone("GMT-3:00"), + status), + "yMdHm", "en", status)); + if (!assertSuccess("Create with pattern yMMMMd", status)) { + return; + } + UnicodeString result; + FieldPosition pos(0); + + LocalPointer cal(Calendar::createInstance( + TimeZone::createTimeZone("GMT-7:00"), + status)); + if (!assertSuccess("Creating GMT-7 time zone failed", status)) { + return; + } + cal->clear(); + cal->set(1998, 5-1, 25, 0, 0, 0); + + // date format time zone should be 4 hours ahead. + fmt->format(cal->getTime(status), result, pos); + assertEquals("format yMdHm", "5/25/1998, 04:00", result); + assertSuccess("", status); +} + +void DateFormatTest::TestDFSCreateForLocaleNonGregorianLocale() { + UErrorCode status = U_ZERO_ERROR; + Locale fa("fa"); + LocalPointer sym( + DateFormatSymbols::createForLocale(fa, status)); + if (!assertSuccess("", status)) { + return; + } + + // Farsi should default to the persian calendar, not gregorian + int32_t count; + const UnicodeString *months = sym->getShortMonths(count); + + // First persian month. + UnicodeString expected("\\u0641\\u0631\\u0648\\u0631\\u062f\\u06cc\\u0646"); + assertEquals("", expected.unescape(), months[0]); +} + +void DateFormatTest::TestDFSCreateForLocaleWithCalendarInLocale() { + UErrorCode status = U_ZERO_ERROR; + Locale en_heb("en@calendar=hebrew"); + LocalPointer sym( + DateFormatSymbols::createForLocale(en_heb, status)); + if (!assertSuccess("", status)) { + return; + } + + // We should get the months of the hebrew calendar, not the gregorian + // calendar. + int32_t count; + const UnicodeString *months = sym->getShortMonths(count); + + // First hebrew month. + UnicodeString expected("Tishri"); + assertEquals("", expected, months[0]); +} + +void DateFormatTest::TestChangeCalendar() { + UErrorCode status = U_ZERO_ERROR; + Locale en("en"); + Locale en_heb("en@calendar=hebrew"); + LocalPointer fmt( + DateFormat::createInstanceForSkeleton("yMMMd", en, status)); + if (!assertSuccess("", status)) { + return; + } + fmt->adoptCalendar(Calendar::createInstance(en_heb, status)); + if (!assertSuccess("", status)) { + return; + } + UnicodeString result; + FieldPosition pos(0); + 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 fmt( + DateFormat::createInstanceForSkeleton( + TESTDATA[i].skeleton, TESTDATA[i].locale, status)); + if (!assertSuccess("createInstanceForSkeleton", status)) { + return; + } + UnicodeString pattern; + static_cast(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 */ //eof