Home | History | Annotate | Download | only in intltest
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /********************************************************************
      4  * COPYRIGHT:
      5  * Copyright (c) 1997-2016, International Business Machines
      6  * Corporation and others. All Rights Reserved.
      7  ********************************************************************/
      8 
      9 #include "unicode/utypes.h"
     10 
     11 #if !UCONFIG_NO_FORMATTING
     12 
     13 #include "dtfmttst.h"
     14 #include "unicode/localpointer.h"
     15 #include "unicode/timezone.h"
     16 #include "unicode/gregocal.h"
     17 #include "unicode/smpdtfmt.h"
     18 #include "unicode/datefmt.h"
     19 #include "unicode/dtptngen.h"
     20 #include "unicode/simpletz.h"
     21 #include "unicode/strenum.h"
     22 #include "unicode/dtfmtsym.h"
     23 #include "cmemory.h"
     24 #include "cstring.h"
     25 #include "caltest.h"  // for fieldName
     26 #include <stdio.h> // for sprintf
     27 
     28 #if U_PLATFORM_USES_ONLY_WIN32_API
     29 #include "windttst.h"
     30 #endif
     31 
     32 #define ASSERT_OK(status)  if(U_FAILURE(status)) {errcheckln(status, #status " = %s @ %s:%d", u_errorName(status), __FILE__, __LINE__); return; }
     33 
     34 // *****************************************************************************
     35 // class DateFormatTest
     36 // *****************************************************************************
     37 
     38 void DateFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
     39 {
     40     if(exec) {
     41         logln("TestSuite DateFormatTest: ");
     42     }
     43     TESTCASE_AUTO_BEGIN;
     44     TESTCASE_AUTO(TestPatterns);
     45     TESTCASE_AUTO(TestEquals);
     46     TESTCASE_AUTO(TestTwoDigitYearDSTParse);
     47     TESTCASE_AUTO(TestFieldPosition);
     48     TESTCASE_AUTO(TestPartialParse994);
     49     TESTCASE_AUTO(TestRunTogetherPattern985);
     50     TESTCASE_AUTO(TestRunTogetherPattern917);
     51     TESTCASE_AUTO(TestCzechMonths459);
     52     TESTCASE_AUTO(TestLetterDPattern212);
     53     TESTCASE_AUTO(TestDayOfYearPattern195);
     54     TESTCASE_AUTO(TestQuotePattern161);
     55     TESTCASE_AUTO(TestBadInput135);
     56     TESTCASE_AUTO(TestBadInput135a);
     57     TESTCASE_AUTO(TestTwoDigitYear);
     58     TESTCASE_AUTO(TestDateFormatZone061);
     59     TESTCASE_AUTO(TestDateFormatZone146);
     60     TESTCASE_AUTO(TestLocaleDateFormat);
     61     TESTCASE_AUTO(TestFormattingLocaleTimeSeparator);
     62     TESTCASE_AUTO(TestWallyWedel);
     63     TESTCASE_AUTO(TestDateFormatCalendar);
     64     TESTCASE_AUTO(TestSpaceParsing);
     65     TESTCASE_AUTO(TestExactCountFormat);
     66     TESTCASE_AUTO(TestWhiteSpaceParsing);
     67     TESTCASE_AUTO(TestInvalidPattern);
     68     TESTCASE_AUTO(TestGeneral);
     69     TESTCASE_AUTO(TestGreekMay);
     70     TESTCASE_AUTO(TestGenericTime);
     71     TESTCASE_AUTO(TestGenericTimeZoneOrder);
     72     TESTCASE_AUTO(TestHost);
     73     TESTCASE_AUTO(TestEras);
     74     TESTCASE_AUTO(TestNarrowNames);
     75     TESTCASE_AUTO(TestShortDays);
     76     TESTCASE_AUTO(TestStandAloneDays);
     77     TESTCASE_AUTO(TestStandAloneMonths);
     78     TESTCASE_AUTO(TestQuarters);
     79     TESTCASE_AUTO(TestZTimeZoneParsing);
     80     TESTCASE_AUTO(TestRelative);
     81     TESTCASE_AUTO(TestRelativeClone);
     82     TESTCASE_AUTO(TestHostClone);
     83     TESTCASE_AUTO(TestHebrewClone);
     84     TESTCASE_AUTO(TestDateFormatSymbolsClone);
     85     TESTCASE_AUTO(TestTimeZoneDisplayName);
     86     TESTCASE_AUTO(TestRoundtripWithCalendar);
     87     TESTCASE_AUTO(Test6338);
     88     TESTCASE_AUTO(Test6726);
     89     TESTCASE_AUTO(TestGMTParsing);
     90     TESTCASE_AUTO(Test6880);
     91     TESTCASE_AUTO(TestISOEra);
     92     TESTCASE_AUTO(TestFormalChineseDate);
     93     TESTCASE_AUTO(TestNumberAsStringParsing);
     94     TESTCASE_AUTO(TestStandAloneGMTParse);
     95     TESTCASE_AUTO(TestParsePosition);
     96     TESTCASE_AUTO(TestMonthPatterns);
     97     TESTCASE_AUTO(TestContext);
     98     TESTCASE_AUTO(TestNonGregoFmtParse);
     99     TESTCASE_AUTO(TestFormatsWithNumberSystems);
    100     /*
    101     TESTCASE_AUTO(TestRelativeError);
    102     TESTCASE_AUTO(TestRelativeOther);
    103     */
    104     TESTCASE_AUTO(TestDotAndAtLeniency);
    105     TESTCASE_AUTO(TestDateFormatLeniency);
    106     TESTCASE_AUTO(TestParseMultiPatternMatch);
    107 
    108     TESTCASE_AUTO(TestParseLeniencyAPIs);
    109     TESTCASE_AUTO(TestNumberFormatOverride);
    110     TESTCASE_AUTO(TestCreateInstanceForSkeleton);
    111     TESTCASE_AUTO(TestCreateInstanceForSkeletonDefault);
    112     TESTCASE_AUTO(TestCreateInstanceForSkeletonWithCalendar);
    113     TESTCASE_AUTO(TestDFSCreateForLocaleNonGregorianLocale);
    114     TESTCASE_AUTO(TestDFSCreateForLocaleWithCalendarInLocale);
    115     TESTCASE_AUTO(TestChangeCalendar);
    116 
    117     TESTCASE_AUTO(TestPatternFromSkeleton);
    118 
    119     TESTCASE_AUTO(TestAmPmMidnightNoon);
    120     TESTCASE_AUTO(TestFlexibleDayPeriod);
    121     TESTCASE_AUTO(TestDayPeriodWithLocales);
    122     TESTCASE_AUTO(TestMinuteSecondFieldsInOddPlaces);
    123     TESTCASE_AUTO(TestDayPeriodParsing);
    124 
    125     TESTCASE_AUTO_END;
    126 }
    127 
    128 void DateFormatTest::TestPatterns() {
    129     static const struct {
    130         const char *actualPattern;
    131         const char *expectedPattern;
    132         const char *localeID;
    133         const char *expectedLocalPattern;
    134     } EXPECTED[] = {
    135         {UDAT_YEAR, "y","en","y"},
    136 
    137         {UDAT_QUARTER, "QQQQ", "en", "QQQQ"},
    138         {UDAT_ABBR_QUARTER, "QQQ", "en", "QQQ"},
    139         {UDAT_YEAR_QUARTER, "yQQQQ", "en", "QQQQ y"},
    140         {UDAT_YEAR_ABBR_QUARTER, "yQQQ", "en", "QQQ y"},
    141 
    142         {UDAT_NUM_MONTH, "M", "en", "L"},
    143         {UDAT_ABBR_MONTH, "MMM", "en", "LLL"},
    144         {UDAT_MONTH, "MMMM", "en", "LLLL"},
    145         {UDAT_YEAR_NUM_MONTH, "yM","en","M/y"},
    146         {UDAT_YEAR_ABBR_MONTH, "yMMM","en","MMM y"},
    147         {UDAT_YEAR_MONTH, "yMMMM","en","MMMM y"},
    148 
    149         {UDAT_DAY, "d","en","d"},
    150         {UDAT_YEAR_NUM_MONTH_DAY, "yMd", "en", "M/d/y"},
    151         {UDAT_YEAR_ABBR_MONTH_DAY, "yMMMd", "en", "MMM d, y"},
    152         {UDAT_YEAR_MONTH_DAY, "yMMMMd", "en", "MMMM d, y"},
    153         {UDAT_YEAR_NUM_MONTH_WEEKDAY_DAY, "yMEd", "en", "EEE, M/d/y"},
    154         {UDAT_YEAR_ABBR_MONTH_WEEKDAY_DAY, "yMMMEd", "en", "EEE, MMM d, y"},
    155         {UDAT_YEAR_MONTH_WEEKDAY_DAY, "yMMMMEEEEd", "en", "EEEE, MMMM d, y"},
    156 
    157         {UDAT_NUM_MONTH_DAY, "Md","en","M/d"},
    158         {UDAT_ABBR_MONTH_DAY, "MMMd","en","MMM d"},
    159         {UDAT_MONTH_DAY, "MMMMd","en","MMMM d"},
    160         {UDAT_NUM_MONTH_WEEKDAY_DAY, "MEd","en","EEE, M/d"},
    161         {UDAT_ABBR_MONTH_WEEKDAY_DAY, "MMMEd","en","EEE, MMM d"},
    162         {UDAT_MONTH_WEEKDAY_DAY, "MMMMEEEEd","en","EEEE, MMMM d"},
    163 
    164         {UDAT_HOUR, "j", "en", "h a"}, // (fixed expected result per ticket 6872<-6626)
    165         {UDAT_HOUR24, "H", "en", "HH"}, // (fixed expected result per ticket 6872<-6626
    166 
    167         {UDAT_MINUTE, "m", "en", "m"},
    168         {UDAT_HOUR_MINUTE, "jm","en","h:mm a"}, // (fixed expected result per ticket 6872<-7180)
    169         {UDAT_HOUR24_MINUTE, "Hm", "en", "HH:mm"}, // (fixed expected result per ticket 6872<-6626)
    170 
    171         {UDAT_SECOND, "s", "en", "s"},
    172         {UDAT_HOUR_MINUTE_SECOND, "jms","en","h:mm:ss a"}, // (fixed expected result per ticket 6872<-7180)
    173         {UDAT_HOUR24_MINUTE_SECOND, "Hms","en","HH:mm:ss"}, // (fixed expected result per ticket 6872<-6626)
    174         {UDAT_MINUTE_SECOND, "ms", "en", "mm:ss"}, // (fixed expected result per ticket 6872<-6626)
    175 
    176         {UDAT_LOCATION_TZ, "VVVV", "en", "VVVV"},
    177         {UDAT_GENERIC_TZ, "vvvv", "en", "vvvv"},
    178         {UDAT_ABBR_GENERIC_TZ, "v", "en", "v"},
    179         {UDAT_SPECIFIC_TZ, "zzzz", "en", "zzzz"},
    180         {UDAT_ABBR_SPECIFIC_TZ, "z", "en", "z"},
    181         {UDAT_ABBR_UTC_TZ, "ZZZZ", "en", "ZZZZ"},
    182 
    183         {UDAT_YEAR_NUM_MONTH_DAY UDAT_ABBR_UTC_TZ, "yMdZZZZ", "en", "M/d/y, ZZZZ"},
    184         {UDAT_MONTH_DAY UDAT_LOCATION_TZ, "MMMMdVVVV", "en", "MMMM d, VVVV"}
    185     };
    186 
    187     IcuTestErrorCode errorCode(*this, "TestPatterns()");
    188     for (int32_t i = 0; i < UPRV_LENGTHOF(EXPECTED); i++) {
    189         // Verify that patterns have the correct values
    190         UnicodeString actualPattern(EXPECTED[i].actualPattern, -1, US_INV);
    191         UnicodeString expectedPattern(EXPECTED[i].expectedPattern, -1, US_INV);
    192         Locale locale(EXPECTED[i].localeID);
    193         if (actualPattern != expectedPattern) {
    194             errln("FAILURE! Expected pattern: " + expectedPattern +
    195                     " but was: " + actualPattern);
    196         }
    197 
    198         // Verify that DataFormat instances produced contain the correct
    199         // localized patterns
    200         // TODO: use DateFormat::getInstanceForSkeleton(), ticket #9029
    201         // Java test code:
    202         // DateFormat date1 = DateFormat.getPatternInstance(actualPattern,
    203         //         locale);
    204         // DateFormat date2 = DateFormat.getPatternInstance(Calendar.getInstance(locale),
    205         //         actualPattern, locale);
    206         LocalPointer<DateTimePatternGenerator> generator(
    207                 DateTimePatternGenerator::createInstance(locale, errorCode));
    208         if(errorCode.logDataIfFailureAndReset("DateTimePatternGenerator::createInstance() failed for locale ID \"%s\"", EXPECTED[i].localeID)) {
    209             continue;
    210         }
    211         UnicodeString pattern = generator->getBestPattern(actualPattern, errorCode);
    212         SimpleDateFormat date1(pattern, locale, errorCode);
    213         SimpleDateFormat date2(pattern, locale, errorCode);
    214         date2.adoptCalendar(Calendar::createInstance(locale, errorCode));
    215         if(errorCode.logIfFailureAndReset("DateFormat::getInstanceForSkeleton() failed")) {
    216             errln("  for actualPattern \"%s\" & locale ID \"%s\"",
    217                   EXPECTED[i].actualPattern, EXPECTED[i].localeID);
    218             continue;
    219         }
    220 
    221         UnicodeString expectedLocalPattern(EXPECTED[i].expectedLocalPattern, -1, US_INV);
    222         UnicodeString actualLocalPattern1;
    223         UnicodeString actualLocalPattern2;
    224         date1.toLocalizedPattern(actualLocalPattern1, errorCode);
    225         date2.toLocalizedPattern(actualLocalPattern2, errorCode);
    226         if (actualLocalPattern1 != expectedLocalPattern) {
    227             errln("FAILURE! Expected local pattern: " + expectedLocalPattern
    228                     + " but was: " + actualLocalPattern1);
    229         }
    230         if (actualLocalPattern2 != expectedLocalPattern) {
    231             errln("FAILURE! Expected local pattern: " + expectedLocalPattern
    232                     + " but was: " + actualLocalPattern2);
    233         }
    234     }
    235 }
    236 
    237 // Test written by Wally Wedel and emailed to me.
    238 void DateFormatTest::TestWallyWedel()
    239 {
    240     UErrorCode status = U_ZERO_ERROR;
    241     /*
    242      * Instantiate a TimeZone so we can get the ids.
    243      */
    244     TimeZone *tz = new SimpleTimeZone(7,"");
    245     /*
    246      * Computational variables.
    247      */
    248     int32_t offset, hours, minutes, seconds;
    249     /*
    250      * Instantiate a SimpleDateFormat set up to produce a full time
    251      zone name.
    252      */
    253     SimpleDateFormat *sdf = new SimpleDateFormat((UnicodeString)"zzzz", status);
    254     /*
    255      * A String array for the time zone ids.
    256      */
    257     int32_t ids_length;
    258     StringEnumeration* ids = TimeZone::createEnumeration();
    259     if (ids == NULL) {
    260         dataerrln("Unable to create TimeZone enumeration.");
    261         if (sdf != NULL) {
    262             delete sdf;
    263         }
    264         return;
    265     }
    266     ids_length = ids->count(status);
    267     /*
    268      * How many ids do we have?
    269      */
    270     logln("Time Zone IDs size: %d", ids_length);
    271     /*
    272      * Column headings (sort of)
    273      */
    274     logln("Ordinal ID offset(h:m) name");
    275     /*
    276      * Loop through the tzs.
    277      */
    278     UDate today = Calendar::getNow();
    279     Calendar *cal = Calendar::createInstance(status);
    280     for (int32_t i = 0; i < ids_length; i++) {
    281         // logln(i + " " + ids[i]);
    282         const UnicodeString* id = ids->snext(status);
    283         TimeZone *ttz = TimeZone::createTimeZone(*id);
    284         // offset = ttz.getRawOffset();
    285         cal->setTimeZone(*ttz);
    286         cal->setTime(today, status);
    287         offset = cal->get(UCAL_ZONE_OFFSET, status) + cal->get(UCAL_DST_OFFSET, status);
    288         // logln(i + " " + ids[i] + " offset " + offset);
    289         const char* sign = "+";
    290         if (offset < 0) {
    291             sign = "-";
    292             offset = -offset;
    293         }
    294         hours = offset/3600000;
    295         minutes = (offset%3600000)/60000;
    296         seconds = (offset%60000)/1000;
    297         UnicodeString dstOffset = (UnicodeString)"" + sign + (hours < 10 ? "0" : "") +
    298             (int32_t)hours + ":" + (minutes < 10 ? "0" : "") + (int32_t)minutes;
    299         if (seconds != 0) {
    300             dstOffset = dstOffset + ":" + (seconds < 10 ? "0" : "") + seconds;
    301         }
    302         /*
    303          * Instantiate a date so we can display the time zone name.
    304          */
    305         sdf->setTimeZone(*ttz);
    306         /*
    307          * Format the output.
    308          */
    309         UnicodeString fmtOffset;
    310         FieldPosition pos(FieldPosition::DONT_CARE);
    311         sdf->format(today,fmtOffset, pos);
    312         // UnicodeString fmtOffset = tzS.toString();
    313         UnicodeString *fmtDstOffset = 0;
    314         if (fmtOffset.startsWith("GMT") && fmtOffset.length() != 3)
    315         {
    316             //fmtDstOffset = fmtOffset->substring(3);
    317             fmtDstOffset = new UnicodeString();
    318             fmtOffset.extract(3, fmtOffset.length(), *fmtDstOffset);
    319         }
    320         /*
    321          * Show our result.
    322          */
    323         UBool ok = fmtDstOffset == 0 || *fmtDstOffset == dstOffset;
    324         if (ok)
    325         {
    326             logln(UnicodeString() + i + " " + *id + " " + dstOffset +
    327                   " " + fmtOffset +
    328                   (fmtDstOffset != 0 ? " ok" : " ?"));
    329         }
    330         else
    331         {
    332             errln(UnicodeString() + i + " " + *id + " " + dstOffset +
    333                   " " + fmtOffset + " *** FAIL ***");
    334         }
    335         delete ttz;
    336         delete fmtDstOffset;
    337     }
    338     delete cal;
    339     //  delete ids;   // TODO:  BAD API
    340     delete ids;
    341     delete sdf;
    342     delete tz;
    343 }
    344 
    345 // -------------------------------------
    346 
    347 /**
    348  * Test operator==
    349  */
    350 void
    351 DateFormatTest::TestEquals()
    352 {
    353     DateFormat* fmtA = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL);
    354     DateFormat* fmtB = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL);
    355     if ( fmtA == NULL || fmtB == NULL){
    356         dataerrln("Error calling DateFormat::createDateTimeInstance");
    357         delete fmtA;
    358         delete fmtB;
    359         return;
    360     }
    361 
    362     if (!(*fmtA == *fmtB)) errln((UnicodeString)"FAIL");
    363     delete fmtA;
    364     delete fmtB;
    365 
    366     TimeZone* test = TimeZone::createTimeZone("PDT");
    367     delete test;
    368 }
    369 
    370 // -------------------------------------
    371 
    372 /**
    373  * Test the parsing of 2-digit years.
    374  */
    375 void
    376 DateFormatTest::TestTwoDigitYearDSTParse(void)
    377 {
    378     UErrorCode status = U_ZERO_ERROR;
    379     SimpleDateFormat* fullFmt = new SimpleDateFormat((UnicodeString)"EEE MMM dd HH:mm:ss.SSS zzz yyyy G", status);
    380     SimpleDateFormat *fmt = new SimpleDateFormat((UnicodeString)"dd-MMM-yy h:mm:ss 'o''clock' a z", Locale::getEnglish(), status);
    381     //DateFormat* fmt = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL, Locale::ENGLISH);
    382     UnicodeString* s = new UnicodeString("03-Apr-04 2:20:47 o'clock AM PST", "");
    383     TimeZone* defaultTZ = TimeZone::createDefault();
    384     TimeZone* PST = TimeZone::createTimeZone("PST");
    385     int32_t defaultOffset = defaultTZ->getRawOffset();
    386     int32_t PSTOffset = PST->getRawOffset();
    387     int32_t hour = 2 + (defaultOffset - PSTOffset) / (60*60*1000);
    388     // hour is the expected hour of day, in units of seconds
    389     hour = ((hour < 0) ? hour + 24 : hour) * 60*60;
    390 
    391     UnicodeString str;
    392 
    393     if(U_FAILURE(status)) {
    394         dataerrln("Could not set up test. exitting - %s", u_errorName(status));
    395         return;
    396     }
    397 
    398     UDate d = fmt->parse(*s, status);
    399     logln(*s + " P> " + ((DateFormat*)fullFmt)->format(d, str));
    400     int32_t y, m, day, hr, min, sec;
    401     dateToFields(d, y, m, day, hr, min, sec);
    402     hour += defaultTZ->inDaylightTime(d, status) ? 1 : 0;
    403     hr = hr*60*60;
    404     if (hr != hour)
    405         errln((UnicodeString)"FAIL: Should parse to hour " + hour + " but got " + hr);
    406 
    407     if (U_FAILURE(status))
    408         errln((UnicodeString)"FAIL: " + (int32_t)status);
    409 
    410     delete s;
    411     delete fmt;
    412     delete fullFmt;
    413     delete PST;
    414     delete defaultTZ;
    415 }
    416 
    417 // -------------------------------------
    418 
    419 UChar toHexString(int32_t i) { return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10))); }
    420 
    421 UnicodeString&
    422 DateFormatTest::escape(UnicodeString& s)
    423 {
    424     UnicodeString buf;
    425     for (int32_t i=0; i<s.length(); ++i)
    426     {
    427         UChar c = s[(int32_t)i];
    428         if (c <= (UChar)0x7F) buf += c;
    429         else {
    430             buf += (UChar)0x5c; buf += (UChar)0x55;
    431             buf += toHexString((c & 0xF000) >> 12);
    432             buf += toHexString((c & 0x0F00) >> 8);
    433             buf += toHexString((c & 0x00F0) >> 4);
    434             buf += toHexString(c & 0x000F);
    435         }
    436     }
    437     return (s = buf);
    438 }
    439 
    440 // -------------------------------------
    441 
    442 /**
    443  * This MUST be kept in sync with DateFormatSymbols.gPatternChars.
    444  */
    445 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
    446 static const char* PATTERN_CHARS = "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB:";
    447 #else
    448 static const char* PATTERN_CHARS = "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB";
    449 #endif
    450 
    451 /**
    452  * A list of the names of all the fields in DateFormat.
    453  * This MUST be kept in sync with DateFormat.
    454  */
    455 static const char* DATEFORMAT_FIELD_NAMES[] = {
    456     "ERA_FIELD",
    457     "YEAR_FIELD",
    458     "MONTH_FIELD",
    459     "DATE_FIELD",
    460     "HOUR_OF_DAY1_FIELD",
    461     "HOUR_OF_DAY0_FIELD",
    462     "MINUTE_FIELD",
    463     "SECOND_FIELD",
    464     "MILLISECOND_FIELD",
    465     "DAY_OF_WEEK_FIELD",
    466     "DAY_OF_YEAR_FIELD",
    467     "DAY_OF_WEEK_IN_MONTH_FIELD",
    468     "WEEK_OF_YEAR_FIELD",
    469     "WEEK_OF_MONTH_FIELD",
    470     "AM_PM_FIELD",
    471     "HOUR1_FIELD",
    472     "HOUR0_FIELD",
    473     "TIMEZONE_FIELD",
    474     "YEAR_WOY_FIELD",
    475     "DOW_LOCAL_FIELD",
    476     "EXTENDED_YEAR_FIELD",
    477     "JULIAN_DAY_FIELD",
    478     "MILLISECONDS_IN_DAY_FIELD",
    479     "TIMEZONE_RFC_FIELD",
    480     "GENERIC_TIMEZONE_FIELD",
    481     "STAND_ALONE_DAY_FIELD",
    482     "STAND_ALONE_MONTH_FIELD",
    483     "QUARTER_FIELD",
    484     "STAND_ALONE_QUARTER_FIELD",
    485     "TIMEZONE_SPECIAL_FIELD",
    486     "YEAR_NAME_FIELD",
    487     "TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD",
    488     "TIMEZONE_ISO_FIELD",
    489     "TIMEZONE_ISO_LOCAL_FIELD",
    490     "RELATED_YEAR_FIELD",
    491     "AM_PM_MIDNIGHT_NOON_FIELD",
    492     "FLEXIBLE_DAY_PERIOD_FIELD",
    493     "UDAT_TIME_SEPARATOR_FIELD",
    494 };
    495 
    496 static const int32_t DATEFORMAT_FIELD_NAMES_LENGTH =
    497     UPRV_LENGTHOF(DATEFORMAT_FIELD_NAMES);
    498 
    499 /**
    500  * Verify that returned field position indices are correct.
    501  */
    502 void DateFormatTest::TestFieldPosition() {
    503     UErrorCode ec = U_ZERO_ERROR;
    504     int32_t i, j, exp;
    505     UnicodeString buf;
    506 
    507     // Verify data
    508     DateFormatSymbols rootSyms(Locale(""), ec);
    509     if (U_FAILURE(ec)) {
    510         dataerrln("Unable to create DateFormatSymbols - %s", u_errorName(ec));
    511         return;
    512     }
    513 
    514     // local pattern chars data is not longer loaded
    515     // from icu locale bundle
    516     assertEquals("patternChars", PATTERN_CHARS, rootSyms.getLocalPatternChars(buf));
    517     assertEquals("patternChars", PATTERN_CHARS, DateFormatSymbols::getPatternUChars());
    518     assertTrue("DATEFORMAT_FIELD_NAMES", DATEFORMAT_FIELD_NAMES_LENGTH == UDAT_FIELD_COUNT);
    519 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
    520     assertTrue("Data", UDAT_FIELD_COUNT == uprv_strlen(PATTERN_CHARS));
    521 #else
    522     assertTrue("Data", UDAT_FIELD_COUNT == uprv_strlen(PATTERN_CHARS) + 1); // +1 for missing TIME_SEPARATOR pattern char
    523 #endif
    524 
    525     // Create test formatters
    526     const int32_t COUNT = 4;
    527     DateFormat* dateFormats[COUNT];
    528     dateFormats[0] = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale::getUS());
    529     dateFormats[1] = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale::getFrance());
    530     // Make the pattern "G y M d..."
    531     buf.remove().append(PATTERN_CHARS);
    532     for (j=buf.length()-1; j>=0; --j) buf.insert(j, (UChar)32/*' '*/);
    533     dateFormats[2] = new SimpleDateFormat(buf, Locale::getUS(), ec);
    534     // Make the pattern "GGGG yyyy MMMM dddd..."
    535     for (j=buf.length()-1; j>=0; j-=2) {
    536         for (i=0; i<3; ++i) {
    537             buf.insert(j, buf.charAt(j));
    538         }
    539     }
    540     dateFormats[3] = new SimpleDateFormat(buf, Locale::getUS(), ec);
    541     if(U_FAILURE(ec)){
    542         errln(UnicodeString("Could not create SimpleDateFormat object for locale en_US. Error: " )+ UnicodeString(u_errorName(ec)));
    543         return;
    544     }
    545     UDate aug13 = 871508052513.0;
    546 
    547     // Expected output field values for above DateFormats on aug13
    548     // Fields are given in order of DateFormat field number
    549     const char* EXPECTED[] = {
    550         "", "1997", "August", "13", "", "", "34", "12", "", "Wednesday",
    551         "", "", "", "", "PM", "2", "", "Pacific Daylight Time", "", "",
    552         "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
    553 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
    554         ":",
    555 #else
    556         "",
    557 #endif
    558 
    559         "", "1997", "ao\\u00FBt", "13", "", "14", "34", "12", "", "mercredi",
    560         "", "", "", "", "", "", "", "heure d\\u2019\\u00E9t\\u00E9 du Pacifique", "", "",
    561         "", "", "", "", "",  "", "", "", "", "", "", "", "", "", "", "", "",
    562 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
    563         ":",
    564 #else
    565         "",
    566 #endif
    567 
    568         "AD", "1997", "8", "13", "14", "14", "34", "12", "5", "Wed",
    569         "225", "2", "33", "3", "PM", "2", "2", "PDT", "1997", "4",
    570         "1997", "2450674", "52452513", "-0700", "PT",  "4", "8", "3", "3", "uslax",
    571         "1997", "GMT-7", "-07", "-07", "1997", "PM", "in the afternoon",
    572 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
    573         ":",
    574 #else
    575         "",
    576 #endif
    577 
    578         "Anno Domini", "1997", "August", "0013", "0014", "0014", "0034", "0012", "5130", "Wednesday",
    579         "0225", "0002", "0033", "0003", "PM", "0002", "0002", "Pacific Daylight Time", "1997", "Wednesday",
    580         "1997", "2450674", "52452513", "GMT-07:00", "Pacific Time",  "Wednesday", "August", "3rd quarter", "3rd quarter", "Los Angeles Time",
    581         "1997", "GMT-07:00", "-0700", "-0700", "1997", "PM", "in the afternoon",
    582 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
    583         ":",
    584 #else
    585         "",
    586 #endif
    587     };
    588 
    589     const int32_t EXPECTED_LENGTH = UPRV_LENGTHOF(EXPECTED);
    590 
    591     assertTrue("data size", EXPECTED_LENGTH == COUNT * UDAT_FIELD_COUNT);
    592 
    593     TimeZone* PT = TimeZone::createTimeZone("America/Los_Angeles");
    594     for (j = 0, exp = 0; j < COUNT; ++j) {
    595         //  String str;
    596         DateFormat* df = dateFormats[j];
    597         df->setTimeZone(*PT);
    598         SimpleDateFormat* sdtfmt = dynamic_cast<SimpleDateFormat*>(df);
    599         if (sdtfmt != NULL) {
    600             logln(" Pattern = " + sdtfmt->toPattern(buf.remove()));
    601         } else {
    602             logln(" Pattern = ? (not a SimpleDateFormat)");
    603         }
    604         logln((UnicodeString)"  Result = " + df->format(aug13, buf.remove()));
    605 
    606         int32_t expBase = exp; // save for later
    607         for (i = 0; i < UDAT_FIELD_COUNT; ++i, ++exp) {
    608             FieldPosition pos(i);
    609             buf.remove();
    610             df->format(aug13, buf, pos);
    611             UnicodeString field;
    612             buf.extractBetween(pos.getBeginIndex(), pos.getEndIndex(), field);
    613             assertEquals((UnicodeString)"field #" + i + " " + DATEFORMAT_FIELD_NAMES[i],
    614                          ctou(EXPECTED[exp]), field);
    615         }
    616 
    617         // test FieldPositionIterator API
    618         logln("FieldPositionIterator");
    619         {
    620           UErrorCode status = U_ZERO_ERROR;
    621           FieldPositionIterator posIter;
    622           FieldPosition fp;
    623 
    624           buf.remove();
    625           df->format(aug13, buf, &posIter, status);
    626           while (posIter.next(fp)) {
    627             int32_t i = fp.getField();
    628             UnicodeString field;
    629             buf.extractBetween(fp.getBeginIndex(), fp.getEndIndex(), field);
    630             assertEquals((UnicodeString)"field #" + i + " " + DATEFORMAT_FIELD_NAMES[i],
    631                          ctou(EXPECTED[expBase + i]), field);
    632           }
    633 
    634         }
    635     }
    636 
    637 
    638     // test null posIter
    639     buf.remove();
    640     UErrorCode status = U_ZERO_ERROR;
    641     dateFormats[0]->format(aug13, buf, NULL, status);
    642     // if we didn't crash, we succeeded.
    643 
    644     for (i=0; i<COUNT; ++i) {
    645         delete dateFormats[i];
    646     }
    647     delete PT;
    648 }
    649 
    650 // -------------------------------------
    651 
    652 /**
    653  * General parse/format tests.  Add test cases as needed.
    654  */
    655 void DateFormatTest::TestGeneral() {
    656     const char* DATA[] = {
    657         "yyyy MM dd HH:mm:ss.SSS",
    658 
    659         // Milliseconds are left-justified, since they format as fractions of a second
    660         "y/M/d H:mm:ss.S", "fp", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.5", "2004 03 10 16:36:31.500",
    661         "y/M/d H:mm:ss.SS", "fp", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.56", "2004 03 10 16:36:31.560",
    662         "y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567",
    663         "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",
    664     };
    665     expect(DATA, UPRV_LENGTHOF(DATA), Locale("en", "", ""));
    666 }
    667 
    668 // -------------------------------------
    669 
    670 /**
    671  * Verify that strings which contain incomplete specifications are parsed
    672  * correctly.  In some instances, this means not being parsed at all, and
    673  * returning an appropriate error.
    674  */
    675 void
    676 DateFormatTest::TestPartialParse994()
    677 {
    678     UErrorCode status = U_ZERO_ERROR;
    679     SimpleDateFormat* f = new SimpleDateFormat(status);
    680     if (U_FAILURE(status)) {
    681         dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
    682         delete f;
    683         return;
    684     }
    685     UDate null = 0;
    686     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:11:42", date(97, 1 - 1, 17, 10, 11, 42));
    687     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:", null);
    688     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10", null);
    689     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 ", null);
    690     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17", null);
    691     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
    692     delete f;
    693 }
    694 
    695 // -------------------------------------
    696 
    697 void
    698 DateFormatTest::tryPat994(SimpleDateFormat* format, const char* pat, const char* str, UDate expected)
    699 {
    700     UErrorCode status = U_ZERO_ERROR;
    701     UDate null = 0;
    702     logln(UnicodeString("Pattern \"") + pat + "\"   String \"" + str + "\"");
    703     //try {
    704         format->applyPattern(pat);
    705         UDate date = format->parse(str, status);
    706         if (U_FAILURE(status) || date == null)
    707         {
    708             logln((UnicodeString)"ParseException: " + (int32_t)status);
    709             if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
    710         }
    711         else
    712         {
    713             UnicodeString f;
    714             ((DateFormat*)format)->format(date, f);
    715             logln(UnicodeString(" parse(") + str + ") -> " + dateToString(date));
    716             logln((UnicodeString)" format -> " + f);
    717             if (expected == null ||
    718                 !(date == expected)) errln((UnicodeString)"FAIL: Expected null");//" + expected);
    719             if (!(f == str)) errln(UnicodeString("FAIL: Expected ") + str);
    720         }
    721     //}
    722     //catch(ParseException e) {
    723     //    logln((UnicodeString)"ParseException: " + e.getMessage());
    724     //    if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
    725     //}
    726     //catch(Exception e) {
    727     //    errln((UnicodeString)"*** Exception:");
    728     //    e.printStackTrace();
    729     //}
    730 }
    731 
    732 // -------------------------------------
    733 
    734 /**
    735  * Verify the behavior of patterns in which digits for different fields run together
    736  * without intervening separators.
    737  */
    738 void
    739 DateFormatTest::TestRunTogetherPattern985()
    740 {
    741     UErrorCode status = U_ZERO_ERROR;
    742     UnicodeString format("yyyyMMddHHmmssSSS");
    743     UnicodeString now, then;
    744     //UBool flag;
    745     SimpleDateFormat *formatter = new SimpleDateFormat(format, status);
    746     if (U_FAILURE(status)) {
    747         dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
    748         delete formatter;
    749         return;
    750     }
    751     UDate date1 = Calendar::getNow();
    752     ((DateFormat*)formatter)->format(date1, now);
    753     logln(now);
    754     ParsePosition pos(0);
    755     UDate date2 = formatter->parse(now, pos);
    756     if (date2 == 0) then = UnicodeString("Parse stopped at ") + pos.getIndex();
    757     else ((DateFormat*)formatter)->format(date2, then);
    758     logln(then);
    759     if (!(date2 == date1)) errln((UnicodeString)"FAIL");
    760     delete formatter;
    761     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
    762 }
    763 
    764 // -------------------------------------
    765 
    766 /**
    767  * Verify the behavior of patterns in which digits for different fields run together
    768  * without intervening separators.
    769  */
    770 void
    771 DateFormatTest::TestRunTogetherPattern917()
    772 {
    773     UErrorCode status = U_ZERO_ERROR;
    774     SimpleDateFormat* fmt;
    775     UnicodeString myDate;
    776     fmt = new SimpleDateFormat((UnicodeString)"yyyy/MM/dd", status);
    777     if (U_FAILURE(status)) {
    778         dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
    779         delete fmt;
    780         return;
    781     }
    782     myDate = "1997/02/03";
    783     testIt917(fmt, myDate, date(97, 2 - 1, 3));
    784     delete fmt;
    785     fmt = new SimpleDateFormat((UnicodeString)"yyyyMMdd", status);
    786     myDate = "19970304";
    787     testIt917(fmt, myDate, date(97, 3 - 1, 4));
    788     delete fmt;
    789     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
    790 }
    791 
    792 // -------------------------------------
    793 
    794 void
    795 DateFormatTest::testIt917(SimpleDateFormat* fmt, UnicodeString& str, UDate expected)
    796 {
    797     UErrorCode status = U_ZERO_ERROR;
    798     UnicodeString pattern;
    799     logln((UnicodeString)"pattern=" + fmt->toPattern(pattern) + "   string=" + str);
    800     Formattable o;
    801     //try {
    802         ((Format*)fmt)->parseObject(str, o, status);
    803     //}
    804     if (U_FAILURE(status)) return;
    805     //catch(ParseException e) {
    806     //    e.printStackTrace();
    807     //    return;
    808     //}
    809     logln((UnicodeString)"Parsed object: " + dateToString(o.getDate()));
    810     if (!(o.getDate() == expected)) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
    811     UnicodeString formatted; ((Format*)fmt)->format(o, formatted, status);
    812     logln((UnicodeString)"Formatted string: " + formatted);
    813     if (!(formatted == str)) errln((UnicodeString)"FAIL: Expected " + str);
    814     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
    815 }
    816 
    817 // -------------------------------------
    818 
    819 /**
    820  * Verify the handling of Czech June and July, which have the unique attribute that
    821  * one is a proper prefix substring of the other.
    822  */
    823 void
    824 DateFormatTest::TestCzechMonths459()
    825 {
    826     UErrorCode status = U_ZERO_ERROR;
    827     DateFormat* fmt = DateFormat::createDateInstance(DateFormat::FULL, Locale("cs", "", ""));
    828     if (fmt == NULL){
    829         dataerrln("Error calling DateFormat::createDateInstance()");
    830         return;
    831     }
    832 
    833     UnicodeString pattern;
    834     logln((UnicodeString)"Pattern " + ((SimpleDateFormat*) fmt)->toPattern(pattern));
    835     UDate june = date(97, UCAL_JUNE, 15);
    836     UDate july = date(97, UCAL_JULY, 15);
    837     UnicodeString juneStr; fmt->format(june, juneStr);
    838     UnicodeString julyStr; fmt->format(july, julyStr);
    839     //try {
    840         logln((UnicodeString)"format(June 15 1997) = " + juneStr);
    841         UDate d = fmt->parse(juneStr, status);
    842         UnicodeString s; fmt->format(d, s);
    843         int32_t month,yr,day,hr,min,sec; dateToFields(d,yr,month,day,hr,min,sec);
    844         logln((UnicodeString)"  -> parse -> " + s + " (month = " + month + ")");
    845         if (month != UCAL_JUNE) errln((UnicodeString)"FAIL: Month should be June");
    846         logln((UnicodeString)"format(July 15 1997) = " + julyStr);
    847         d = fmt->parse(julyStr, status);
    848         fmt->format(d, s);
    849         dateToFields(d,yr,month,day,hr,min,sec);
    850         logln((UnicodeString)"  -> parse -> " + s + " (month = " + month + ")");
    851         if (month != UCAL_JULY) errln((UnicodeString)"FAIL: Month should be July");
    852     //}
    853     //catch(ParseException e) {
    854     if (U_FAILURE(status))
    855         errln((UnicodeString)"Exception: " + (int32_t)status);
    856     //}
    857     delete fmt;
    858 }
    859 
    860 // -------------------------------------
    861 
    862 /**
    863  * Test the handling of 'D' in patterns.
    864  */
    865 void
    866 DateFormatTest::TestLetterDPattern212()
    867 {
    868     UErrorCode status = U_ZERO_ERROR;
    869     UnicodeString dateString("1995-040.05:01:29");
    870     UnicodeString bigD("yyyy-DDD.hh:mm:ss");
    871     UnicodeString littleD("yyyy-ddd.hh:mm:ss");
    872     UDate expLittleD = date(95, 0, 1, 5, 1, 29);
    873     UDate expBigD = expLittleD + 39 * 24 * 3600000.0;
    874     expLittleD = expBigD; // Expect the same, with default lenient parsing
    875     logln((UnicodeString)"dateString= " + dateString);
    876     SimpleDateFormat *formatter = new SimpleDateFormat(bigD, status);
    877     if (U_FAILURE(status)) {
    878         dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
    879         delete formatter;
    880         return;
    881     }
    882     ParsePosition pos(0);
    883     UDate myDate = formatter->parse(dateString, pos);
    884     logln((UnicodeString)"Using " + bigD + " -> " + myDate);
    885     if (myDate != expBigD) errln((UnicodeString)"FAIL: bigD - Expected " + dateToString(expBigD));
    886     delete formatter;
    887     formatter = new SimpleDateFormat(littleD, status);
    888     ASSERT_OK(status);
    889     pos = ParsePosition(0);
    890     myDate = formatter->parse(dateString, pos);
    891     logln((UnicodeString)"Using " + littleD + " -> " + dateToString(myDate));
    892     if (myDate != expLittleD) errln((UnicodeString)"FAIL: littleD - Expected " + dateToString(expLittleD));
    893     delete formatter;
    894     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
    895 }
    896 
    897 // -------------------------------------
    898 
    899 /**
    900  * Test the day of year pattern.
    901  */
    902 void
    903 DateFormatTest::TestDayOfYearPattern195()
    904 {
    905     UErrorCode status = U_ZERO_ERROR;
    906     UDate today = Calendar::getNow();
    907     int32_t year,month,day,hour,min,sec; dateToFields(today,year,month,day,hour,min,sec);
    908     UDate expected = date(year, month, day);
    909     logln((UnicodeString)"Test Date: " + dateToString(today));
    910     SimpleDateFormat* sdf = (SimpleDateFormat*)DateFormat::createDateInstance();
    911     if (sdf == NULL){
    912         dataerrln("Error calling DateFormat::createDateInstance()");
    913         return;
    914     }
    915     tryPattern(*sdf, today, 0, expected);
    916     tryPattern(*sdf, today, "G yyyy DDD", expected);
    917     delete sdf;
    918     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
    919 }
    920 
    921 // -------------------------------------
    922 
    923 void
    924 DateFormatTest::tryPattern(SimpleDateFormat& sdf, UDate d, const char* pattern, UDate expected)
    925 {
    926     UErrorCode status = U_ZERO_ERROR;
    927     if (pattern != 0) sdf.applyPattern(pattern);
    928     UnicodeString thePat;
    929     logln((UnicodeString)"pattern: " + sdf.toPattern(thePat));
    930     UnicodeString formatResult; (*(DateFormat*)&sdf).format(d, formatResult);
    931     logln((UnicodeString)" format -> " + formatResult);
    932     // try {
    933         UDate d2 = sdf.parse(formatResult, status);
    934         logln((UnicodeString)" parse(" + formatResult + ") -> " + dateToString(d2));
    935         if (d2 != expected) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
    936         UnicodeString format2; (*(DateFormat*)&sdf).format(d2, format2);
    937         logln((UnicodeString)" format -> " + format2);
    938         if (!(formatResult == format2)) errln((UnicodeString)"FAIL: Round trip drift");
    939     //}
    940     //catch(Exception e) {
    941     if (U_FAILURE(status))
    942         errln((UnicodeString)"Error: " + (int32_t)status);
    943     //}
    944 }
    945 
    946 // -------------------------------------
    947 
    948 /**
    949  * Test the handling of single quotes in patterns.
    950  */
    951 void
    952 DateFormatTest::TestQuotePattern161()
    953 {
    954     UErrorCode status = U_ZERO_ERROR;
    955     SimpleDateFormat* formatter = new SimpleDateFormat((UnicodeString)"MM/dd/yyyy 'at' hh:mm:ss a zzz", status);
    956     if (U_FAILURE(status)) {
    957         dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
    958         delete formatter;
    959         return;
    960     }
    961     UDate currentTime_1 = date(97, UCAL_AUGUST, 13, 10, 42, 28);
    962     UnicodeString dateString; ((DateFormat*)formatter)->format(currentTime_1, dateString);
    963     UnicodeString exp("08/13/1997 at 10:42:28 AM ");
    964     logln((UnicodeString)"format(" + dateToString(currentTime_1) + ") = " + dateString);
    965     if (0 != dateString.compareBetween(0, exp.length(), exp, 0, exp.length())) errln((UnicodeString)"FAIL: Expected " + exp);
    966     delete formatter;
    967     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
    968 }
    969 
    970 // -------------------------------------
    971 
    972 /**
    973  * Verify the correct behavior when handling invalid input strings.
    974  */
    975 void
    976 DateFormatTest::TestBadInput135()
    977 {
    978     UErrorCode status = U_ZERO_ERROR;
    979     DateFormat::EStyle looks[] = {
    980         DateFormat::SHORT, DateFormat::MEDIUM, DateFormat::LONG, DateFormat::FULL
    981     };
    982     int32_t looks_length = UPRV_LENGTHOF(looks);
    983     const char* strings[] = {
    984         "Mar 15", "Mar 15 1997", "asdf", "3/1/97 1:23:", "3/1/00 1:23:45 AM"
    985     };
    986     int32_t strings_length = UPRV_LENGTHOF(strings);
    987     DateFormat *full = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::LONG);
    988     if(full==NULL) {
    989       dataerrln("could not create date time instance");
    990       return;
    991     }
    992     UnicodeString expected("March 1, 2000 at 1:23:45 AM ");
    993     for (int32_t i = 0; i < strings_length;++i) {
    994         const char* text = strings[i];
    995         for (int32_t j = 0; j < looks_length;++j) {
    996             DateFormat::EStyle dateLook = looks[j];
    997             for (int32_t k = 0; k < looks_length;++k) {
    998                 DateFormat::EStyle timeLook = looks[k];
    999                 DateFormat *df = DateFormat::createDateTimeInstance(dateLook, timeLook);
   1000                 if (df == NULL){
   1001                     dataerrln("Error calling DateFormat::createDateTimeInstance()");
   1002                     continue;
   1003                 }
   1004                 UnicodeString prefix = UnicodeString(text) + ", " + dateLook + "/" + timeLook + ": ";
   1005                 //try {
   1006                     UDate when = df->parse(text, status);
   1007                     if (when == 0 && U_SUCCESS(status)) {
   1008                         errln(prefix + "SHOULD NOT HAPPEN: parse returned 0.");
   1009                         continue;
   1010                     }
   1011                     if (U_SUCCESS(status))
   1012                     {
   1013                         UnicodeString format;
   1014                         UnicodeString pattern;
   1015                         SimpleDateFormat* sdtfmt = dynamic_cast<SimpleDateFormat*>(df);
   1016                         if (sdtfmt != NULL) {
   1017                             sdtfmt->toPattern(pattern);
   1018                         }
   1019                         full->format(when, format);
   1020                         logln(prefix + "OK: " + format);
   1021                         if (0!=format.compareBetween(0, expected.length(), expected, 0, expected.length()))
   1022                             errln((UnicodeString)"FAIL: Parse \"" + text + "\", pattern \"" + pattern + "\", expected " + expected + " got " + format);
   1023                     }
   1024                 //}
   1025                 //catch(ParseException e) {
   1026                     else
   1027                         status = U_ZERO_ERROR;
   1028                 //}
   1029                 //catch(StringIndexOutOfBoundsException e) {
   1030                 //    errln(prefix + "SHOULD NOT HAPPEN: " + (int)status);
   1031                 //}
   1032                 delete df;
   1033             }
   1034         }
   1035     }
   1036     delete full;
   1037     if (U_FAILURE(status))
   1038         errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
   1039 }
   1040 
   1041 static const char* const parseFormats[] = {
   1042     "MMMM d, yyyy",
   1043     "MMMM d yyyy",
   1044     "M/d/yy",
   1045     "d MMMM, yyyy",
   1046     "d MMMM yyyy",
   1047     "d MMMM",
   1048     "MMMM d",
   1049     "yyyy",
   1050     "h:mm a MMMM d, yyyy"
   1051 };
   1052 
   1053 #if 0
   1054 // strict inputStrings
   1055 static const char* const inputStrings[] = {
   1056     "bogus string", 0, 0, 0, 0, 0, 0, 0, 0, 0,
   1057     "April 1, 1997", "April 1, 1997", 0, 0, 0, 0, 0, "April 1", 0, 0,
   1058     "Jan 1, 1970", "January 1, 1970", 0, 0, 0, 0, 0, "January 1", 0, 0,
   1059     "Jan 1 2037", 0, "January 1 2037", 0, 0, 0, 0, "January 1", 0, 0,
   1060     "1/1/70", 0, 0, "1/1/70", 0, 0, 0, 0, "0001", 0,
   1061     "5 May 1997", 0, 0, 0, 0, "5 May 1997", "5 May", 0, "0005", 0,
   1062     "16 May", 0, 0, 0, 0, 0, "16 May", 0, "0016", 0,
   1063     "April 30", 0, 0, 0, 0, 0, 0, "April 30", 0, 0,
   1064     "1998", 0, 0, 0, 0, 0, 0, 0, "1998", 0,
   1065     "1", 0, 0, 0, 0, 0, 0, 0, "0001", 0,
   1066     "3:00 pm Jan 1, 1997", 0, 0, 0, 0, 0, 0, 0, "0003", "3:00 PM January 1, 1997",
   1067 };
   1068 #else
   1069 // lenient inputStrings
   1070 static const char* const inputStrings[] = {
   1071     "bogus string", 0, 0, 0, 0, 0, 0, 0, 0, 0,
   1072     "April 1, 1997", "April 1, 1997", "April 1 1997", "4/1/97", 0, 0, 0, "April 1", 0, 0,
   1073     "Jan 1, 1970", "January 1, 1970", "January 1 1970", "1/1/70", 0, 0, 0, "January 1", 0, 0,
   1074     "Jan 1 2037", "January 1, 2037", "January 1 2037", "1/1/37", 0, 0, 0, "January 1", 0, 0,
   1075     "1/1/70", "January 1, 0070", "January 1 0070", "1/1/70", "1 January, 0070", "1 January 0070", "1 January", "January 1", "0001", 0,
   1076     "5 May 1997", 0, 0, 0, "5 May, 1997", "5 May 1997", "5 May", 0, "0005", 0,
   1077     "16 May", 0, 0, 0, 0, 0, "16 May", 0, "0016", 0,
   1078     "April 30", 0, 0, 0, 0, 0, 0, "April 30", 0, 0,
   1079     "1998", 0, 0, 0, 0, 0, 0, 0, "1998", 0,
   1080     "1", 0, 0, 0, 0, 0, 0, 0, "0001", 0,
   1081     "3:00 pm Jan 1, 1997", 0, 0, 0, 0, 0, 0, 0, "0003", "3:00 PM January 1, 1997",
   1082 };
   1083 #endif
   1084 
   1085 // -------------------------------------
   1086 
   1087 /**
   1088  * Verify the correct behavior when parsing an array of inputs against an
   1089  * array of patterns, with known results.  The results are encoded after
   1090  * the input strings in each row.
   1091  */
   1092 void
   1093 DateFormatTest::TestBadInput135a()
   1094 {
   1095   UErrorCode status = U_ZERO_ERROR;
   1096   SimpleDateFormat* dateParse = new SimpleDateFormat(status);
   1097   if(U_FAILURE(status)) {
   1098     dataerrln("Failed creating SimpleDateFormat with %s. Quitting test", u_errorName(status));
   1099     delete dateParse;
   1100     return;
   1101   }
   1102   const char* s;
   1103   UDate date;
   1104   const uint32_t PF_LENGTH = UPRV_LENGTHOF(parseFormats);
   1105   const uint32_t INPUT_LENGTH = UPRV_LENGTHOF(inputStrings);
   1106 
   1107   dateParse->applyPattern("d MMMM, yyyy");
   1108   dateParse->adoptTimeZone(TimeZone::createDefault());
   1109   s = "not parseable";
   1110   UnicodeString thePat;
   1111   logln(UnicodeString("Trying to parse \"") + s + "\" with " + dateParse->toPattern(thePat));
   1112   //try {
   1113   date = dateParse->parse(s, status);
   1114   if (U_SUCCESS(status))
   1115     errln((UnicodeString)"FAIL: Expected exception during parse");
   1116   //}
   1117   //catch(Exception ex) {
   1118   else
   1119     logln((UnicodeString)"Exception during parse: " + (int32_t)status);
   1120   status = U_ZERO_ERROR;
   1121   //}
   1122   for (uint32_t i = 0; i < INPUT_LENGTH; i += (PF_LENGTH + 1)) {
   1123     ParsePosition parsePosition(0);
   1124     UnicodeString s( inputStrings[i]);
   1125     for (uint32_t index = 0; index < PF_LENGTH;++index) {
   1126       const char* expected = inputStrings[i + 1 + index];
   1127       dateParse->applyPattern(parseFormats[index]);
   1128       dateParse->adoptTimeZone(TimeZone::createDefault());
   1129       //try {
   1130       parsePosition.setIndex(0);
   1131       date = dateParse->parse(s, parsePosition);
   1132       if (parsePosition.getIndex() != 0) {
   1133         UnicodeString s1, s2;
   1134         s.extract(0, parsePosition.getIndex(), s1);
   1135         s.extract(parsePosition.getIndex(), s.length(), s2);
   1136         if (date == 0) {
   1137           errln((UnicodeString)"ERROR: null result fmt=\"" +
   1138                      parseFormats[index] +
   1139                      "\" pos=" + parsePosition.getIndex() + " " +
   1140                      s1 + "|" + s2);
   1141         }
   1142         else {
   1143           UnicodeString result;
   1144           ((DateFormat*)dateParse)->format(date, result);
   1145           logln((UnicodeString)"Parsed \"" + s + "\" using \"" + dateParse->toPattern(thePat) + "\" to: " + result);
   1146           if (expected == 0)
   1147             errln((UnicodeString)"FAIL: Expected parse failure, got " + result);
   1148           else if (!(result == expected))
   1149             errln(UnicodeString("FAIL: Parse \"") + s + UnicodeString("\", expected ") + expected + UnicodeString(", got ") + result);
   1150         }
   1151       }
   1152       else if (expected != 0) {
   1153         errln(UnicodeString("FAIL: Expected ") + expected + " from \"" +
   1154                      s + "\" with \"" + dateParse->toPattern(thePat) + "\"");
   1155       }
   1156       //}
   1157       //catch(Exception ex) {
   1158       if (U_FAILURE(status))
   1159         errln((UnicodeString)"An exception was thrown during parse: " + (int32_t)status);
   1160       //}
   1161     }
   1162   }
   1163   delete dateParse;
   1164   if (U_FAILURE(status))
   1165     errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
   1166 }
   1167 
   1168 // -------------------------------------
   1169 
   1170 /**
   1171  * Test the parsing of two-digit years.
   1172  */
   1173 void
   1174 DateFormatTest::TestTwoDigitYear()
   1175 {
   1176     UErrorCode ec = U_ZERO_ERROR;
   1177     SimpleDateFormat fmt("dd/MM/yy", Locale::getUK(), ec);
   1178     if (U_FAILURE(ec)) {
   1179         dataerrln("FAIL: SimpleDateFormat constructor - %s", u_errorName(ec));
   1180         return;
   1181     }
   1182     parse2DigitYear(fmt, "5/6/30", date(130, UCAL_JUNE, 5));
   1183     parse2DigitYear(fmt, "4/6/50", date(50, UCAL_JUNE, 4));
   1184 }
   1185 
   1186 // -------------------------------------
   1187 
   1188 void
   1189 DateFormatTest::parse2DigitYear(DateFormat& fmt, const char* str, UDate expected)
   1190 {
   1191     UErrorCode status = U_ZERO_ERROR;
   1192     //try {
   1193         UDate d = fmt.parse(str, status);
   1194         UnicodeString thePat;
   1195         logln(UnicodeString("Parsing \"") + str + "\" with " + ((SimpleDateFormat*)&fmt)->toPattern(thePat) +
   1196             "  => " + dateToString(d));
   1197         if (d != expected) errln((UnicodeString)"FAIL: Expected " + expected);
   1198     //}
   1199     //catch(ParseException e) {
   1200         if (U_FAILURE(status))
   1201         errln((UnicodeString)"FAIL: Got exception");
   1202     //}
   1203 }
   1204 
   1205 // -------------------------------------
   1206 
   1207 /**
   1208  * Test the formatting of time zones.
   1209  */
   1210 void
   1211 DateFormatTest::TestDateFormatZone061()
   1212 {
   1213     UErrorCode status = U_ZERO_ERROR;
   1214     UDate date;
   1215     DateFormat *formatter;
   1216     date= 859248000000.0;
   1217     logln((UnicodeString)"Date 1997/3/25 00:00 GMT: " + date);
   1218     formatter = new SimpleDateFormat((UnicodeString)"dd-MMM-yyyyy HH:mm", Locale::getUK(), status);
   1219     if(U_FAILURE(status)) {
   1220       dataerrln("Failed creating SimpleDateFormat with %s. Quitting test", u_errorName(status));
   1221       delete formatter;
   1222       return;
   1223     }
   1224     formatter->adoptTimeZone(TimeZone::createTimeZone("GMT"));
   1225     UnicodeString temp; formatter->format(date, temp);
   1226     logln((UnicodeString)"Formatted in GMT to: " + temp);
   1227     //try {
   1228         UDate tempDate = formatter->parse(temp, status);
   1229         logln((UnicodeString)"Parsed to: " + dateToString(tempDate));
   1230         if (tempDate != date) errln((UnicodeString)"FAIL: Expected " + dateToString(date));
   1231     //}
   1232     //catch(Throwable t) {
   1233     if (U_FAILURE(status))
   1234         errln((UnicodeString)"Date Formatter throws: " + (int32_t)status);
   1235     //}
   1236     delete formatter;
   1237 }
   1238 
   1239 // -------------------------------------
   1240 
   1241 /**
   1242  * Test the formatting of time zones.
   1243  */
   1244 void
   1245 DateFormatTest::TestDateFormatZone146()
   1246 {
   1247     TimeZone *saveDefault = TimeZone::createDefault();
   1248 
   1249         //try {
   1250     TimeZone *thedefault = TimeZone::createTimeZone("GMT");
   1251     TimeZone::setDefault(*thedefault);
   1252             // java.util.Locale.setDefault(new java.util.Locale("ar", "", ""));
   1253 
   1254             // check to be sure... its GMT all right
   1255         TimeZone *testdefault = TimeZone::createDefault();
   1256         UnicodeString testtimezone;
   1257         testdefault->getID(testtimezone);
   1258         if (testtimezone == "GMT")
   1259             logln("Test timezone = " + testtimezone);
   1260         else
   1261             dataerrln("Test timezone should be GMT, not " + testtimezone);
   1262 
   1263         UErrorCode status = U_ZERO_ERROR;
   1264         // now try to use the default GMT time zone
   1265         GregorianCalendar *greenwichcalendar =
   1266             new GregorianCalendar(1997, 3, 4, 23, 0, status);
   1267         if (U_FAILURE(status)) {
   1268             dataerrln("Fail new GregorianCalendar: %s", u_errorName(status));
   1269         } else {
   1270             //*****************************greenwichcalendar.setTimeZone(TimeZone.getDefault());
   1271             //greenwichcalendar.set(1997, 3, 4, 23, 0);
   1272             // try anything to set hour to 23:00 !!!
   1273             greenwichcalendar->set(UCAL_HOUR_OF_DAY, 23);
   1274             // get time
   1275             UDate greenwichdate = greenwichcalendar->getTime(status);
   1276             // format every way
   1277             UnicodeString DATA [] = {
   1278                 UnicodeString("simple format:  "), UnicodeString("04/04/97 23:00 GMT"),
   1279                     UnicodeString("MM/dd/yy HH:mm z"),
   1280                 UnicodeString("full format:    "), UnicodeString("Friday, April 4, 1997 11:00:00 o'clock PM GMT"),
   1281                     UnicodeString("EEEE, MMMM d, yyyy h:mm:ss 'o''clock' a z"),
   1282                 UnicodeString("long format:    "), UnicodeString("April 4, 1997 11:00:00 PM GMT"),
   1283                     UnicodeString("MMMM d, yyyy h:mm:ss a z"),
   1284                 UnicodeString("default format: "), UnicodeString("04-Apr-97 11:00:00 PM"),
   1285                     UnicodeString("dd-MMM-yy h:mm:ss a"),
   1286                 UnicodeString("short format:   "), UnicodeString("4/4/97 11:00 PM"),
   1287                     UnicodeString("M/d/yy h:mm a")
   1288             };
   1289             int32_t DATA_length = UPRV_LENGTHOF(DATA);
   1290 
   1291             for (int32_t i=0; i<DATA_length; i+=3) {
   1292                 DateFormat *fmt = new SimpleDateFormat(DATA[i+2], Locale::getEnglish(), status);
   1293                 if (U_FAILURE(status)) {
   1294                     dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
   1295                     break;
   1296                 }
   1297                 fmt->setCalendar(*greenwichcalendar);
   1298                 UnicodeString result;
   1299                 result = fmt->format(greenwichdate, result);
   1300                 logln(DATA[i] + result);
   1301                 if (result != DATA[i+1])
   1302                     errln("FAIL: Expected " + DATA[i+1] + ", got " + result);
   1303                 delete fmt;
   1304             }
   1305         }
   1306     //}
   1307     //finally {
   1308         TimeZone::adoptDefault(saveDefault);
   1309     //}
   1310         delete testdefault;
   1311         delete greenwichcalendar;
   1312         delete thedefault;
   1313 
   1314 
   1315 }
   1316 
   1317 // -------------------------------------
   1318 
   1319 /**
   1320  * Test the formatting of dates in different locales.
   1321  */
   1322 void
   1323 DateFormatTest::TestLocaleDateFormat() // Bug 495
   1324 {
   1325     UDate testDate = date(97, UCAL_SEPTEMBER, 15);
   1326     DateFormat *dfFrench = DateFormat::createDateTimeInstance(DateFormat::FULL,
   1327         DateFormat::FULL, Locale::getFrench());
   1328     DateFormat *dfUS = DateFormat::createDateTimeInstance(DateFormat::FULL,
   1329         DateFormat::FULL, Locale::getUS());
   1330     UnicodeString expectedFRENCH ( "lundi 15 septembre 1997 \\u00E0 00:00:00 heure d\\u2019\\u00E9t\\u00E9 du Pacifique", -1, US_INV );
   1331     expectedFRENCH = expectedFRENCH.unescape();
   1332     UnicodeString expectedUS ( "Monday, September 15, 1997 at 12:00:00 AM Pacific Daylight Time" );
   1333     logln((UnicodeString)"Date set to : " + dateToString(testDate));
   1334     UnicodeString out;
   1335     if (dfUS == NULL || dfFrench == NULL){
   1336         dataerrln("Error calling DateFormat::createDateTimeInstance)");
   1337         delete dfUS;
   1338         delete dfFrench;
   1339         return;
   1340     }
   1341 
   1342     dfFrench->format(testDate, out);
   1343     logln((UnicodeString)"Date Formated with French Locale " + out);
   1344     if (!(out == expectedFRENCH))
   1345         errln((UnicodeString)"FAIL: Expected " + expectedFRENCH);
   1346     out.truncate(0);
   1347     dfUS->format(testDate, out);
   1348     logln((UnicodeString)"Date Formated with US Locale " + out);
   1349     if (!(out == expectedUS))
   1350         errln((UnicodeString)"FAIL: Expected " + expectedUS);
   1351     delete dfUS;
   1352     delete dfFrench;
   1353 }
   1354 
   1355 void
   1356 DateFormatTest::TestFormattingLocaleTimeSeparator()
   1357 {
   1358     // This test not as useful is it once was, since timeSeparator
   1359     // in the Arabic is changed back to ":" in CLDR 28.
   1360     const UDate testDate = 874266720000.;  // Sun Sep 14 21:52:00 CET 1997
   1361     logln((UnicodeString)"Date set to : " + dateToString(testDate));
   1362 
   1363     const LocalPointer<const TimeZone> tz(TimeZone::createTimeZone("CET"));
   1364 
   1365     const LocalPointer<DateFormat> dfArab(DateFormat::createTimeInstance(
   1366             DateFormat::SHORT, Locale("ar")));
   1367 
   1368     const LocalPointer<DateFormat> dfLatn(DateFormat::createTimeInstance(
   1369             DateFormat::SHORT, Locale("ar", NULL, NULL, "numbers=latn")));
   1370 
   1371     if (dfLatn.isNull() || dfArab.isNull()) {
   1372         dataerrln("Error calling DateFormat::createTimeInstance()");
   1373         return;
   1374     }
   1375 
   1376     dfArab->setTimeZone(*tz);
   1377     dfLatn->setTimeZone(*tz);
   1378 
   1379     const UnicodeString expectedArab = UnicodeString(
   1380             "\\u0669:\\u0665\\u0662 \\u0645", -1, US_INV).unescape();
   1381 
   1382     const UnicodeString expectedLatn = UnicodeString(
   1383             "9:52 \\u0645", -1, US_INV).unescape();
   1384 
   1385     UnicodeString actualArab;
   1386     UnicodeString actualLatn;
   1387 
   1388     dfArab->format(testDate, actualArab);
   1389     dfLatn->format(testDate, actualLatn);
   1390 
   1391     assertEquals("Arab", expectedArab, actualArab);
   1392     assertEquals("Latn", expectedLatn, actualLatn);
   1393 }
   1394 
   1395 /**
   1396  * Test DateFormat(Calendar) API
   1397  */
   1398 void DateFormatTest::TestDateFormatCalendar() {
   1399     DateFormat *date=0, *time=0, *full=0;
   1400     Calendar *cal=0;
   1401     UnicodeString str;
   1402     ParsePosition pos;
   1403     UDate when;
   1404     UErrorCode ec = U_ZERO_ERROR;
   1405 
   1406     /* Create a formatter for date fields. */
   1407     date = DateFormat::createDateInstance(DateFormat::kShort, Locale::getUS());
   1408     if (date == NULL) {
   1409         dataerrln("FAIL: createDateInstance failed");
   1410         goto FAIL;
   1411     }
   1412 
   1413     /* Create a formatter for time fields. */
   1414     time = DateFormat::createTimeInstance(DateFormat::kShort, Locale::getUS());
   1415     if (time == NULL) {
   1416         errln("FAIL: createTimeInstance failed");
   1417         goto FAIL;
   1418     }
   1419 
   1420     /* Create a full format for output */
   1421     full = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull,
   1422                                               Locale::getUS());
   1423     if (full == NULL) {
   1424         errln("FAIL: createInstance failed");
   1425         goto FAIL;
   1426     }
   1427 
   1428     /* Create a calendar */
   1429     cal = Calendar::createInstance(Locale::getUS(), ec);
   1430     if (cal == NULL || U_FAILURE(ec)) {
   1431         errln((UnicodeString)"FAIL: Calendar::createInstance failed with " +
   1432               u_errorName(ec));
   1433         goto FAIL;
   1434     }
   1435 
   1436     /* Parse the date */
   1437     cal->clear();
   1438     str = UnicodeString("4/5/2001", "");
   1439     pos.setIndex(0);
   1440     date->parse(str, *cal, pos);
   1441     if (pos.getIndex() != str.length()) {
   1442         errln((UnicodeString)"FAIL: DateFormat::parse(4/5/2001) failed at " +
   1443               pos.getIndex());
   1444         goto FAIL;
   1445     }
   1446 
   1447     /* Parse the time */
   1448     str = UnicodeString("5:45 PM", "");
   1449     pos.setIndex(0);
   1450     time->parse(str, *cal, pos);
   1451     if (pos.getIndex() != str.length()) {
   1452         errln((UnicodeString)"FAIL: DateFormat::parse(17:45) failed at " +
   1453               pos.getIndex());
   1454         goto FAIL;
   1455     }
   1456 
   1457     /* Check result */
   1458     when = cal->getTime(ec);
   1459     if (U_FAILURE(ec)) {
   1460         errln((UnicodeString)"FAIL: cal->getTime() failed with " + u_errorName(ec));
   1461         goto FAIL;
   1462     }
   1463     str.truncate(0);
   1464     full->format(when, str);
   1465     // Thursday, April 5, 2001 5:45:00 PM PDT 986517900000
   1466     if (when == 986517900000.0) {
   1467         logln("Ok: Parsed result: " + str);
   1468     } else {
   1469         errln("FAIL: Parsed result: " + str + ", exp 4/5/2001 5:45 PM");
   1470     }
   1471 
   1472  FAIL:
   1473     delete date;
   1474     delete time;
   1475     delete full;
   1476     delete cal;
   1477 }
   1478 
   1479 /**
   1480  * Test DateFormat's parsing of space characters.  See jitterbug 1916.
   1481  */
   1482 void DateFormatTest::TestSpaceParsing() {
   1483     const char* DATA[] = {
   1484         "yyyy MM dd HH:mm:ss",
   1485 
   1486         // pattern, input, expected parse or NULL if expect parse failure
   1487         "MMMM d yy", " 04 05 06",  "2006 04 05 00:00:00",
   1488         NULL,        "04 05 06",   "2006 04 05 00:00:00",
   1489 
   1490         "MM d yy",   " 04 05 06",    "2006 04 05 00:00:00",
   1491         NULL,        "04 05 06",     "2006 04 05 00:00:00",
   1492         NULL,        "04/05/06",     "2006 04 05 00:00:00",
   1493         NULL,        "04-05-06",     "2006 04 05 00:00:00",
   1494         NULL,        "04.05.06",     "2006 04 05 00:00:00",
   1495         NULL,        "04 / 05 / 06", "2006 04 05 00:00:00",
   1496         NULL,        "Apr / 05/ 06", "2006 04 05 00:00:00",
   1497         NULL,        "Apr-05-06",    "2006 04 05 00:00:00",
   1498         NULL,        "Apr 05, 2006", "2006 04 05 00:00:00",
   1499 
   1500         "MMMM d yy", " Apr 05 06", "2006 04 05 00:00:00",
   1501         NULL,        "Apr 05 06",  "2006 04 05 00:00:00",
   1502         NULL,        "Apr05 06",   "2006 04 05 00:00:00",
   1503 
   1504         "hh:mm:ss a", "12:34:56 PM", "1970 01 01 12:34:56",
   1505         NULL,         "12:34:56PM",  "1970 01 01 12:34:56",
   1506         NULL,         "12.34.56PM",  "1970 01 01 12:34:56",
   1507         NULL,         "12 : 34 : 56  PM", "1970 01 01 12:34:56",
   1508 
   1509         "MM d yy 'at' hh:mm:ss a", "04/05/06 12:34:56 PM", "2006 04 05 12:34:56",
   1510 
   1511         "MMMM dd yyyy hh:mm a", "September 27, 1964 21:56 PM", "1964 09 28 09:56:00",
   1512         NULL,                   "November 4, 2008 0:13 AM",    "2008 11 04 00:13:00",
   1513 
   1514         "HH'h'mm'min'ss's'", "12h34min56s", "1970 01 01 12:34:56",
   1515         NULL,                "12h34mi56s",  "1970 01 01 12:34:56",
   1516         NULL,                "12h34m56s",   "1970 01 01 12:34:56",
   1517         NULL,                "12:34:56",    "1970 01 01 12:34:56"
   1518     };
   1519     const int32_t DATA_len = UPRV_LENGTHOF(DATA);
   1520 
   1521     expectParse(DATA, DATA_len, Locale("en"));
   1522 }
   1523 
   1524 /**
   1525  * Test handling of "HHmmss" pattern.
   1526  */
   1527 void DateFormatTest::TestExactCountFormat() {
   1528     const char* DATA[] = {
   1529         "yyyy MM dd HH:mm:ss",
   1530 
   1531         // pattern, input, expected parse or NULL if expect parse failure
   1532         "HHmmss", "123456", "1970 01 01 12:34:56",
   1533         NULL,     "12345",  "1970 01 01 01:23:45",
   1534         NULL,     "1234",   NULL,
   1535         NULL,     "00-05",  NULL,
   1536         NULL,     "12-34",  NULL,
   1537         NULL,     "00+05",  NULL,
   1538         "ahhmm",  "PM730",  "1970 01 01 19:30:00",
   1539     };
   1540     const int32_t DATA_len = UPRV_LENGTHOF(DATA);
   1541 
   1542     expectParse(DATA, DATA_len, Locale("en"));
   1543 }
   1544 
   1545 /**
   1546  * Test handling of white space.
   1547  */
   1548 void DateFormatTest::TestWhiteSpaceParsing() {
   1549     const char* DATA[] = {
   1550         "yyyy MM dd",
   1551 
   1552         // pattern, input, expected parse or null if expect parse failure
   1553 
   1554         // Pattern space run should parse input text space run
   1555         "MM   d yy",   " 04 01 03",    "2003 04 01",
   1556         NULL,          " 04  01   03 ", "2003 04 01",
   1557     };
   1558     const int32_t DATA_len = UPRV_LENGTHOF(DATA);
   1559 
   1560     expectParse(DATA, DATA_len, Locale("en"));
   1561 }
   1562 
   1563 
   1564 void DateFormatTest::TestInvalidPattern() {
   1565     UErrorCode ec = U_ZERO_ERROR;
   1566     SimpleDateFormat f(UnicodeString("Yesterday"), ec);
   1567     if (U_FAILURE(ec)) {
   1568         dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(ec));
   1569         return;
   1570     }
   1571     UnicodeString out;
   1572     FieldPosition pos;
   1573     f.format((UDate)0, out, pos);
   1574     logln(out);
   1575     // The bug is that the call to format() will crash.  By not
   1576     // crashing, the test passes.
   1577 }
   1578 
   1579 void DateFormatTest::TestGreekMay() {
   1580     UErrorCode ec = U_ZERO_ERROR;
   1581     UDate date = -9896080848000.0;
   1582     SimpleDateFormat fmt("EEEE, dd MMMM yyyy h:mm:ss a", Locale("el", "", ""), ec);
   1583     if (U_FAILURE(ec)) {
   1584         dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(ec));
   1585         return;
   1586     }
   1587     UnicodeString str;
   1588     fmt.format(date, str);
   1589     ParsePosition pos(0);
   1590     UDate d2 = fmt.parse(str, pos);
   1591     if (date != d2) {
   1592         errln("FAIL: unable to parse strings where case-folding changes length");
   1593     }
   1594 }
   1595 
   1596 void DateFormatTest::TestStandAloneMonths()
   1597 {
   1598     const char *EN_DATA[] = {
   1599         "yyyy MM dd HH:mm:ss",
   1600 
   1601         "yyyy LLLL dd H:mm:ss", "fp", "2004 03 10 16:36:31", "2004 March 10 16:36:31", "2004 03 10 16:36:31",
   1602         "yyyy LLL dd H:mm:ss",  "fp", "2004 03 10 16:36:31", "2004 Mar 10 16:36:31",   "2004 03 10 16:36:31",
   1603         "yyyy LLLL dd H:mm:ss", "F",  "2004 03 10 16:36:31", "2004 March 10 16:36:31",
   1604         "yyyy LLL dd H:mm:ss",  "pf", "2004 Mar 10 16:36:31", "2004 03 10 16:36:31", "2004 Mar 10 16:36:31",
   1605 
   1606         "LLLL", "fp", "1970 01 01 0:00:00", "January",   "1970 01 01 0:00:00",
   1607         "LLLL", "fp", "1970 02 01 0:00:00", "February",  "1970 02 01 0:00:00",
   1608         "LLLL", "fp", "1970 03 01 0:00:00", "March",     "1970 03 01 0:00:00",
   1609         "LLLL", "fp", "1970 04 01 0:00:00", "April",     "1970 04 01 0:00:00",
   1610         "LLLL", "fp", "1970 05 01 0:00:00", "May",       "1970 05 01 0:00:00",
   1611         "LLLL", "fp", "1970 06 01 0:00:00", "June",      "1970 06 01 0:00:00",
   1612         "LLLL", "fp", "1970 07 01 0:00:00", "July",      "1970 07 01 0:00:00",
   1613         "LLLL", "fp", "1970 08 01 0:00:00", "August",    "1970 08 01 0:00:00",
   1614         "LLLL", "fp", "1970 09 01 0:00:00", "September", "1970 09 01 0:00:00",
   1615         "LLLL", "fp", "1970 10 01 0:00:00", "October",   "1970 10 01 0:00:00",
   1616         "LLLL", "fp", "1970 11 01 0:00:00", "November",  "1970 11 01 0:00:00",
   1617         "LLLL", "fp", "1970 12 01 0:00:00", "December",  "1970 12 01 0:00:00",
   1618 
   1619         "LLL", "fp", "1970 01 01 0:00:00", "Jan", "1970 01 01 0:00:00",
   1620         "LLL", "fp", "1970 02 01 0:00:00", "Feb", "1970 02 01 0:00:00",
   1621         "LLL", "fp", "1970 03 01 0:00:00", "Mar", "1970 03 01 0:00:00",
   1622         "LLL", "fp", "1970 04 01 0:00:00", "Apr", "1970 04 01 0:00:00",
   1623         "LLL", "fp", "1970 05 01 0:00:00", "May", "1970 05 01 0:00:00",
   1624         "LLL", "fp", "1970 06 01 0:00:00", "Jun", "1970 06 01 0:00:00",
   1625         "LLL", "fp", "1970 07 01 0:00:00", "Jul", "1970 07 01 0:00:00",
   1626         "LLL", "fp", "1970 08 01 0:00:00", "Aug", "1970 08 01 0:00:00",
   1627         "LLL", "fp", "1970 09 01 0:00:00", "Sep", "1970 09 01 0:00:00",
   1628         "LLL", "fp", "1970 10 01 0:00:00", "Oct", "1970 10 01 0:00:00",
   1629         "LLL", "fp", "1970 11 01 0:00:00", "Nov", "1970 11 01 0:00:00",
   1630         "LLL", "fp", "1970 12 01 0:00:00", "Dec", "1970 12 01 0:00:00",
   1631     };
   1632 
   1633     const char *CS_DATA[] = {
   1634         "yyyy MM dd HH:mm:ss",
   1635 
   1636         "yyyy LLLL dd H:mm:ss", "fp", "2004 04 10 16:36:31", "2004 duben 10 16:36:31", "2004 04 10 16:36:31",
   1637         "yyyy MMMM dd H:mm:ss", "fp", "2004 04 10 16:36:31", "2004 dubna 10 16:36:31", "2004 04 10 16:36:31",
   1638         "yyyy LLL dd H:mm:ss",  "fp", "2004 04 10 16:36:31", "2004 dub 10 16:36:31",   "2004 04 10 16:36:31",
   1639         "yyyy LLLL dd H:mm:ss", "F",  "2004 04 10 16:36:31", "2004 duben 10 16:36:31",
   1640         "yyyy MMMM dd H:mm:ss", "F",  "2004 04 10 16:36:31", "2004 dubna 10 16:36:31",
   1641         "yyyy LLLL dd H:mm:ss", "pf", "2004 duben 10 16:36:31", "2004 04 10 16:36:31", "2004 duben 10 16:36:31",
   1642         "yyyy MMMM dd H:mm:ss", "pf", "2004 dubna 10 16:36:31", "2004 04 10 16:36:31", "2004 dubna 10 16:36:31",
   1643 
   1644         "LLLL", "fp", "1970 01 01 0:00:00", "leden",               "1970 01 01 0:00:00",
   1645         "LLLL", "fp", "1970 02 01 0:00:00", "\\u00FAnor",           "1970 02 01 0:00:00",
   1646         "LLLL", "fp", "1970 03 01 0:00:00", "b\\u0159ezen",         "1970 03 01 0:00:00",
   1647         "LLLL", "fp", "1970 04 01 0:00:00", "duben",               "1970 04 01 0:00:00",
   1648         "LLLL", "fp", "1970 05 01 0:00:00", "kv\\u011Bten",         "1970 05 01 0:00:00",
   1649         "LLLL", "fp", "1970 06 01 0:00:00", "\\u010Derven",         "1970 06 01 0:00:00",
   1650         "LLLL", "fp", "1970 07 01 0:00:00", "\\u010Dervenec",       "1970 07 01 0:00:00",
   1651         "LLLL", "fp", "1970 08 01 0:00:00", "srpen",               "1970 08 01 0:00:00",
   1652         "LLLL", "fp", "1970 09 01 0:00:00", "z\\u00E1\\u0159\\u00ED", "1970 09 01 0:00:00",
   1653         "LLLL", "fp", "1970 10 01 0:00:00", "\\u0159\\u00EDjen",     "1970 10 01 0:00:00",
   1654         "LLLL", "fp", "1970 11 01 0:00:00", "listopad",            "1970 11 01 0:00:00",
   1655         "LLLL", "fp", "1970 12 01 0:00:00", "prosinec",            "1970 12 01 0:00:00",
   1656 
   1657         "LLL", "fp", "1970 01 01 0:00:00", "led",  "1970 01 01 0:00:00",
   1658         "LLL", "fp", "1970 02 01 0:00:00", "\\u00FAno",  "1970 02 01 0:00:00",
   1659         "LLL", "fp", "1970 03 01 0:00:00", "b\\u0159e",  "1970 03 01 0:00:00",
   1660         "LLL", "fp", "1970 04 01 0:00:00", "dub",  "1970 04 01 0:00:00",
   1661         "LLL", "fp", "1970 05 01 0:00:00", "kv\\u011B",  "1970 05 01 0:00:00",
   1662         "LLL", "fp", "1970 06 01 0:00:00", "\\u010Dvn",  "1970 06 01 0:00:00",
   1663         "LLL", "fp", "1970 07 01 0:00:00", "\\u010Dvc",  "1970 07 01 0:00:00",
   1664         "LLL", "fp", "1970 08 01 0:00:00", "srp",  "1970 08 01 0:00:00",
   1665         "LLL", "fp", "1970 09 01 0:00:00", "z\\u00E1\\u0159",  "1970 09 01 0:00:00",
   1666         "LLL", "fp", "1970 10 01 0:00:00", "\\u0159\\u00EDj", "1970 10 01 0:00:00",
   1667         "LLL", "fp", "1970 11 01 0:00:00", "lis", "1970 11 01 0:00:00",
   1668         "LLL", "fp", "1970 12 01 0:00:00", "pro", "1970 12 01 0:00:00",
   1669     };
   1670 
   1671     expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
   1672     expect(CS_DATA, UPRV_LENGTHOF(CS_DATA), Locale("cs", "", ""));
   1673 }
   1674 
   1675 void DateFormatTest::TestStandAloneDays()
   1676 {
   1677     const char *EN_DATA[] = {
   1678         "yyyy MM dd HH:mm:ss",
   1679 
   1680         "cccc", "fp", "1970 01 04 0:00:00", "Sunday",    "1970 01 04 0:00:00",
   1681         "cccc", "fp", "1970 01 05 0:00:00", "Monday",    "1970 01 05 0:00:00",
   1682         "cccc", "fp", "1970 01 06 0:00:00", "Tuesday",   "1970 01 06 0:00:00",
   1683         "cccc", "fp", "1970 01 07 0:00:00", "Wednesday", "1970 01 07 0:00:00",
   1684         "cccc", "fp", "1970 01 01 0:00:00", "Thursday",  "1970 01 01 0:00:00",
   1685         "cccc", "fp", "1970 01 02 0:00:00", "Friday",    "1970 01 02 0:00:00",
   1686         "cccc", "fp", "1970 01 03 0:00:00", "Saturday",  "1970 01 03 0:00:00",
   1687 
   1688         "ccc", "fp", "1970 01 04 0:00:00", "Sun", "1970 01 04 0:00:00",
   1689         "ccc", "fp", "1970 01 05 0:00:00", "Mon", "1970 01 05 0:00:00",
   1690         "ccc", "fp", "1970 01 06 0:00:00", "Tue", "1970 01 06 0:00:00",
   1691         "ccc", "fp", "1970 01 07 0:00:00", "Wed", "1970 01 07 0:00:00",
   1692         "ccc", "fp", "1970 01 01 0:00:00", "Thu", "1970 01 01 0:00:00",
   1693         "ccc", "fp", "1970 01 02 0:00:00", "Fri", "1970 01 02 0:00:00",
   1694         "ccc", "fp", "1970 01 03 0:00:00", "Sat", "1970 01 03 0:00:00",
   1695     };
   1696 
   1697     const char *CS_DATA[] = {
   1698         "yyyy MM dd HH:mm:ss",
   1699 
   1700         "cccc", "fp", "1970 01 04 0:00:00", "ned\\u011Ble",       "1970 01 04 0:00:00",
   1701         "cccc", "fp", "1970 01 05 0:00:00", "pond\\u011Bl\\u00ED", "1970 01 05 0:00:00",
   1702         "cccc", "fp", "1970 01 06 0:00:00", "\\u00FAter\\u00FD",   "1970 01 06 0:00:00",
   1703         "cccc", "fp", "1970 01 07 0:00:00", "st\\u0159eda",       "1970 01 07 0:00:00",
   1704         "cccc", "fp", "1970 01 01 0:00:00", "\\u010Dtvrtek",      "1970 01 01 0:00:00",
   1705         "cccc", "fp", "1970 01 02 0:00:00", "p\\u00E1tek",        "1970 01 02 0:00:00",
   1706         "cccc", "fp", "1970 01 03 0:00:00", "sobota",            "1970 01 03 0:00:00",
   1707 
   1708         "ccc", "fp", "1970 01 04 0:00:00", "ne",      "1970 01 04 0:00:00",
   1709         "ccc", "fp", "1970 01 05 0:00:00", "po",      "1970 01 05 0:00:00",
   1710         "ccc", "fp", "1970 01 06 0:00:00", "\\u00FAt", "1970 01 06 0:00:00",
   1711         "ccc", "fp", "1970 01 07 0:00:00", "st",      "1970 01 07 0:00:00",
   1712         "ccc", "fp", "1970 01 01 0:00:00", "\\u010Dt", "1970 01 01 0:00:00",
   1713         "ccc", "fp", "1970 01 02 0:00:00", "p\\u00E1", "1970 01 02 0:00:00",
   1714         "ccc", "fp", "1970 01 03 0:00:00", "so",      "1970 01 03 0:00:00",
   1715     };
   1716 
   1717     expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
   1718     expect(CS_DATA, UPRV_LENGTHOF(CS_DATA), Locale("cs", "", ""));
   1719 }
   1720 
   1721 void DateFormatTest::TestShortDays()
   1722 {
   1723     const char *EN_DATA[] = {
   1724         "yyyy MM dd HH:mm:ss",
   1725 
   1726         "EEEEEE, MMM d y", "fp", "2013 01 13 0:00:00", "Su, Jan 13 2013", "2013 01 13 0:00:00",
   1727         "EEEEEE, MMM d y", "fp", "2013 01 16 0:00:00", "We, Jan 16 2013", "2013 01 16 0:00:00",
   1728         "EEEEEE d",        "fp", "1970 01 17 0:00:00", "Sa 17",           "1970 01 17 0:00:00",
   1729         "cccccc d",        "fp", "1970 01 17 0:00:00", "Sa 17",           "1970 01 17 0:00:00",
   1730         "cccccc",          "fp", "1970 01 03 0:00:00", "Sa",              "1970 01 03 0:00:00",
   1731     };
   1732     const char *SV_DATA[] = {
   1733         "yyyy MM dd HH:mm:ss",
   1734 
   1735         "EEEEEE d MMM y",  "fp", "2013 01 13 0:00:00", "s\\u00F6 13 jan. 2013", "2013 01 13 0:00:00",
   1736         "EEEEEE d MMM y",  "fp", "2013 01 16 0:00:00", "on 16 jan. 2013",       "2013 01 16 0:00:00",
   1737         "EEEEEE d",        "fp", "1970 01 17 0:00:00", "l\\u00F6 17",          "1970 01 17 0:00:00",
   1738         "cccccc d",        "fp", "1970 01 17 0:00:00", "l\\u00F6 17",          "1970 01 17 0:00:00",
   1739         "cccccc",          "fp", "1970 01 03 0:00:00", "l\\u00F6",             "1970 01 03 0:00:00",
   1740     };
   1741     expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
   1742     expect(SV_DATA, UPRV_LENGTHOF(SV_DATA), Locale("sv", "", ""));
   1743 }
   1744 
   1745 void DateFormatTest::TestNarrowNames()
   1746 {
   1747     const char *EN_DATA[] = {
   1748             "yyyy MM dd HH:mm:ss",
   1749 
   1750             "yyyy MMMMM dd H:mm:ss", "2004 03 10 16:36:31", "2004 M 10 16:36:31",
   1751             "yyyy LLLLL dd H:mm:ss",  "2004 03 10 16:36:31", "2004 M 10 16:36:31",
   1752 
   1753             "MMMMM", "1970 01 01 0:00:00", "J",
   1754             "MMMMM", "1970 02 01 0:00:00", "F",
   1755             "MMMMM", "1970 03 01 0:00:00", "M",
   1756             "MMMMM", "1970 04 01 0:00:00", "A",
   1757             "MMMMM", "1970 05 01 0:00:00", "M",
   1758             "MMMMM", "1970 06 01 0:00:00", "J",
   1759             "MMMMM", "1970 07 01 0:00:00", "J",
   1760             "MMMMM", "1970 08 01 0:00:00", "A",
   1761             "MMMMM", "1970 09 01 0:00:00", "S",
   1762             "MMMMM", "1970 10 01 0:00:00", "O",
   1763             "MMMMM", "1970 11 01 0:00:00", "N",
   1764             "MMMMM", "1970 12 01 0:00:00", "D",
   1765 
   1766             "LLLLL", "1970 01 01 0:00:00", "J",
   1767             "LLLLL", "1970 02 01 0:00:00", "F",
   1768             "LLLLL", "1970 03 01 0:00:00", "M",
   1769             "LLLLL", "1970 04 01 0:00:00", "A",
   1770             "LLLLL", "1970 05 01 0:00:00", "M",
   1771             "LLLLL", "1970 06 01 0:00:00", "J",
   1772             "LLLLL", "1970 07 01 0:00:00", "J",
   1773             "LLLLL", "1970 08 01 0:00:00", "A",
   1774             "LLLLL", "1970 09 01 0:00:00", "S",
   1775             "LLLLL", "1970 10 01 0:00:00", "O",
   1776             "LLLLL", "1970 11 01 0:00:00", "N",
   1777             "LLLLL", "1970 12 01 0:00:00", "D",
   1778 
   1779             "EEEEE", "1970 01 04 0:00:00", "S",
   1780             "EEEEE", "1970 01 05 0:00:00", "M",
   1781             "EEEEE", "1970 01 06 0:00:00", "T",
   1782             "EEEEE", "1970 01 07 0:00:00", "W",
   1783             "EEEEE", "1970 01 01 0:00:00", "T",
   1784             "EEEEE", "1970 01 02 0:00:00", "F",
   1785             "EEEEE", "1970 01 03 0:00:00", "S",
   1786 
   1787             "ccccc", "1970 01 04 0:00:00", "S",
   1788             "ccccc", "1970 01 05 0:00:00", "M",
   1789             "ccccc", "1970 01 06 0:00:00", "T",
   1790             "ccccc", "1970 01 07 0:00:00", "W",
   1791             "ccccc", "1970 01 01 0:00:00", "T",
   1792             "ccccc", "1970 01 02 0:00:00", "F",
   1793             "ccccc", "1970 01 03 0:00:00", "S",
   1794 
   1795             "h:mm a",     "2015 01 01 10:00:00", "10:00 AM",
   1796             "h:mm a",     "2015 01 01 22:00:00", "10:00 PM",
   1797             "h:mm aaaaa", "2015 01 01 10:00:00", "10:00 a",
   1798             "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 p",
   1799         };
   1800 
   1801         const char *CS_DATA[] = {
   1802             "yyyy MM dd HH:mm:ss",
   1803 
   1804             "yyyy LLLLL dd H:mm:ss", "2004 04 10 16:36:31", "2004 4 10 16:36:31",
   1805             "yyyy MMMMM dd H:mm:ss", "2004 04 10 16:36:31", "2004 4 10 16:36:31",
   1806 
   1807             "MMMMM", "1970 01 01 0:00:00", "1",
   1808             "MMMMM", "1970 02 01 0:00:00", "2",
   1809             "MMMMM", "1970 03 01 0:00:00", "3",
   1810             "MMMMM", "1970 04 01 0:00:00", "4",
   1811             "MMMMM", "1970 05 01 0:00:00", "5",
   1812             "MMMMM", "1970 06 01 0:00:00", "6",
   1813             "MMMMM", "1970 07 01 0:00:00", "7",
   1814             "MMMMM", "1970 08 01 0:00:00", "8",
   1815             "MMMMM", "1970 09 01 0:00:00", "9",
   1816             "MMMMM", "1970 10 01 0:00:00", "10",
   1817             "MMMMM", "1970 11 01 0:00:00", "11",
   1818             "MMMMM", "1970 12 01 0:00:00", "12",
   1819 
   1820             "LLLLL", "1970 01 01 0:00:00", "1",
   1821             "LLLLL", "1970 02 01 0:00:00", "2",
   1822             "LLLLL", "1970 03 01 0:00:00", "3",
   1823             "LLLLL", "1970 04 01 0:00:00", "4",
   1824             "LLLLL", "1970 05 01 0:00:00", "5",
   1825             "LLLLL", "1970 06 01 0:00:00", "6",
   1826             "LLLLL", "1970 07 01 0:00:00", "7",
   1827             "LLLLL", "1970 08 01 0:00:00", "8",
   1828             "LLLLL", "1970 09 01 0:00:00", "9",
   1829             "LLLLL", "1970 10 01 0:00:00", "10",
   1830             "LLLLL", "1970 11 01 0:00:00", "11",
   1831             "LLLLL", "1970 12 01 0:00:00", "12",
   1832 
   1833             "EEEEE", "1970 01 04 0:00:00", "N",
   1834             "EEEEE", "1970 01 05 0:00:00", "P",
   1835             "EEEEE", "1970 01 06 0:00:00", "\\u00DA",
   1836             "EEEEE", "1970 01 07 0:00:00", "S",
   1837             "EEEEE", "1970 01 01 0:00:00", "\\u010C",
   1838             "EEEEE", "1970 01 02 0:00:00", "P",
   1839             "EEEEE", "1970 01 03 0:00:00", "S",
   1840 
   1841             "ccccc", "1970 01 04 0:00:00", "N",
   1842             "ccccc", "1970 01 05 0:00:00", "P",
   1843             "ccccc", "1970 01 06 0:00:00", "\\u00DA",
   1844             "ccccc", "1970 01 07 0:00:00", "S",
   1845             "ccccc", "1970 01 01 0:00:00", "\\u010C",
   1846             "ccccc", "1970 01 02 0:00:00", "P",
   1847             "ccccc", "1970 01 03 0:00:00", "S",
   1848 
   1849             "h:mm a",     "2015 01 01 10:00:00", "10:00 dop.",
   1850             "h:mm a",     "2015 01 01 22:00:00", "10:00 odp.",
   1851             "h:mm aaaaa", "2015 01 01 10:00:00", "10:00 dop.",
   1852             "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 odp.",
   1853         };
   1854 
   1855         const char *CA_DATA[] = {
   1856             "yyyy MM dd HH:mm:ss",
   1857 
   1858             "h:mm a",     "2015 01 01 10:00:00", "10:00 a. m.",
   1859             "h:mm a",     "2015 01 01 22:00:00", "10:00 p. m.",
   1860             "h:mm aaaaa", "2015 01 01 10:00:00", "10:00 a. m.",
   1861             "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 p. m.",
   1862         };
   1863 
   1864       expectFormat(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
   1865       expectFormat(CS_DATA, UPRV_LENGTHOF(CS_DATA), Locale("cs", "", ""));
   1866       expectFormat(CA_DATA, UPRV_LENGTHOF(CA_DATA), Locale("ca", "", ""));
   1867 }
   1868 
   1869 void DateFormatTest::TestEras()
   1870 {
   1871     const char *EN_DATA[] = {
   1872         "yyyy MM dd",
   1873 
   1874         "MMMM dd yyyy G",    "fp", "1951 07 17", "July 17 1951 AD",          "1951 07 17",
   1875         "MMMM dd yyyy GG",   "fp", "1951 07 17", "July 17 1951 AD",          "1951 07 17",
   1876         "MMMM dd yyyy GGG",  "fp", "1951 07 17", "July 17 1951 AD",          "1951 07 17",
   1877         "MMMM dd yyyy GGGG", "fp", "1951 07 17", "July 17 1951 Anno Domini", "1951 07 17",
   1878 
   1879         "MMMM dd yyyy G",    "fp", "-438 07 17", "July 17 0439 BC",            "-438 07 17",
   1880         "MMMM dd yyyy GG",   "fp", "-438 07 17", "July 17 0439 BC",            "-438 07 17",
   1881         "MMMM dd yyyy GGG",  "fp", "-438 07 17", "July 17 0439 BC",            "-438 07 17",
   1882         "MMMM dd yyyy GGGG", "fp", "-438 07 17", "July 17 0439 Before Christ", "-438 07 17",
   1883     };
   1884 
   1885     expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
   1886 }
   1887 
   1888 void DateFormatTest::TestQuarters()
   1889 {
   1890     const char *EN_DATA[] = {
   1891         "yyyy MM dd",
   1892 
   1893         "Q",    "fp", "1970 01 01", "1",           "1970 01 01",
   1894         "QQ",   "fp", "1970 04 01", "02",          "1970 04 01",
   1895         "QQQ",  "fp", "1970 07 01", "Q3",          "1970 07 01",
   1896         "QQQQ", "fp", "1970 10 01", "4th quarter", "1970 10 01",
   1897 
   1898         "q",    "fp", "1970 01 01", "1",           "1970 01 01",
   1899         "qq",   "fp", "1970 04 01", "02",          "1970 04 01",
   1900         "qqq",  "fp", "1970 07 01", "Q3",          "1970 07 01",
   1901         "qqqq", "fp", "1970 10 01", "4th quarter", "1970 10 01",
   1902 
   1903         "Qyy",  "fp", "2015 04 01", "215",         "2015 04 01",
   1904         "QQyy", "fp", "2015 07 01", "0315",        "2015 07 01",
   1905     };
   1906 
   1907     expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
   1908 }
   1909 
   1910 /**
   1911  * Test parsing.  Input is an array that starts with the following
   1912  * header:
   1913  *
   1914  * [0]   = pattern string to parse [i+2] with
   1915  *
   1916  * followed by test cases, each of which is 3 array elements:
   1917  *
   1918  * [i]   = pattern, or NULL to reuse prior pattern
   1919  * [i+1] = input string
   1920  * [i+2] = expected parse result (parsed with pattern [0])
   1921  *
   1922  * If expect parse failure, then [i+2] should be NULL.
   1923  */
   1924 void DateFormatTest::expectParse(const char** data, int32_t data_length,
   1925                                  const Locale& loc) {
   1926     const UDate FAIL = (UDate) -1;
   1927     const UnicodeString FAIL_STR("parse failure");
   1928     int32_t i = 0;
   1929 
   1930     UErrorCode ec = U_ZERO_ERROR;
   1931     SimpleDateFormat fmt("", loc, ec);
   1932     SimpleDateFormat ref(data[i++], loc, ec);
   1933     SimpleDateFormat gotfmt("G yyyy MM dd HH:mm:ss z", loc, ec);
   1934     if (U_FAILURE(ec)) {
   1935         dataerrln("FAIL: SimpleDateFormat constructor - %s", u_errorName(ec));
   1936         return;
   1937     }
   1938 
   1939     const char* currentPat = NULL;
   1940     while (i<data_length) {
   1941         const char* pattern  = data[i++];
   1942         const char* input    = data[i++];
   1943         const char* expected = data[i++];
   1944 
   1945         ec = U_ZERO_ERROR;
   1946         if (pattern != NULL) {
   1947             fmt.applyPattern(pattern);
   1948             currentPat = pattern;
   1949         }
   1950         UDate got = fmt.parse(input, ec);
   1951         UnicodeString gotstr(FAIL_STR);
   1952         if (U_FAILURE(ec)) {
   1953             got = FAIL;
   1954         } else {
   1955             gotstr.remove();
   1956             gotfmt.format(got, gotstr);
   1957         }
   1958 
   1959         UErrorCode ec2 = U_ZERO_ERROR;
   1960         UDate exp = FAIL;
   1961         UnicodeString expstr(FAIL_STR);
   1962         if (expected != NULL) {
   1963             expstr = expected;
   1964             exp = ref.parse(expstr, ec2);
   1965             if (U_FAILURE(ec2)) {
   1966                 // This only happens if expected is in wrong format --
   1967                 // should never happen once test is debugged.
   1968                 errln("FAIL: Internal test error");
   1969                 return;
   1970             }
   1971         }
   1972 
   1973         if (got == exp) {
   1974             logln((UnicodeString)"Ok: " + input + " x " +
   1975                   currentPat + " => " + gotstr);
   1976         } else {
   1977             errln((UnicodeString)"FAIL: " + input + " x " +
   1978                   currentPat + " => " + gotstr + ", expected " +
   1979                   expstr);
   1980         }
   1981     }
   1982 }
   1983 
   1984 /**
   1985  * Test formatting and parsing.  Input is an array that starts
   1986  * with the following header:
   1987  *
   1988  * [0]   = pattern string to parse [i+2] with
   1989  *
   1990  * followed by test cases, each of which is 3 array elements:
   1991  *
   1992  * [i]   = pattern, or null to reuse prior pattern
   1993  * [i+1] = control string, either "fp", "pf", or "F".
   1994  * [i+2..] = data strings
   1995  *
   1996  * The number of data strings depends on the control string.
   1997  * Examples:
   1998  * 1. "y/M/d H:mm:ss.SS", "fp", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.56", "2004 03 10 16:36:31.560",
   1999  * 'f': Format date [i+2] (as parsed using pattern [0]) and expect string [i+3].
   2000  * 'p': Parse string [i+3] and expect date [i+4].
   2001  *
   2002  * 2. "y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567"
   2003  * 'F': Format date [i+2] and expect string [i+3],
   2004  *      then parse string [i+3] and expect date [i+2].
   2005  *
   2006  * 3. "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",
   2007  * 'p': Parse string [i+2] and expect date [i+3].
   2008  * 'f': Format date [i+3] and expect string [i+4].
   2009  */
   2010 void DateFormatTest::expect(const char** data, int32_t data_length,
   2011                             const Locale& loc) {
   2012     int32_t i = 0;
   2013     UErrorCode ec = U_ZERO_ERROR;
   2014     UnicodeString str, str2;
   2015     SimpleDateFormat fmt("", loc, ec);
   2016     SimpleDateFormat ref(data[i++], loc, ec);
   2017     SimpleDateFormat univ("EE G yyyy MM dd HH:mm:ss.SSS z", loc, ec);
   2018     if (U_FAILURE(ec)) {
   2019         dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(ec));
   2020         return;
   2021     }
   2022 
   2023     UnicodeString currentPat;
   2024     while (i<data_length) {
   2025         const char* pattern  = data[i++];
   2026         if (pattern != NULL) {
   2027             fmt.applyPattern(pattern);
   2028             currentPat = pattern;
   2029         }
   2030 
   2031         const char* control = data[i++];
   2032 
   2033         if (uprv_strcmp(control, "fp") == 0) {
   2034             // 'f'
   2035             const char* datestr = data[i++];
   2036             const char* string = data[i++];
   2037             UDate date = ref.parse(ctou(datestr), ec);
   2038             if (!assertSuccess("parse", ec)) return;
   2039             assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
   2040                          ctou(string),
   2041                          fmt.format(date, str.remove()));
   2042             // 'p'
   2043             datestr = data[i++];
   2044             date = ref.parse(ctou(datestr), ec);
   2045             if (!assertSuccess("parse", ec)) return;
   2046             UDate parsedate = fmt.parse(ctou(string), ec);
   2047             if (assertSuccess((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")", ec)) {
   2048                 assertEquals((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")",
   2049                              univ.format(date, str.remove()),
   2050                              univ.format(parsedate, str2.remove()));
   2051             }
   2052         }
   2053 
   2054         else if (uprv_strcmp(control, "pf") == 0) {
   2055             // 'p'
   2056             const char* string = data[i++];
   2057             const char* datestr = data[i++];
   2058             UDate date = ref.parse(ctou(datestr), ec);
   2059             if (!assertSuccess("parse", ec)) return;
   2060             UDate parsedate = fmt.parse(ctou(string), ec);
   2061             if (assertSuccess((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")", ec)) {
   2062                 assertEquals((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")",
   2063                              univ.format(date, str.remove()),
   2064                              univ.format(parsedate, str2.remove()));
   2065             }
   2066             // 'f'
   2067             string = data[i++];
   2068             assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
   2069                          ctou(string),
   2070                          fmt.format(date, str.remove()));
   2071         }
   2072 
   2073         else if (uprv_strcmp(control, "F") == 0) {
   2074             const char* datestr  = data[i++];
   2075             const char* string   = data[i++];
   2076             UDate date = ref.parse(ctou(datestr), ec);
   2077             if (!assertSuccess("parse", ec)) return;
   2078             assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
   2079                          ctou(string),
   2080                          fmt.format(date, str.remove()));
   2081 
   2082             UDate parsedate = fmt.parse(string, ec);
   2083             if (assertSuccess((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")", ec)) {
   2084                 assertEquals((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")",
   2085                              univ.format(date, str.remove()),
   2086                              univ.format(parsedate, str2.remove()));
   2087             }
   2088         }
   2089 
   2090         else {
   2091             errln((UnicodeString)"FAIL: Invalid control string " + control);
   2092             return;
   2093         }
   2094     }
   2095 }
   2096 
   2097 /**
   2098  * Test formatting.  Input is an array that starts
   2099  * with the following header:
   2100  *
   2101  * [0]   = pattern string to parse [i+2] with
   2102  *
   2103  * followed by test cases, each of which is 3 array elements:
   2104  *
   2105  * [i]   = pattern, or null to reuse prior pattern
   2106  * [i+1] = data string a
   2107  * [i+2] = data string b
   2108  *
   2109  * Examples:
   2110  * Format date [i+1] and expect string [i+2].
   2111  *
   2112  * "y/M/d H:mm:ss.SSSS", "2004/3/10 16:36:31.5679", "2004 03 10 16:36:31.567"
   2113  */
   2114 void DateFormatTest::expectFormat(const char** data, int32_t data_length,
   2115                             const Locale& loc) {
   2116     int32_t i = 0;
   2117     UErrorCode ec = U_ZERO_ERROR;
   2118     UnicodeString str, str2;
   2119     SimpleDateFormat fmt("", loc, ec);
   2120     SimpleDateFormat ref(data[i++], loc, ec);
   2121     SimpleDateFormat univ("EE G yyyy MM dd HH:mm:ss.SSS z", loc, ec);
   2122     if (U_FAILURE(ec)) {
   2123         dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(ec));
   2124         return;
   2125     }
   2126 
   2127     UnicodeString currentPat;
   2128 
   2129     while (i<data_length) {
   2130         const char* pattern  = data[i++];
   2131         if (pattern != NULL) {
   2132             fmt.applyPattern(pattern);
   2133             currentPat = pattern;
   2134         }
   2135 
   2136         const char* datestr = data[i++];
   2137         const char* string = data[i++];
   2138         UDate date = ref.parse(ctou(datestr), ec);
   2139         if (!assertSuccess("parse", ec)) return;
   2140         assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
   2141                         ctou(string),
   2142                         fmt.format(date, str.remove()));
   2143     }
   2144 }
   2145 
   2146 void DateFormatTest::TestGenericTime() {
   2147   const Locale en("en");
   2148   // Note: We no longer parse strings in different styles.
   2149 /*
   2150   const char* ZDATA[] = {
   2151         "yyyy MM dd HH:mm zzz",
   2152         // round trip
   2153         "y/M/d H:mm zzzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Standard Time",
   2154         "y/M/d H:mm zzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
   2155         "y/M/d H:mm vvvv", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
   2156         "y/M/d H:mm v", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PT",
   2157         // non-generic timezone string influences dst offset even if wrong for date/time
   2158         "y/M/d H:mm zzz", "pf", "2004/1/1 1:00 PDT", "2004 01 01 01:00 PDT", "2004/1/1 0:00 PST",
   2159         "y/M/d H:mm vvvv", "pf", "2004/1/1 1:00 PDT", "2004 01 01 01:00 PDT", "2004/1/1 0:00 Pacific Time",
   2160         "y/M/d H:mm zzz", "pf", "2004/7/1 1:00 PST", "2004 07 01 02:00 PDT", "2004/7/1 2:00 PDT",
   2161         "y/M/d H:mm vvvv", "pf", "2004/7/1 1:00 PST", "2004 07 01 02:00 PDT", "2004/7/1 2:00 Pacific Time",
   2162         // generic timezone generates dst offset appropriate for local time
   2163         "y/M/d H:mm zzz", "pf", "2004/1/1 1:00 PT", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
   2164         "y/M/d H:mm vvvv", "pf", "2004/1/1 1:00 PT", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
   2165         "y/M/d H:mm zzz", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 PDT",
   2166         "y/M/d H:mm vvvv", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 Pacific Time",
   2167         // daylight savings time transition edge cases.
   2168         // time to parse does not really exist, PT interpreted as earlier time
   2169         "y/M/d H:mm zzz", "pf", "2005/4/3 2:30 PT", "2005 04 03 03:30 PDT", "2005/4/3 3:30 PDT",
   2170         "y/M/d H:mm zzz", "pf", "2005/4/3 2:30 PST", "2005 04 03 03:30 PDT", "2005/4/3 3:30 PDT",
   2171         "y/M/d H:mm zzz", "pf", "2005/4/3 2:30 PDT", "2005 04 03 01:30 PST", "2005/4/3 1:30 PST",
   2172         "y/M/d H:mm v", "pf", "2005/4/3 2:30 PT", "2005 04 03 03:30 PDT", "2005/4/3 3:30 PT",
   2173         "y/M/d H:mm v", "pf", "2005/4/3 2:30 PST", "2005 04 03 03:30 PDT", "2005/4/3 3:30 PT",
   2174         "y/M/d H:mm v", "pf", "2005/4/3 2:30 PDT", "2005 04 03 01:30 PST", "2005/4/3 1:30 PT",
   2175         "y/M/d H:mm", "pf", "2005/4/3 2:30", "2005 04 03 03:30 PDT", "2005/4/3 3:30",
   2176         // time to parse is ambiguous, PT interpreted as later time
   2177         "y/M/d H:mm zzz", "pf", "2005/10/30 1:30 PT", "2005 10 30 01:30 PST", "2005/10/30 1:30 PST",
   2178         "y/M/d H:mm v", "pf", "2005/10/30 1:30 PT", "2005 10 30  01:30 PST", "2005/10/30 1:30 PT",
   2179         "y/M/d H:mm", "pf", "2005/10/30 1:30 PT", "2005 10 30 01:30 PST", "2005/10/30 1:30",
   2180 
   2181         "y/M/d H:mm zzz", "pf", "2004/10/31 1:30 PT", "2004 10 31 01:30 PST", "2004/10/31 1:30 PST",
   2182         "y/M/d H:mm zzz", "pf", "2004/10/31 1:30 PST", "2004 10 31 01:30 PST", "2004/10/31 1:30 PST",
   2183         "y/M/d H:mm zzz", "pf", "2004/10/31 1:30 PDT", "2004 10 31 01:30 PDT", "2004/10/31 1:30 PDT",
   2184         "y/M/d H:mm v", "pf", "2004/10/31 1:30 PT", "2004 10 31 01:30 PST", "2004/10/31 1:30 PT",
   2185         "y/M/d H:mm v", "pf", "2004/10/31 1:30 PST", "2004 10 31 01:30 PST", "2004/10/31 1:30 PT",
   2186         "y/M/d H:mm v", "pf", "2004/10/31 1:30 PDT", "2004 10 31 01:30 PDT", "2004/10/31 1:30 PT",
   2187         "y/M/d H:mm", "pf", "2004/10/31 1:30", "2004 10 31 01:30 PST", "2004/10/31 1:30",
   2188   };
   2189 */
   2190   const char* ZDATA[] = {
   2191         "yyyy MM dd HH:mm zzz",
   2192         // round trip
   2193         "y/M/d H:mm zzzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Standard Time",
   2194         "y/M/d H:mm zzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
   2195         "y/M/d H:mm vvvv", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
   2196         "y/M/d H:mm v", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PT",
   2197         // non-generic timezone string influences dst offset even if wrong for date/time
   2198         "y/M/d H:mm zzz", "pf", "2004/1/1 1:00 PDT", "2004 01 01 01:00 PDT", "2004/1/1 0:00 PST",
   2199         "y/M/d H:mm zzz", "pf", "2004/7/1 1:00 PST", "2004 07 01 02:00 PDT", "2004/7/1 2:00 PDT",
   2200         // generic timezone generates dst offset appropriate for local time
   2201         "y/M/d H:mm zzz", "pf", "2004/1/1 1:00 PST", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
   2202         "y/M/d H:mm vvvv", "pf", "2004/1/1 1:00 Pacific Time", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
   2203         "y/M/d H:mm zzz", "pf", "2004/7/1 1:00 PDT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 PDT",
   2204         "y/M/d H:mm vvvv", "pf", "2004/7/1 1:00 Pacific Time", "2004 07 01 01:00 PDT", "2004/7/1 1:00 Pacific Time",
   2205         // daylight savings time transition edge cases.
   2206         // time to parse does not really exist, PT interpreted as earlier time
   2207         "y/M/d H:mm zzz", "pf", "2005/4/3 2:30 PST", "2005 04 03 03:30 PDT", "2005/4/3 3:30 PDT",
   2208         "y/M/d H:mm zzz", "pf", "2005/4/3 2:30 PDT", "2005 04 03 01:30 PST", "2005/4/3 1:30 PST",
   2209         "y/M/d H:mm v", "pf", "2005/4/3 2:30 PT", "2005 04 03 03:30 PDT", "2005/4/3 3:30 PT",
   2210         "y/M/d H:mm", "pf", "2005/4/3 2:30", "2005 04 03 03:30 PDT", "2005/4/3 3:30",
   2211         // time to parse is ambiguous, PT interpreted as later time
   2212         "y/M/d H:mm v", "pf", "2005/10/30 1:30 PT", "2005 10 30  01:30 PST", "2005/10/30 1:30 PT",
   2213         "y/M/d H:mm", "pf", "2005/10/30 1:30 PT", "2005 10 30 01:30 PST", "2005/10/30 1:30",
   2214 
   2215         "y/M/d H:mm zzz", "pf", "2004/10/31 1:30 PST", "2004 10 31 01:30 PST", "2004/10/31 1:30 PST",
   2216         "y/M/d H:mm zzz", "pf", "2004/10/31 1:30 PDT", "2004 10 31 01:30 PDT", "2004/10/31 1:30 PDT",
   2217         "y/M/d H:mm v", "pf", "2004/10/31 1:30 PT", "2004 10 31 01:30 PST", "2004/10/31 1:30 PT",
   2218         "y/M/d H:mm", "pf", "2004/10/31 1:30", "2004 10 31 01:30 PST", "2004/10/31 1:30",
   2219   };
   2220 
   2221   const int32_t ZDATA_length = UPRV_LENGTHOF(ZDATA);
   2222   expect(ZDATA, ZDATA_length, en);
   2223 
   2224   UErrorCode status = U_ZERO_ERROR;
   2225 
   2226   logln("cross format/parse tests");    // Note: We no longer support cross format/parse
   2227   UnicodeString basepat("yy/MM/dd H:mm ");
   2228   SimpleDateFormat formats[] = {
   2229     SimpleDateFormat(basepat + "vvv", en, status),
   2230     SimpleDateFormat(basepat + "vvvv", en, status),
   2231     SimpleDateFormat(basepat + "zzz", en, status),
   2232     SimpleDateFormat(basepat + "zzzz", en, status)
   2233   };
   2234   if (U_FAILURE(status)) {
   2235     dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(status));
   2236     return;
   2237   }
   2238   const int32_t formats_length = UPRV_LENGTHOF(formats);
   2239 
   2240   UnicodeString test;
   2241   SimpleDateFormat univ("yyyy MM dd HH:mm zzz", en, status);
   2242   ASSERT_OK(status);
   2243   const UnicodeString times[] = {
   2244     "2004 01 02 03:04 PST",
   2245     "2004 07 08 09:10 PDT"
   2246   };
   2247   int32_t times_length = UPRV_LENGTHOF(times);
   2248   for (int i = 0; i < times_length; ++i) {
   2249     UDate d = univ.parse(times[i], status);
   2250     logln(UnicodeString("\ntime: ") + d);
   2251     for (int j = 0; j < formats_length; ++j) {
   2252       test.remove();
   2253       formats[j].format(d, test);
   2254       logln("\ntest: '" + test + "'");
   2255       for (int k = 0; k < formats_length; ++k) {
   2256         UDate t = formats[k].parse(test, status);
   2257         if (U_SUCCESS(status)) {
   2258           if (d != t) {
   2259             errln((UnicodeString)"FAIL: format " + k +
   2260                   " incorrectly parsed output of format " + j +
   2261                   " (" + test + "), returned " +
   2262                   dateToString(t) + " instead of " + dateToString(d));
   2263           } else {
   2264             logln((UnicodeString)"OK: format " + k + " parsed ok");
   2265           }
   2266         } else if (status == U_PARSE_ERROR) {
   2267           errln((UnicodeString)"FAIL: format " + k +
   2268                 " could not parse output of format " + j +
   2269                 " (" + test + ")");
   2270         }
   2271       }
   2272     }
   2273   }
   2274 }
   2275 
   2276 void DateFormatTest::TestGenericTimeZoneOrder() {
   2277   // generic times should parse the same no matter what the placement of the time zone string
   2278 
   2279   // Note: We no longer support cross style format/parse
   2280 
   2281   //const char* XDATA[] = {
   2282   //  "yyyy MM dd HH:mm zzz",
   2283   //  // standard time, explicit daylight/standard
   2284   //  "y/M/d H:mm zzz", "pf", "2004/1/1 1:00 PT", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
   2285   //  "y/M/d zzz H:mm", "pf", "2004/1/1 PT 1:00", "2004 01 01 01:00 PST", "2004/1/1 PST 1:00",
   2286   //  "zzz y/M/d H:mm", "pf", "PT 2004/1/1 1:00", "2004 01 01 01:00 PST", "PST 2004/1/1 1:00",
   2287 
   2288   //  // standard time, generic
   2289   //  "y/M/d H:mm vvvv", "pf", "2004/1/1 1:00 PT", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
   2290   //  "y/M/d vvvv H:mm", "pf", "2004/1/1 PT 1:00", "2004 01 01 01:00 PST", "2004/1/1 Pacific Time 1:00",
   2291   //  "vvvv y/M/d H:mm", "pf", "PT 2004/1/1 1:00", "2004 01 01 01:00 PST", "Pacific Time 2004/1/1 1:00",
   2292 
   2293   //  // dahylight time, explicit daylight/standard
   2294   //  "y/M/d H:mm zzz", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 PDT",
   2295   //  "y/M/d zzz H:mm", "pf", "2004/7/1 PT 1:00", "2004 07 01 01:00 PDT", "2004/7/1 PDT 1:00",
   2296   //  "zzz y/M/d H:mm", "pf", "PT 2004/7/1 1:00", "2004 07 01 01:00 PDT", "PDT 2004/7/1 1:00",
   2297 
   2298   //  // daylight time, generic
   2299   //  "y/M/d H:mm vvvv", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 Pacific Time",
   2300   //  "y/M/d vvvv H:mm", "pf", "2004/7/1 PT 1:00", "2004 07 01 01:00 PDT", "2004/7/1 Pacific Time 1:00",
   2301   //  "vvvv y/M/d H:mm", "pf", "PT 2004/7/1 1:00", "2004 07 01 01:00 PDT", "Pacific Time 2004/7/1 1:00",
   2302   //};
   2303   const char* XDATA[] = {
   2304     "yyyy MM dd HH:mm zzz",
   2305     // standard time, explicit daylight/standard
   2306     "y/M/d H:mm zzz", "pf", "2004/1/1 1:00 PST", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
   2307     "y/M/d zzz H:mm", "pf", "2004/1/1 PST 1:00", "2004 01 01 01:00 PST", "2004/1/1 PST 1:00",
   2308     "zzz y/M/d H:mm", "pf", "PST 2004/1/1 1:00", "2004 01 01 01:00 PST", "PST 2004/1/1 1:00",
   2309 
   2310     // standard time, generic
   2311     "y/M/d H:mm vvvv", "pf", "2004/1/1 1:00 Pacific Time", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
   2312     "y/M/d vvvv H:mm", "pf", "2004/1/1 Pacific Time 1:00", "2004 01 01 01:00 PST", "2004/1/1 Pacific Time 1:00",
   2313     "vvvv y/M/d H:mm", "pf", "Pacific Time 2004/1/1 1:00", "2004 01 01 01:00 PST", "Pacific Time 2004/1/1 1:00",
   2314 
   2315     // dahylight time, explicit daylight/standard
   2316     "y/M/d H:mm zzz", "pf", "2004/7/1 1:00 PDT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 PDT",
   2317     "y/M/d zzz H:mm", "pf", "2004/7/1 PDT 1:00", "2004 07 01 01:00 PDT", "2004/7/1 PDT 1:00",
   2318     "zzz y/M/d H:mm", "pf", "PDT 2004/7/1 1:00", "2004 07 01 01:00 PDT", "PDT 2004/7/1 1:00",
   2319 
   2320     // daylight time, generic
   2321     "y/M/d H:mm v", "pf", "2004/7/1 1:00 PT", "2004 07 01 01:00 PDT", "2004/7/1 1:00 PT",
   2322     "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",
   2323     "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",
   2324   };
   2325   const int32_t XDATA_length = UPRV_LENGTHOF(XDATA);
   2326   Locale en("en");
   2327   expect(XDATA, XDATA_length, en);
   2328 }
   2329 
   2330 void DateFormatTest::TestZTimeZoneParsing(void) {
   2331     UErrorCode status = U_ZERO_ERROR;
   2332     const Locale en("en");
   2333     UnicodeString test;
   2334     //SimpleDateFormat univ("yyyy-MM-dd'T'HH:mm Z", en, status);
   2335     SimpleDateFormat univ("HH:mm Z", en, status);
   2336     if (failure(status, "construct SimpleDateFormat", TRUE)) return;
   2337     const TimeZone *t = TimeZone::getGMT();
   2338     univ.setTimeZone(*t);
   2339 
   2340     univ.setLenient(false);
   2341     ParsePosition pp(0);
   2342     struct {
   2343         UnicodeString input;
   2344         UnicodeString expected_result;
   2345     } tests[] = {
   2346         { "11:00 -0200", "13:00 +0000" },
   2347         { "11:00 +0200", "09:00 +0000" },
   2348         { "11:00 +0400", "07:00 +0000" },
   2349         { "11:00 +0530", "05:30 +0000" }
   2350     };
   2351 
   2352     UnicodeString result;
   2353     int32_t tests_length = UPRV_LENGTHOF(tests);
   2354     for (int i = 0; i < tests_length; ++i) {
   2355         pp.setIndex(0);
   2356         UDate d = univ.parse(tests[i].input, pp);
   2357         if(pp.getIndex() != tests[i].input.length()){
   2358             errln("Test %i: setZoneString() did not succeed. Consumed: %i instead of %i",
   2359                   i, pp.getIndex(), tests[i].input.length());
   2360             return;
   2361         }
   2362         result.remove();
   2363         univ.format(d, result);
   2364         if(result != tests[i].expected_result) {
   2365             errln("Expected " + tests[i].expected_result
   2366                   + " got " + result);
   2367             return;
   2368         }
   2369         logln("SUCCESS: Parsed " + tests[i].input
   2370               + " got " + result
   2371               + " expected " + tests[i].expected_result);
   2372     }
   2373 }
   2374 
   2375 void DateFormatTest::TestHost(void)
   2376 {
   2377 #if U_PLATFORM_USES_ONLY_WIN32_API
   2378     Win32DateTimeTest::testLocales(this);
   2379 #endif
   2380 }
   2381 
   2382 // Relative Date Tests
   2383 
   2384 void DateFormatTest::TestRelative(int daysdelta,
   2385                                   const Locale& loc,
   2386                                   const char *expectChars) {
   2387     char banner[25];
   2388     sprintf(banner, "%d", daysdelta);
   2389     UnicodeString bannerStr(banner, "");
   2390 
   2391     UErrorCode status = U_ZERO_ERROR;
   2392 
   2393     FieldPosition pos(FieldPosition::DONT_CARE);
   2394     UnicodeString test;
   2395     Locale en("en");
   2396     DateFormat *fullrelative = DateFormat::createDateInstance(DateFormat::kFullRelative, loc);
   2397 
   2398     if (fullrelative == NULL) {
   2399         dataerrln("DateFormat::createDateInstance(DateFormat::kFullRelative, %s) returned NULL", loc.getName());
   2400         return;
   2401     }
   2402 
   2403     DateFormat *full         = DateFormat::createDateInstance(DateFormat::kFull        , loc);
   2404 
   2405     if (full == NULL) {
   2406         errln("DateFormat::createDateInstance(DateFormat::kFull, %s) returned NULL", loc.getName());
   2407         return;
   2408     }
   2409 
   2410     DateFormat *en_full =         DateFormat::createDateInstance(DateFormat::kFull,         en);
   2411 
   2412     if (en_full == NULL) {
   2413         errln("DateFormat::createDateInstance(DateFormat::kFull, en) returned NULL");
   2414         return;
   2415     }
   2416 
   2417     DateFormat *en_fulltime =         DateFormat::createDateTimeInstance(DateFormat::kFull,DateFormat::kFull,en);
   2418 
   2419     if (en_fulltime == NULL) {
   2420         errln("DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, en) returned NULL");
   2421         return;
   2422     }
   2423 
   2424     UnicodeString result;
   2425     UnicodeString normalResult;
   2426     UnicodeString expect;
   2427     UnicodeString parseResult;
   2428 
   2429     Calendar *c = Calendar::createInstance(status);
   2430 
   2431     // Today = Today
   2432     c->setTime(Calendar::getNow(), status);
   2433     if(daysdelta != 0) {
   2434         c->add(Calendar::DATE,daysdelta,status);
   2435     }
   2436     ASSERT_OK(status);
   2437 
   2438     // calculate the expected string
   2439     if(expectChars != NULL) {
   2440         expect = expectChars;
   2441     } else {
   2442         full->format(*c, expect, pos); // expected = normal full
   2443     }
   2444 
   2445     fullrelative   ->format(*c, result, pos);
   2446     en_full        ->format(*c, normalResult, pos);
   2447 
   2448     if(result != expect) {
   2449         errln("FAIL: Relative Format ["+bannerStr+"] of "+normalResult+" failed, expected "+expect+" but got " + result);
   2450     } else {
   2451         logln("PASS: Relative Format ["+bannerStr+"] of "+normalResult+" got " + result);
   2452     }
   2453 
   2454 
   2455     //verify
   2456     UDate d = fullrelative->parse(result, status);
   2457     ASSERT_OK(status);
   2458 
   2459     UnicodeString parseFormat; // parse rel->format full
   2460     en_full->format(d, parseFormat, status);
   2461 
   2462     UnicodeString origFormat;
   2463     en_full->format(*c, origFormat, pos);
   2464 
   2465     if(parseFormat!=origFormat) {
   2466         errln("FAIL: Relative Parse ["+bannerStr+"] of "+result+" failed, expected "+parseFormat+" but got "+origFormat);
   2467     } else {
   2468         logln("PASS: Relative Parse ["+bannerStr+"] of "+result+" passed, got "+parseFormat);
   2469     }
   2470 
   2471     delete full;
   2472     delete fullrelative;
   2473     delete en_fulltime;
   2474     delete en_full;
   2475     delete c;
   2476 }
   2477 
   2478 
   2479 void DateFormatTest::TestRelative(void)
   2480 {
   2481     Locale en("en");
   2482     TestRelative( 0, en, "today");
   2483     TestRelative(-1, en, "yesterday");
   2484     TestRelative( 1, en, "tomorrow");
   2485     TestRelative( 2, en, NULL);
   2486     TestRelative( -2, en, NULL);
   2487     TestRelative( 3, en, NULL);
   2488     TestRelative( -3, en, NULL);
   2489     TestRelative( 300, en, NULL);
   2490     TestRelative( -300, en, NULL);
   2491 }
   2492 
   2493 void DateFormatTest::TestRelativeClone(void)
   2494 {
   2495     /*
   2496     Verify that a cloned formatter gives the same results
   2497     and is useable after the original has been deleted.
   2498     */
   2499     UErrorCode status = U_ZERO_ERROR;
   2500     Locale loc("en");
   2501     UDate now = Calendar::getNow();
   2502     DateFormat *full = DateFormat::createDateInstance(DateFormat::kFullRelative, loc);
   2503     if (full == NULL) {
   2504         dataerrln("FAIL: Can't create Relative date instance");
   2505         return;
   2506     }
   2507     UnicodeString result1;
   2508     full->format(now, result1, status);
   2509     Format *fullClone = full->clone();
   2510     delete full;
   2511     full = NULL;
   2512 
   2513     UnicodeString result2;
   2514     fullClone->format(now, result2, status);
   2515     ASSERT_OK(status);
   2516     if (result1 != result2) {
   2517         errln("FAIL: Clone returned different result from non-clone.");
   2518     }
   2519     delete fullClone;
   2520 }
   2521 
   2522 void DateFormatTest::TestHostClone(void)
   2523 {
   2524     /*
   2525     Verify that a cloned formatter gives the same results
   2526     and is useable after the original has been deleted.
   2527     */
   2528     // This is mainly important on Windows.
   2529     UErrorCode status = U_ZERO_ERROR;
   2530     Locale loc("en_US@compat=host");
   2531     UDate now = Calendar::getNow();
   2532     DateFormat *full = DateFormat::createDateInstance(DateFormat::kFull, loc);
   2533     if (full == NULL) {
   2534         dataerrln("FAIL: Can't create host date instance");
   2535         return;
   2536     }
   2537     UnicodeString result1;
   2538     full->format(now, result1, status);
   2539     Format *fullClone = full->clone();
   2540     delete full;
   2541     full = NULL;
   2542 
   2543     UnicodeString result2;
   2544     fullClone->format(now, result2, status);
   2545     ASSERT_OK(status);
   2546     if (result1 != result2) {
   2547         errln("FAIL: Clone returned different result from non-clone.");
   2548     }
   2549     delete fullClone;
   2550 }
   2551 
   2552 void DateFormatTest::TestHebrewClone(void)
   2553 {
   2554     /*
   2555     Verify that a cloned formatter gives the same results
   2556     and is useable after the original has been deleted.
   2557     */
   2558     UErrorCode status = U_ZERO_ERROR;
   2559     Locale loc("he@calendar=hebrew");
   2560     UDate now = Calendar::getNow();
   2561     LocalPointer<DateFormat> fmt(
   2562             DateFormat::createDateInstance(DateFormat::kLong, loc));
   2563     if (fmt.isNull()) {
   2564         dataerrln("FAIL: Can't create Hebrew date instance");
   2565         return;
   2566     }
   2567     UnicodeString result1;
   2568     fmt->format(now, result1, status);
   2569     LocalPointer<Format> fmtClone(fmt->clone());
   2570 
   2571     // free fmt to be sure that fmtClone is independent of fmt.
   2572     fmt.adoptInstead(NULL);
   2573 
   2574     UnicodeString result2;
   2575     fmtClone->format(now, result2, status);
   2576     ASSERT_OK(status);
   2577     if (result1 != result2) {
   2578         errln("FAIL: Clone returned different result from non-clone.");
   2579     }
   2580 }
   2581 
   2582 static UBool getActualAndValidLocales(
   2583         const Format &fmt, Locale &valid, Locale &actual) {
   2584     const SimpleDateFormat* dat = dynamic_cast<const SimpleDateFormat*>(&fmt);
   2585     if (dat == NULL) {
   2586         return FALSE;
   2587     }
   2588     const DateFormatSymbols *sym = dat->getDateFormatSymbols();
   2589     if (sym == NULL) {
   2590         return FALSE;
   2591     }
   2592     UErrorCode status = U_ZERO_ERROR;
   2593     valid = sym->getLocale(ULOC_VALID_LOCALE, status);
   2594     actual = sym->getLocale(ULOC_ACTUAL_LOCALE, status);
   2595     return U_SUCCESS(status);
   2596 }
   2597 
   2598 void DateFormatTest::TestDateFormatSymbolsClone(void)
   2599 {
   2600     /*
   2601     Verify that a cloned formatter gives the same results
   2602     and is useable after the original has been deleted.
   2603     */
   2604     Locale loc("de_CH_LUCERNE");
   2605     LocalPointer<DateFormat> fmt(
   2606             DateFormat::createDateInstance(DateFormat::kDefault, loc));
   2607     if (fmt.isNull()) {
   2608         dataerrln("FAIL: DateFormat::createDateInstance failed for %s", loc.getName());
   2609         return;
   2610     }
   2611     Locale valid1;
   2612     Locale actual1;
   2613     if (!getActualAndValidLocales(*fmt, valid1, actual1)) {
   2614         dataerrln("FAIL: Could not fetch valid + actual locales");
   2615         return;
   2616     }
   2617     LocalPointer<Format> fmtClone(fmt->clone());
   2618 
   2619     // Free fmt to be sure that fmtClone is really independent of fmt.
   2620     fmt.adoptInstead(NULL);
   2621     Locale valid2;
   2622     Locale actual2;
   2623     if (!getActualAndValidLocales(*fmtClone, valid2, actual2)) {
   2624         errln("FAIL: Could not fetch valid + actual locales");
   2625         return;
   2626     }
   2627     if (valid1 != valid2 || actual1 != actual2) {
   2628         errln("Date format symbol locales of clone don't match original");
   2629     }
   2630 }
   2631 
   2632 void DateFormatTest::TestTimeZoneDisplayName()
   2633 {
   2634     // This test data was ported from ICU4J.  Don't know why the 6th column in there because it's not being
   2635     // used currently.
   2636     const char *fallbackTests[][6]  = {
   2637         { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
   2638         { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
   2639         { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZZ", "-08:00", "-8:00" },
   2640         { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "PST", "America/Los_Angeles" },
   2641         { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "Pacific Standard Time", "America/Los_Angeles" },
   2642         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
   2643         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
   2644         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "PDT", "America/Los_Angeles" },
   2645         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "Pacific Daylight Time", "America/Los_Angeles" },
   2646         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "PT", "America/Los_Angeles" },
   2647         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Pacific Time", "America/Los_Angeles" },
   2648         { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "Los Angeles Time", "America/Los_Angeles" },
   2649         { "en_GB", "America/Los_Angeles", "2004-01-15T12:00:00Z", "z", "GMT-8", "America/Los_Angeles" },
   2650         { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "Z", "-0700", "-7:00" },
   2651         { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
   2652         { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "z", "MST", "America/Phoenix" },
   2653         { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "zzzz", "Mountain Standard Time", "America/Phoenix" },
   2654         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
   2655         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
   2656         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "z", "MST", "America/Phoenix" },
   2657         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "zzzz", "Mountain Standard Time", "America/Phoenix" },
   2658         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "v", "MST", "America/Phoenix" },
   2659         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "vvvv", "Mountain Standard Time", "America/Phoenix" },
   2660         { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "VVVV", "Phoenix Time", "America/Phoenix" },
   2661 
   2662         { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2663         { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2664         { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2665         { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" },
   2666         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2667         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2668         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2669         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" },
   2670         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Time", "America/Buenos_Aires" },
   2671         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentina Standard Time", "America/Buenos_Aires" },
   2672         { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "VVVV", "Buenos Aires Time", "America/Buenos_Aires" },
   2673 
   2674         { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2675         { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2676         { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2677         { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" },
   2678         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2679         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2680         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2681         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" },
   2682         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Time", "America/Buenos_Aires" },
   2683         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentina Standard Time", "America/Buenos_Aires" },
   2684         { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "VVVV", "Buenos Aires Time", "America/Buenos_Aires" },
   2685 
   2686         { "en", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
   2687         { "en", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
   2688         { "en", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
   2689         { "en", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "Cuba Standard Time", "-5:00" },
   2690         { "en", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
   2691         { "en", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
   2692         { "en", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
   2693         { "en", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "Cuba Daylight Time", "-4:00" },
   2694         { "en", "America/Havana", "2004-07-15T00:00:00Z", "v", "Cuba Time", "America/Havana" },
   2695         { "en", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Cuba Time", "America/Havana" },
   2696         { "en", "America/Havana", "2004-07-15T00:00:00Z", "VVVV", "Cuba Time", "America/Havana" },
   2697 
   2698         { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   2699         { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
   2700         { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
   2701         { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "Australian Eastern Daylight Time", "+11:00" },
   2702         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   2703         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
   2704         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
   2705         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "Australian Eastern Standard Time", "+10:00" },
   2706         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Sydney Time", "Australia/Sydney" },
   2707         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Eastern Australia Time", "Australia/Sydney" },
   2708         { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "VVVV", "Sydney Time", "Australia/Sydney" },
   2709 
   2710         { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   2711         { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
   2712         { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
   2713         { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "Australian Eastern Daylight Time", "+11:00" },
   2714         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   2715         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
   2716         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
   2717         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "Australian Eastern Standard Time", "+10:00" },
   2718         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Sydney Time", "Australia/Sydney" },
   2719         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Eastern Australia Time", "Australia/Sydney" },
   2720         { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "VVVV", "Sydney Time", "Australia/Sydney" },
   2721 
   2722         { "en", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
   2723         { "en", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
   2724         { "en", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
   2725         { "en", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "Greenwich Mean Time", "+0:00" },
   2726         { "en", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
   2727         { "en", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
   2728         { "en", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "Europe/London" },
   2729         { "en", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "British Summer Time", "Europe/London" },
   2730     // icu en.txt has exemplar city for this time zone
   2731         { "en", "Europe/London", "2004-07-15T00:00:00Z", "v", "United Kingdom Time", "Europe/London" },
   2732         { "en", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "United Kingdom Time", "Europe/London" },
   2733         { "en", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "United Kingdom Time", "Europe/London" },
   2734 
   2735         { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2736         { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2737         { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2738         { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   2739         { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2740         { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2741         { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2742         { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   2743         { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
   2744         { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
   2745 
   2746         // JB#5150
   2747         { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
   2748         { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
   2749         { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
   2750         { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "India Standard Time", "+5:30" },
   2751         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
   2752         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
   2753         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
   2754         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "India Standard Time", "+5:30" },
   2755         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "India Time", "Asia/Calcutta" },
   2756         { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "India Standard Time", "Asia/Calcutta" },
   2757 
   2758         // Proper CLDR primary zone support #9733
   2759         { "en", "America/Santiago", "2013-01-01T00:00:00Z", "VVVV", "Chile Time", "America/Santiago" },
   2760         { "en", "Pacific/Easter", "2013-01-01T00:00:00Z", "VVVV", "Easter Time", "Pacific/Easter" },
   2761 
   2762         // ==========
   2763 
   2764         { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
   2765         { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
   2766         { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "-8:00" },
   2767         { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "Nordamerikanische Westk\\u00fcsten-Normalzeit", "-8:00" },
   2768         { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
   2769         { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
   2770         { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "-7:00" },
   2771         { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "Nordamerikanische Westk\\u00fcsten-Sommerzeit", "-7:00" },
   2772         { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "Los Angeles Zeit", "America/Los_Angeles" },
   2773         { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Nordamerikanische Westk\\u00fcstenzeit", "America/Los_Angeles" },
   2774 
   2775         { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2776         { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2777         { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2778         { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" },
   2779         { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2780         { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2781         { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2782         { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" },
   2783         { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Zeit", "America/Buenos_Aires" },
   2784         { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentinische Normalzeit", "America/Buenos_Aires" },
   2785 
   2786         { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2787         { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2788         { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2789         { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" },
   2790         { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2791         { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2792         { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2793         { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" },
   2794         { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Zeit", "America/Buenos_Aires" },
   2795         { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentinische Normalzeit", "America/Buenos_Aires" },
   2796 
   2797         { "de", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
   2798         { "de", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
   2799         { "de", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
   2800         { "de", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "Kubanische Normalzeit", "-5:00" },
   2801         { "de", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
   2802         { "de", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
   2803         { "de", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
   2804         { "de", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "Kubanische Sommerzeit", "-4:00" },
   2805         { "de", "America/Havana", "2004-07-15T00:00:00Z", "v", "Kuba Zeit", "America/Havana" },
   2806         { "de", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Kubanische Zeit", "America/Havana" },
   2807         // added to test proper fallback of country name
   2808         { "de_CH", "America/Havana", "2004-07-15T00:00:00Z", "v", "Kuba Zeit", "America/Havana" },
   2809         { "de_CH", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Kubanische Zeit", "America/Havana" },
   2810 
   2811         { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   2812         { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
   2813         { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
   2814         { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "Ostaustralische Sommerzeit", "+11:00" },
   2815         { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   2816         { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
   2817         { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
   2818         { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "Ostaustralische Normalzeit", "+10:00" },
   2819         { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Sydney Zeit", "Australia/Sydney" },
   2820         { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Ostaustralische Zeit", "Australia/Sydney" },
   2821 
   2822         { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   2823         { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
   2824         { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
   2825         { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "Ostaustralische Sommerzeit", "+11:00" },
   2826         { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   2827         { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
   2828         { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
   2829         { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "Ostaustralische Normalzeit", "+10:00" },
   2830         { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Sydney Zeit", "Australia/Sydney" },
   2831         { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Ostaustralische Zeit", "Australia/Sydney" },
   2832 
   2833         { "de", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
   2834         { "de", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
   2835         { "de", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
   2836         { "de", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "Mittlere Greenwich-Zeit", "+0:00" },
   2837         { "de", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
   2838         { "de", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
   2839         { "de", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
   2840         { "de", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "Britische Sommerzeit", "+1:00" },
   2841         { "de", "Europe/London", "2004-07-15T00:00:00Z", "v", "Vereinigtes K\\u00f6nigreich Zeit", "Europe/London" },
   2842         { "de", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "Vereinigtes K\\u00f6nigreich Zeit", "Europe/London" },
   2843 
   2844         { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2845         { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2846         { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2847         { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   2848         { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2849         { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2850         { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2851         { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   2852         { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
   2853         { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
   2854 
   2855         // JB#5150
   2856         { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
   2857         { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
   2858         { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
   2859         { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "Indische Zeit", "+5:30" },
   2860         { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
   2861         { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
   2862         { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
   2863         { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "Indische Zeit", "+5:30" },
   2864         { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "Indien Zeit", "Asia/Calcutta" },
   2865         { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "Indische Zeit", "Asia/Calcutta" },
   2866 
   2867         // ==========
   2868 
   2869         { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
   2870         { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
   2871         { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "America/Los_Angeles" },
   2872         { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u6807\\u51c6\\u65f6\\u95f4", "America/Los_Angeles" },
   2873         { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
   2874         { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
   2875         { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "America/Los_Angeles" },
   2876         { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u590f\\u4ee4\\u65f6\\u95f4", "America/Los_Angeles" },
   2877     // icu zh.txt has exemplar city for this time zone
   2878         { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4", "America/Los_Angeles" },
   2879         { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u65f6\\u95f4", "America/Los_Angeles" },
   2880 
   2881         { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2882         { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2883         { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2884         { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" },
   2885         { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2886         { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2887         { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2888         { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" },
   2889         { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u5E03\\u5B9C\\u8BFA\\u65AF\\u827E\\u5229\\u65AF\\u65F6\\u95F4", "America/Buenos_Aires" },
   2890         { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "America/Buenos_Aires" },
   2891 
   2892         { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2893         { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2894         { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2895         { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" },
   2896         { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2897         { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2898         { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2899         { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" },
   2900         { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u5E03\\u5B9C\\u8BFA\\u65AF\\u827E\\u5229\\u65AF\\u65F6\\u95F4", "America/Buenos_Aires" },
   2901         { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "America/Buenos_Aires" },
   2902 
   2903         { "zh", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
   2904         { "zh", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
   2905         { "zh", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
   2906         { "zh", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u53e4\\u5df4\\u6807\\u51c6\\u65f6\\u95f4", "-5:00" },
   2907         { "zh", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
   2908         { "zh", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
   2909         { "zh", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
   2910         { "zh", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u53e4\\u5df4\\u590f\\u4ee4\\u65f6\\u95f4", "-4:00" },
   2911         { "zh", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u53e4\\u5df4\\u65f6\\u95f4", "America/Havana" },
   2912         { "zh", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u53e4\\u5df4\\u65f6\\u95f4", "America/Havana" },
   2913 
   2914         { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   2915         { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
   2916         { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
   2917         { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u590f\\u4ee4\\u65f6\\u95f4", "+11:00" },
   2918         { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   2919         { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
   2920         { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
   2921         { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u6807\\u51c6\\u65f6\\u95f4", "+10:00" },
   2922     // icu zh.txt does not have info for this time zone
   2923         { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u6089\\u5C3C\\u65F6\\u95F4", "Australia/Sydney" },
   2924         { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u65f6\\u95f4", "Australia/Sydney" },
   2925 
   2926         { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   2927         { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
   2928         { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
   2929         { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u590f\\u4ee4\\u65f6\\u95f4", "+11:00" },
   2930         { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   2931         { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
   2932         { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
   2933         { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u6807\\u51c6\\u65f6\\u95f4", "+10:00" },
   2934         { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u6089\\u5C3C\\u65F6\\u95F4", "Australia/Sydney" },
   2935         { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u65f6\\u95f4", "Australia/Sydney" },
   2936 
   2937         { "zh", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
   2938         { "zh", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
   2939         { "zh", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
   2940         { "zh", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
   2941         { "zh", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
   2942         { "zh", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u683C\\u6797\\u5C3C\\u6CBB\\u6807\\u51C6\\u65F6\\u95F4", "+0:00" },
   2943         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
   2944         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
   2945         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
   2946         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u82f1\\u56fd\\u590f\\u4ee4\\u65f6\\u95f4", "+1:00" },
   2947         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" },
   2948         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" },
   2949         { "zh", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" },
   2950 
   2951         { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2952         { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2953         { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2954         { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   2955         { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2956         { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2957         { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2958         { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   2959         { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
   2960         { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
   2961 
   2962         // JB#5150
   2963         { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
   2964         { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
   2965         { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
   2966         { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u5370\\u5ea6\\u65f6\\u95f4", "+5:30" },
   2967         { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
   2968         { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
   2969         { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
   2970         { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u5370\\u5ea6\\u65f6\\u95f4", "+5:30" },
   2971         { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u5370\\u5ea6\\u65f6\\u95f4", "Asia/Calcutta" },
   2972         { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u5370\\u5ea6\\u65f6\\u95f4", "Asia/Calcutta" },
   2973 
   2974         // ==========
   2975 
   2976         { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
   2977         { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
   2978         { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "-8:00" },
   2979         { "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" },
   2980         { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
   2981         { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
   2982         { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "-7:00" },
   2983         { "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" },
   2984         { "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" },
   2985         { "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" },
   2986 
   2987         { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2988         { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2989         { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2990         { "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" },
   2991         { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2992         { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   2993         { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   2994         { "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" },
   2995         { "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" },
   2996         { "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" },
   2997 
   2998         { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   2999         { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3000         { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3001         { "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" },
   3002         { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3003         { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3004         { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3005         { "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" },
   3006         { "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" },
   3007         { "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" },
   3008 
   3009         { "hi", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
   3010         { "hi", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
   3011         { "hi", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
   3012         { "hi", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u092e\\u093e\\u0928\\u0915 \\u0938\\u092e\\u092f", "-5:00" },
   3013         { "hi", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
   3014         { "hi", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
   3015         { "hi", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
   3016         { "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" },
   3017         { "hi", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0938\\u092E\\u092F", "America/Havana" },
   3018         { "hi", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0938\\u092e\\u092f", "America/Havana" },
   3019 
   3020         { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   3021         { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
   3022         { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
   3023         { "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" },
   3024         { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   3025         { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
   3026         { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
   3027         { "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" },
   3028         { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u0938\\u093F\\u0921\\u0928\\u0940 \\u0938\\u092E\\u092F", "Australia/Sydney" },
   3029         { "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" },
   3030 
   3031         { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   3032         { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
   3033         { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
   3034         { "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" },
   3035         { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   3036         { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
   3037         { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
   3038         { "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" },
   3039         { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u0938\\u093F\\u0921\\u0928\\u0940 \\u0938\\u092E\\u092F", "Australia/Sydney" },
   3040         { "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" },
   3041 
   3042         { "hi", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
   3043         { "hi", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
   3044         { "hi", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
   3045         { "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" },
   3046         { "hi", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
   3047         { "hi", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
   3048         { "hi", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
   3049         { "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" },
   3050         { "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" },
   3051         { "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" },
   3052 
   3053         { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3054         { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3055         { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3056         { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   3057         { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3058         { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3059         { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3060         { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   3061         { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
   3062         { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
   3063 
   3064         { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
   3065         { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
   3066         { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "IST", "+5:30" },
   3067         { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "+5:30" },
   3068         { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
   3069         { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
   3070         { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "IST", "+05:30" },
   3071         { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "+5:30" },
   3072         { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "IST", "Asia/Calcutta" },
   3073         { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "Asia/Calcutta" },
   3074 
   3075         // ==========
   3076 
   3077         { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
   3078         { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-08:00", "-8:00" },
   3079         { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-8", "America/Los_Angeles" },
   3080         { "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" },
   3081         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
   3082         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-07:00", "-7:00" },
   3083         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-7", "America/Los_Angeles" },
   3084         { "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" },
   3085     // icu bg.txt has exemplar city for this time zone
   3086         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u041B\\u043E\\u0441 \\u0410\\u043D\\u0434\\u0436\\u0435\\u043B\\u0438\\u0441", "America/Los_Angeles" },
   3087         { "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" },
   3088         { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "\\u041B\\u043E\\u0441 \\u0410\\u043D\\u0434\\u0436\\u0435\\u043B\\u0438\\u0441", "America/Los_Angeles" },
   3089 
   3090         { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3091         { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
   3092         { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
   3093         { "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" },
   3094         { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3095         { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
   3096         { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
   3097         { "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" },
   3098         { "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" },
   3099         { "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" },
   3100 
   3101         { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3102         { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
   3103         { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
   3104         { "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" },
   3105         { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3106         { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
   3107         { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
   3108         { "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" },
   3109     // icu bg.txt does not have info for this time zone
   3110         { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u0411\\u0443\\u0435\\u043D\\u043E\\u0441 \\u0410\\u0439\\u0440\\u0435\\u0441", "America/Buenos_Aires" },
   3111         { "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" },
   3112 
   3113         { "bg", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
   3114         { "bg", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-05:00", "-5:00" },
   3115         { "bg", "America/Havana", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-5", "-5:00" },
   3116         { "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" },
   3117         { "bg", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
   3118         { "bg", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-04:00", "-4:00" },
   3119         { "bg", "America/Havana", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-4", "-4:00" },
   3120         { "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" },
   3121         { "bg", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u041a\\u0443\\u0431\\u0430", "America/Havana" },
   3122         { "bg", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u041a\\u0443\\u0431\\u0438\\u043d\\u0441\\u043a\\u043e \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Havana" },
   3123 
   3124         { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   3125         { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11:00", "+11:00" },
   3126         { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11", "+11:00" },
   3127         { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u0418\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E\\u0430\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u0439\\u0441\\u043A\\u043E \\u043B\\u044F\\u0442\\u043D\\u043E \\u0447\\u0430\\u0441\\u043E\\u0432\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "+11:00" },
   3128         { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   3129         { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10:00", "+10:00" },
   3130         { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10", "+10:00" },
   3131         { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u0418\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E\\u0430\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u0439\\u0441\\u043A\\u043E \\u0441\\u0442\\u0430\\u043D\\u0434\\u0430\\u0440\\u0442\\u043D\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "+10:00" },
   3132         { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u0421\\u0438\\u0434\\u043D\\u0438", "Australia/Sydney" },
   3133         { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u0418\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E\\u0430\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u0439\\u0441\\u043A\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "Australia/Sydney" },
   3134 
   3135         { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   3136         { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11:00", "+11:00" },
   3137         { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11", "+11:00" },
   3138         { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u0418\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E\\u0430\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u0439\\u0441\\u043A\\u043E \\u043B\\u044F\\u0442\\u043D\\u043E \\u0447\\u0430\\u0441\\u043E\\u0432\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "+11:00" },
   3139         { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   3140         { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10:00", "+10:00" },
   3141         { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10", "+10:00" },
   3142         { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u0418\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E\\u0430\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u0439\\u0441\\u043A\\u043E \\u0441\\u0442\\u0430\\u043D\\u0434\\u0430\\u0440\\u0442\\u043D\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "+10:00" },
   3143         { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u0421\\u0438\\u0434\\u043D\\u0438", "Australia/Sydney" },
   3144         { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u0418\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E\\u0430\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u0439\\u0441\\u043A\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "Australia/Sydney" },
   3145 
   3146         { "bg", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
   3147         { "bg", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" },
   3148         { "bg", "Europe/London", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" },
   3149         { "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" },
   3150         { "bg", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
   3151         { "bg", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+01:00", "+1:00" },
   3152         { "bg", "Europe/London", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+1", "+1:00" },
   3153         { "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" },
   3154         { "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" },
   3155         { "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" },
   3156 
   3157         { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3158         { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
   3159         { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
   3160         { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
   3161         { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3162         { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
   3163         { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
   3164         { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
   3165         { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
   3166         { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
   3167 
   3168         // JB#5150
   3169         { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
   3170         { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+05:30", "+5:30" },
   3171         { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+5:30", "+5:30" },
   3172         { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u0418\\u043D\\u0434\\u0438\\u0439\\u0441\\u043A\\u043E \\u0432\\u0440\\u0435\\u043c\\u0435", "+5:30" },
   3173         { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
   3174         { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+05:30", "+5:30" },
   3175         { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+5:30", "+05:30" },
   3176         { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u0418\\u043D\\u0434\\u0438\\u0439\\u0441\\u043A\\u043E \\u0432\\u0440\\u0435\\u043c\\u0435", "+5:30" },
   3177         { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u0418\\u043D\\u0434\\u0438\\u044F", "Asia/Calcutta" },
   3178         { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u0418\\u043D\\u0434\\u0438\\u0439\\u0441\\u043A\\u043E \\u0432\\u0440\\u0435\\u043c\\u0435", "Asia/Calcutta" },
   3179     // ==========
   3180 
   3181         { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
   3182         { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
   3183         { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "America/Los_Angeles" },
   3184         { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u30a2\\u30e1\\u30ea\\u30ab\\u592a\\u5e73\\u6d0b\\u6a19\\u6e96\\u6642", "America/Los_Angeles" },
   3185         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-700" },
   3186         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
   3187         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "America/Los_Angeles" },
   3188         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u30a2\\u30e1\\u30ea\\u30ab\\u592a\\u5e73\\u6d0b\\u590f\\u6642\\u9593", "America/Los_Angeles" },
   3189     // icu ja.txt has exemplar city for this time zone
   3190         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u30ED\\u30B5\\u30F3\\u30BC\\u30EB\\u30B9\\u6642\\u9593", "America/Los_Angeles" },
   3191         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u30A2\\u30E1\\u30EA\\u30AB\\u592A\\u5e73\\u6D0B\\u6642\\u9593", "America/Los_Angeles" },
   3192         { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "\\u30ED\\u30B5\\u30F3\\u30BC\\u30EB\\u30B9\\u6642\\u9593", "America/Los_Angeles" },
   3193 
   3194         { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3195         { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3196         { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3197         { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" },
   3198         { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3199         { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3200         { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3201         { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" },
   3202     // icu ja.txt does not have info for this time zone
   3203         { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u30D6\\u30A8\\u30CE\\u30B9\\u30A2\\u30A4\\u30EC\\u30B9\\u6642\\u9593", "America/Buenos_Aires" },
   3204         { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "America/Buenos_Aires" },
   3205 
   3206         { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3207         { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3208         { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3209         { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" },
   3210         { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3211         { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3212         { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3213         { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" },
   3214         { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u30D6\\u30A8\\u30CE\\u30B9\\u30A2\\u30A4\\u30EC\\u30B9\\u6642\\u9593", "America/Buenos_Aires" },
   3215         { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "America/Buenos_Aires" },
   3216 
   3217         { "ja", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
   3218         { "ja", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
   3219         { "ja", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
   3220         { "ja", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u30AD\\u30E5\\u30FC\\u30D0\\u6A19\\u6E96\\u6642", "-5:00" },
   3221         { "ja", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
   3222         { "ja", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
   3223         { "ja", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
   3224         { "ja", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u30AD\\u30E5\\u30FC\\u30D0\\u590F\\u6642\\u9593", "-4:00" },
   3225         { "ja", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u30ad\\u30e5\\u30fc\\u30d0\\u6642\\u9593", "America/Havana" },
   3226         { "ja", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u30ad\\u30e5\\u30fc\\u30d0\\u6642\\u9593", "America/Havana" },
   3227 
   3228         { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   3229         { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
   3230         { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
   3231         { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u590F\\u6642\\u9593", "+11:00" },
   3232         { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   3233         { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
   3234         { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
   3235         { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6A19\\u6E96\\u6642", "+10:00" },
   3236     // icu ja.txt does not have info for this time zone
   3237         { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u30B7\\u30C9\\u30CB\\u30FC\\u6642\\u9593", "Australia/Sydney" },
   3238         { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6642\\u9593", "Australia/Sydney" },
   3239 
   3240         { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   3241         { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
   3242         { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
   3243         { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u590F\\u6642\\u9593", "+11:00" },
   3244         { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   3245         { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
   3246         { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
   3247         { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6A19\\u6E96\\u6642", "+10:00" },
   3248         { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u30B7\\u30C9\\u30CB\\u30FC\\u6642\\u9593", "Australia/Sydney" },
   3249         { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6642\\u9593", "Australia/Sydney" },
   3250 
   3251         { "ja", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
   3252         { "ja", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
   3253         { "ja", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
   3254         { "ja", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u30B0\\u30EA\\u30CB\\u30C3\\u30B8\\u6A19\\u6E96\\u6642", "+0:00" },
   3255         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
   3256         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
   3257         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
   3258         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u82f1\\u56fd\\u590f\\u6642\\u9593", "+1:00" },
   3259         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u30a4\\u30ae\\u30ea\\u30b9\\u6642\\u9593", "Europe/London" },
   3260         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u30a4\\u30ae\\u30ea\\u30b9\\u6642\\u9593", "Europe/London" },
   3261         { "ja", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "\\u30a4\\u30ae\\u30ea\\u30b9\\u6642\\u9593", "Europe/London" },
   3262 
   3263         { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3264         { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3265         { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3266         { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   3267         { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3268         { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3269         { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3270         { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   3271         { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
   3272         { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
   3273 
   3274         // JB#5150
   3275         { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
   3276         { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
   3277         { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
   3278         { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u30A4\\u30F3\\u30C9\\u6A19\\u6E96\\u6642", "+5:30" },
   3279         { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
   3280         { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
   3281         { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
   3282         { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u30A4\\u30F3\\u30C9\\u6A19\\u6E96\\u6642", "+5:30" },
   3283         { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u30A4\\u30F3\\u30C9\\u6642\\u9593", "Asia/Calcutta" },
   3284         { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u30A4\\u30F3\\u30C9\\u6A19\\u6E96\\u6642", "Asia/Calcutta" },
   3285 
   3286     // ==========
   3287 
   3288         { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
   3289         { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
   3290         { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "-8:00" },
   3291         { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "GMT-08:00", "-8:00" },
   3292         { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
   3293         { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
   3294         { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "-7:00" },
   3295         { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "GMT-07:00", "-7:00" },
   3296         { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "Los Angeles", "America/Los_Angeles" },
   3297         { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Los Angeles", "America/Los_Angeles" },
   3298 
   3299         { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3300         { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3301         { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3302         { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   3303         { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3304         { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3305         { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3306         { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   3307         { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires", "America/Buenos_Aires" },
   3308         { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Buenos Aires", "America/Buenos_Aires" },
   3309 
   3310         { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3311         { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3312         { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3313         { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   3314         { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3315         { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3316         { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3317         { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   3318         { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires", "America/Buenos_Aires" },
   3319         { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Buenos Aires", "America/Buenos_Aires" },
   3320 
   3321         { "ti", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
   3322         { "ti", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
   3323         { "ti", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
   3324         { "ti", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "GMT-05:00", "-5:00" },
   3325         { "ti", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
   3326         { "ti", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
   3327         { "ti", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
   3328         { "ti", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "GMT-04:00", "-4:00" },
   3329         { "ti", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u12A9\\u1263", "America/Havana" },
   3330         { "ti", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u12A9\\u1263", "America/Havana" },
   3331 
   3332         { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   3333         { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
   3334         { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
   3335         { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" },
   3336         { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   3337         { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
   3338         { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
   3339         { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" },
   3340         { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Sydney", "Australia/Sydney" },
   3341         { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Sydney", "Australia/Sydney" },
   3342 
   3343         { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
   3344         { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
   3345         { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
   3346         { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" },
   3347         { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
   3348         { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
   3349         { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
   3350         { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" },
   3351         { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Sydney", "Australia/Sydney" },
   3352         { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Sydney", "Australia/Sydney" },
   3353 
   3354         { "ti", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
   3355         { "ti", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
   3356         { "ti", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
   3357         { "ti", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "GMT", "+0:00" },
   3358         { "ti", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
   3359         { "ti", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
   3360         { "ti", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
   3361         { "ti", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "GMT+01:00", "+1:00" },
   3362         { "ti", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u12A5\\u1295\\u130D\\u120A\\u12DD", "Europe/London" },
   3363         { "ti", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u12A5\\u1295\\u130D\\u120A\\u12DD", "Europe/London" },
   3364 
   3365         { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3366         { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3367         { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3368         { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   3369         { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
   3370         { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
   3371         { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
   3372         { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
   3373         { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
   3374         { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
   3375 
   3376         // JB#5150
   3377         { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
   3378         { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
   3379         { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
   3380         { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
   3381         { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
   3382         { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
   3383         { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
   3384         { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
   3385         { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u1205\\u1295\\u12F2", "Alna/Calcutta" },
   3386         { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u1205\\u1295\\u12F2", "Asia/Calcutta" },
   3387 
   3388         // Ticket#8589 Partial location name to use country name if the zone is the golden
   3389         // zone for the time zone's country.
   3390         { "en_MX", "America/Chicago", "1995-07-15T00:00:00Z", "vvvv", "Central Time (United States)", "America/Chicago"},
   3391 
   3392         // Tests proper handling of time zones that should have empty sets when inherited from the parent.
   3393         // For example, en_GB understands CET as Central European Time, but en_HK, which inherits from en_GB
   3394         // does not
   3395         { "en_GB", "Europe/Paris", "2004-01-15T00:00:00Z", "zzzz", "Central European Standard Time", "+1:00"},
   3396         { "en_GB", "Europe/Paris", "2004-07-15T00:00:00Z", "zzzz", "Central European Summer Time", "+2:00"},
   3397         { "en_GB", "Europe/Paris", "2004-01-15T00:00:00Z", "z", "CET", "+1:00"},
   3398         { "en_GB", "Europe/Paris", "2004-07-15T00:00:00Z", "z", "CEST", "+2:00"},
   3399         { "en_HK", "Europe/Paris", "2004-01-15T00:00:00Z", "zzzz", "Central European Standard Time", "+1:00"},
   3400         { "en_HK", "Europe/Paris", "2004-07-15T00:00:00Z", "zzzz", "Central European Summer Time", "+2:00"},
   3401         { "en_HK", "Europe/Paris", "2004-01-15T00:00:00Z", "z", "GMT+1", "+1:00"},
   3402         { "en_HK", "Europe/Paris", "2004-07-15T00:00:00Z", "z", "GMT+2", "+2:00"},
   3403 
   3404         { NULL, NULL, NULL, NULL, NULL, NULL },
   3405     };
   3406 
   3407     UErrorCode status = U_ZERO_ERROR;
   3408     Calendar *cal = GregorianCalendar::createInstance(status);
   3409     if (failure(status, "GregorianCalendar::createInstance", TRUE)) return;
   3410     SimpleDateFormat testfmt(UnicodeString("yyyy-MM-dd'T'HH:mm:ss'Z'"), status);
   3411     if (failure(status, "SimpleDateFormat constructor", TRUE)) return;
   3412     testfmt.setTimeZone(*TimeZone::getGMT());
   3413 
   3414     for (int i = 0; fallbackTests[i][0]; i++) {
   3415         const char **testLine = fallbackTests[i];
   3416         UnicodeString info[5];
   3417         for ( int j = 0 ; j < 5 ; j++ ) {
   3418             info[j] = UnicodeString(testLine[j], -1, US_INV);
   3419         }
   3420         info[4] = info[4].unescape();
   3421         logln("%s;%s;%s;%s", testLine[0], testLine[1], testLine[2], testLine[3]);
   3422 
   3423         TimeZone *tz = TimeZone::createTimeZone(info[1]);
   3424 
   3425         UDate d = testfmt.parse(testLine[2], status);
   3426         cal->setTime(d, status);
   3427         if (U_FAILURE(status)) {
   3428             errln(UnicodeString("Failed to set date: ") + testLine[2]);
   3429         }
   3430 
   3431         SimpleDateFormat fmt(info[3], Locale(testLine[0]),status);
   3432         ASSERT_OK(status);
   3433         cal->adoptTimeZone(tz);
   3434         UnicodeString result;
   3435         FieldPosition pos(FieldPosition::DONT_CARE);
   3436         fmt.format(*cal,result,pos);
   3437         if (result != info[4]) {
   3438             errln(info[0] + ";" + info[1] + ";" + info[2] + ";" + info[3] + " expected: '" +
   3439                   info[4] + "' but got: '" + result + "'");
   3440         }
   3441     }
   3442     delete cal;
   3443 }
   3444 
   3445 void DateFormatTest::TestRoundtripWithCalendar(void) {
   3446     UErrorCode status = U_ZERO_ERROR;
   3447 
   3448     TimeZone *tz = TimeZone::createTimeZone("Europe/Paris");
   3449     TimeZone *gmt = TimeZone::createTimeZone("Etc/GMT");
   3450 
   3451     Calendar *calendars[] = {
   3452         Calendar::createInstance(*tz, Locale("und@calendar=gregorian"), status),
   3453         Calendar::createInstance(*tz, Locale("und@calendar=buddhist"), status),
   3454 //        Calendar::createInstance(*tz, Locale("und@calendar=hebrew"), status),
   3455         Calendar::createInstance(*tz, Locale("und@calendar=islamic"), status),
   3456         Calendar::createInstance(*tz, Locale("und@calendar=japanese"), status),
   3457         NULL
   3458     };
   3459     if (U_FAILURE(status)) {
   3460         dataerrln("Failed to initialize calendars: %s", u_errorName(status));
   3461         for (int i = 0; calendars[i] != NULL; i++) {
   3462             delete calendars[i];
   3463         }
   3464         return;
   3465     }
   3466 
   3467     //FIXME The formatters commented out below are currently failing because of
   3468     // the calendar calculation problem reported by #6691
   3469 
   3470     // The order of test formatters must match the order of calendars above.
   3471     DateFormat *formatters[] = {
   3472         DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("en_US")), //calendar=gregorian
   3473         DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("th_TH")), //calendar=buddhist
   3474 //        DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("he_IL@calendar=hebrew")),
   3475         DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("ar_EG@calendar=islamic")),
   3476 //        DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("ja_JP@calendar=japanese")),
   3477         NULL
   3478     };
   3479 
   3480     UDate d = Calendar::getNow();
   3481     UnicodeString buf;
   3482     FieldPosition fpos;
   3483     ParsePosition ppos;
   3484 
   3485     for (int i = 0; formatters[i] != NULL; i++) {
   3486         buf.remove();
   3487         fpos.setBeginIndex(0);
   3488         fpos.setEndIndex(0);
   3489         calendars[i]->setTime(d, status);
   3490 
   3491         // Normal case output - the given calendar matches the calendar
   3492         // used by the formatter
   3493         formatters[i]->format(*calendars[i], buf, fpos);
   3494         UnicodeString refStr(buf);
   3495 
   3496         for (int j = 0; calendars[j] != NULL; j++) {
   3497             if (j == i) {
   3498                 continue;
   3499             }
   3500             buf.remove();
   3501             fpos.setBeginIndex(0);
   3502             fpos.setEndIndex(0);
   3503             calendars[j]->setTime(d, status);
   3504 
   3505             // Even the different calendar type is specified,
   3506             // we should get the same result.
   3507             formatters[i]->format(*calendars[j], buf, fpos);
   3508             if (refStr != buf) {
   3509                 errln((UnicodeString)"FAIL: Different format result with a different calendar for the same time -"
   3510                         + "\n Reference calendar type=" + calendars[i]->getType()
   3511                         + "\n Another calendar type=" + calendars[j]->getType()
   3512                         + "\n Expected result=" + refStr
   3513                         + "\n Actual result=" + buf);
   3514             }
   3515         }
   3516 
   3517         calendars[i]->setTimeZone(*gmt);
   3518         calendars[i]->clear();
   3519         ppos.setErrorIndex(-1);
   3520         ppos.setIndex(0);
   3521 
   3522         // Normal case parse result - the given calendar matches the calendar
   3523         // used by the formatter
   3524         formatters[i]->parse(refStr, *calendars[i], ppos);
   3525 
   3526         for (int j = 0; calendars[j] != NULL; j++) {
   3527             if (j == i) {
   3528                 continue;
   3529             }
   3530             calendars[j]->setTimeZone(*gmt);
   3531             calendars[j]->clear();
   3532             ppos.setErrorIndex(-1);
   3533             ppos.setIndex(0);
   3534 
   3535             // Even the different calendar type is specified,
   3536             // we should get the same time and time zone.
   3537             formatters[i]->parse(refStr, *calendars[j], ppos);
   3538             if (calendars[i]->getTime(status) != calendars[j]->getTime(status)
   3539                 || calendars[i]->getTimeZone() != calendars[j]->getTimeZone()) {
   3540                 UnicodeString tzid;
   3541                 errln((UnicodeString)"FAIL: Different parse result with a different calendar for the same string -"
   3542                         + "\n Reference calendar type=" + calendars[i]->getType()
   3543                         + "\n Another calendar type=" + calendars[j]->getType()
   3544                         + "\n Date string=" + refStr
   3545                         + "\n Expected time=" + calendars[i]->getTime(status)
   3546                         + "\n Expected time zone=" + calendars[i]->getTimeZone().getID(tzid)
   3547                         + "\n Actual time=" + calendars[j]->getTime(status)
   3548                         + "\n Actual time zone=" + calendars[j]->getTimeZone().getID(tzid));
   3549             }
   3550         }
   3551         if (U_FAILURE(status)) {
   3552             errln((UnicodeString)"FAIL: " + u_errorName(status));
   3553             break;
   3554         }
   3555     }
   3556 
   3557     delete tz;
   3558     delete gmt;
   3559     for (int i = 0; calendars[i] != NULL; i++) {
   3560         delete calendars[i];
   3561     }
   3562     for (int i = 0; formatters[i] != NULL; i++) {
   3563         delete formatters[i];
   3564     }
   3565 }
   3566 
   3567 /*
   3568 void DateFormatTest::TestRelativeError(void)
   3569 {
   3570     UErrorCode status;
   3571     Locale en("en");
   3572 
   3573     DateFormat *en_reltime_reldate =         DateFormat::createDateTimeInstance(DateFormat::kFullRelative,DateFormat::kFullRelative,en);
   3574     if(en_reltime_reldate == NULL) {
   3575         logln("PASS: rel date/rel time failed");
   3576     } else {
   3577         errln("FAIL: rel date/rel time created, should have failed.");
   3578         delete en_reltime_reldate;
   3579     }
   3580 }
   3581 
   3582 void DateFormatTest::TestRelativeOther(void)
   3583 {
   3584     logln("Nothing in this test. When we get more data from CLDR, put in some tests of -2, +2, etc. ");
   3585 }
   3586 */
   3587 
   3588 void DateFormatTest::Test6338(void)
   3589 {
   3590     UErrorCode status = U_ZERO_ERROR;
   3591 
   3592     SimpleDateFormat *fmt1 = new SimpleDateFormat(UnicodeString("y-M-d"), Locale("ar"), status);
   3593     if (failure(status, "new SimpleDateFormat", TRUE)) return;
   3594 
   3595     UDate dt1 = date(2008-1900, UCAL_JUNE, 10, 12, 00);
   3596     UnicodeString str1;
   3597     str1 = fmt1->format(dt1, str1);
   3598     logln(str1);
   3599 
   3600     UDate dt11 = fmt1->parse(str1, status);
   3601     failure(status, "fmt->parse");
   3602 
   3603     UnicodeString str11;
   3604     str11 = fmt1->format(dt11, str11);
   3605     logln(str11);
   3606 
   3607     if (str1 != str11) {
   3608         errln((UnicodeString)"FAIL: Different dates str1:" + str1
   3609             + " str2:" + str11);
   3610     }
   3611     delete fmt1;
   3612 
   3613     /////////////////
   3614 
   3615     status = U_ZERO_ERROR;
   3616     SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("y M d"), Locale("ar"), status);
   3617     failure(status, "new SimpleDateFormat");
   3618 
   3619     UDate dt2 = date(2008-1900, UCAL_JUNE, 10, 12, 00);
   3620     UnicodeString str2;
   3621     str2 = fmt2->format(dt2, str2);
   3622     logln(str2);
   3623 
   3624     UDate dt22 = fmt2->parse(str2, status);
   3625     failure(status, "fmt->parse");
   3626 
   3627     UnicodeString str22;
   3628     str22 = fmt2->format(dt22, str22);
   3629     logln(str22);
   3630 
   3631     if (str2 != str22) {
   3632         errln((UnicodeString)"FAIL: Different dates str1:" + str2
   3633             + " str2:" + str22);
   3634     }
   3635     delete fmt2;
   3636 
   3637     /////////////////
   3638 
   3639     status = U_ZERO_ERROR;
   3640     SimpleDateFormat *fmt3 = new SimpleDateFormat(UnicodeString("y-M-d"), Locale("en-us"), status);
   3641     failure(status, "new SimpleDateFormat");
   3642 
   3643     UDate dt3 = date(2008-1900, UCAL_JUNE, 10, 12, 00);
   3644     UnicodeString str3;
   3645     str3 = fmt3->format(dt3, str3);
   3646     logln(str3);
   3647 
   3648     UDate dt33 = fmt3->parse(str3, status);
   3649     failure(status, "fmt->parse");
   3650 
   3651     UnicodeString str33;
   3652     str33 = fmt3->format(dt33, str33);
   3653     logln(str33);
   3654 
   3655     if (str3 != str33) {
   3656         errln((UnicodeString)"FAIL: Different dates str1:" + str3
   3657             + " str2:" + str33);
   3658     }
   3659     delete fmt3;
   3660 
   3661     /////////////////
   3662 
   3663     status = U_ZERO_ERROR;
   3664     SimpleDateFormat *fmt4 = new SimpleDateFormat(UnicodeString("y M  d"), Locale("en-us"), status);
   3665     failure(status, "new SimpleDateFormat");
   3666 
   3667     UDate dt4 = date(2008-1900, UCAL_JUNE, 10, 12, 00);
   3668     UnicodeString str4;
   3669     str4 = fmt4->format(dt4, str4);
   3670     logln(str4);
   3671 
   3672     UDate dt44 = fmt4->parse(str4, status);
   3673     failure(status, "fmt->parse");
   3674 
   3675     UnicodeString str44;
   3676     str44 = fmt4->format(dt44, str44);
   3677     logln(str44);
   3678 
   3679     if (str4 != str44) {
   3680         errln((UnicodeString)"FAIL: Different dates str1:" + str4
   3681             + " str2:" + str44);
   3682     }
   3683     delete fmt4;
   3684 
   3685 }
   3686 
   3687 void DateFormatTest::Test6726(void)
   3688 {
   3689     // status
   3690 //    UErrorCode status = U_ZERO_ERROR;
   3691 
   3692     // fmtf, fmtl, fmtm, fmts;
   3693     UnicodeString strf, strl, strm, strs;
   3694     UDate dt = date(2008-1900, UCAL_JUNE, 10, 12, 00);
   3695 
   3696     Locale loc("ja");
   3697     DateFormat* fmtf = DateFormat::createDateTimeInstance(DateFormat::FULL, DateFormat::FULL, loc);
   3698     DateFormat* fmtl = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::FULL, loc);
   3699     DateFormat* fmtm = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL, loc);
   3700     DateFormat* fmts = DateFormat::createDateTimeInstance(DateFormat::SHORT, DateFormat::FULL, loc);
   3701     if (fmtf == NULL || fmtl == NULL || fmtm == NULL || fmts == NULL) {
   3702         dataerrln("Unable to create DateFormat. got NULL.");
   3703         /* It may not be true that if one is NULL all is NULL.  Just to be safe. */
   3704         delete fmtf;
   3705         delete fmtl;
   3706         delete fmtm;
   3707         delete fmts;
   3708 
   3709         return;
   3710     }
   3711     strf = fmtf->format(dt, strf);
   3712     strl = fmtl->format(dt, strl);
   3713     strm = fmtm->format(dt, strm);
   3714     strs = fmts->format(dt, strs);
   3715 
   3716 
   3717     logln("strm.charAt(10)=%04X wanted 0x20\n", strm.charAt(10));
   3718     if (strm.charAt(10) != UChar(0x0020)) {
   3719       errln((UnicodeString)"FAIL: Improper formatted date: " + strm );
   3720     }
   3721     logln("strs.charAt(10)=%04X wanted 0x20\n", strs.charAt(8));
   3722     if (strs.charAt(10)  != UChar(0x0020)) {
   3723         errln((UnicodeString)"FAIL: Improper formatted date: " + strs);
   3724     }
   3725 
   3726     delete fmtf;
   3727     delete fmtl;
   3728     delete fmtm;
   3729     delete fmts;
   3730 
   3731     return;
   3732 }
   3733 
   3734 /**
   3735  * Test DateFormat's parsing of default GMT variants.  See ticket#6135
   3736  */
   3737 void DateFormatTest::TestGMTParsing() {
   3738     const char* DATA[] = {
   3739         "HH:mm:ss Z",
   3740 
   3741         // pattern, input, expected output (in quotes)
   3742         "HH:mm:ss Z",       "10:20:30 GMT+03:00",   "10:20:30 +0300",
   3743         "HH:mm:ss Z",       "10:20:30 UT-02:00",    "10:20:30 -0200",
   3744         "HH:mm:ss Z",       "10:20:30 GMT",         "10:20:30 +0000",
   3745         "HH:mm:ss vvvv",    "10:20:30 UT+10:00",    "10:20:30 +1000",
   3746         "HH:mm:ss zzzz",    "10:20:30 UTC",         "10:20:30 +0000",   // standalone "UTC"
   3747         "ZZZZ HH:mm:ss",    "UT 10:20:30",          "10:20:30 +0000",
   3748         "z HH:mm:ss",       "UT+0130 10:20:30",     "10:20:30 +0130",
   3749         "z HH:mm:ss",       "UTC+0130 10:20:30",    "10:20:30 +0130",
   3750         // Note: GMT-1100 no longer works because of the introduction of the short
   3751         // localized GMT support. Previous implementation support this level of
   3752         // leniency (no separator char in localized GMT format), but the new
   3753         // implementation handles GMT-11 as the legitimate short localized GMT format
   3754         // and stop at there. Otherwise, roundtrip would be broken.
   3755         //"HH mm Z ss",       "10 20 GMT-1100 30",    "10:20:30 -1100",
   3756         "HH mm Z ss",       "10 20 GMT-11 30",    "10:20:30 -1100",
   3757         "HH:mm:ssZZZZZ",    "14:25:45Z",            "14:25:45 +0000",
   3758         "HH:mm:ssZZZZZ",    "15:00:00-08:00",       "15:00:00 -0800",
   3759     };
   3760     const int32_t DATA_len = UPRV_LENGTHOF(DATA);
   3761     expectParse(DATA, DATA_len, Locale("en"));
   3762 }
   3763 
   3764 // Test case for localized GMT format parsing
   3765 // with no delimitters in offset format (Chinese locale)
   3766 void DateFormatTest::Test6880() {
   3767     UErrorCode status = U_ZERO_ERROR;
   3768     UDate d1, d2, dp1, dp2, dexp1, dexp2;
   3769     UnicodeString s1, s2;
   3770 
   3771     TimeZone *tz = TimeZone::createTimeZone("Asia/Shanghai");
   3772     GregorianCalendar gcal(*tz, status);
   3773     if (failure(status, "construct GregorianCalendar", TRUE)) return;
   3774 
   3775     gcal.clear();
   3776     gcal.set(1900, UCAL_JULY, 1, 12, 00);   // offset 8:05:43
   3777     d1 = gcal.getTime(status);
   3778 
   3779     gcal.clear();
   3780     gcal.set(1950, UCAL_JULY, 1, 12, 00);   // offset 8:00
   3781     d2 = gcal.getTime(status);
   3782 
   3783     gcal.clear();
   3784     gcal.set(1970, UCAL_JANUARY, 1, 12, 00);
   3785     dexp2 = gcal.getTime(status);
   3786     dexp1 = dexp2 - (5*60 + 43)*1000;   // subtract 5m43s
   3787 
   3788     if (U_FAILURE(status)) {
   3789         errln("FAIL: Gregorian calendar error");
   3790     }
   3791 
   3792     DateFormat *fmt = DateFormat::createTimeInstance(DateFormat::kFull, Locale("zh"));
   3793     if (fmt == NULL) {
   3794         dataerrln("Unable to create DateFormat. Got NULL.");
   3795         return;
   3796     }
   3797     fmt->adoptTimeZone(tz);
   3798 
   3799     fmt->format(d1, s1);
   3800     fmt->format(d2, s2);
   3801 
   3802     dp1 = fmt->parse(s1, status);
   3803     dp2 = fmt->parse(s2, status);
   3804 
   3805     if (U_FAILURE(status)) {
   3806         errln("FAIL: Parse failure");
   3807     }
   3808 
   3809     if (dp1 != dexp1) {
   3810         errln("FAIL: Failed to parse " + s1 + " parsed: " + dp1 + " expected: " + dexp1);
   3811     }
   3812     if (dp2 != dexp2) {
   3813         errln("FAIL: Failed to parse " + s2 + " parsed: " + dp2 + " expected: " + dexp2);
   3814     }
   3815 
   3816     delete fmt;
   3817 }
   3818 
   3819 typedef struct {
   3820     const char * localeStr;
   3821     UBool        lenient;
   3822     UBool        expectFail;
   3823     UnicodeString datePattern;
   3824     UnicodeString dateString;
   3825 } NumAsStringItem;
   3826 
   3827 void DateFormatTest::TestNumberAsStringParsing()
   3828 {
   3829     const NumAsStringItem items[] = {
   3830         // loc lenient fail?  datePattern                                         dateString
   3831         { "",   FALSE, TRUE,  UnicodeString("y MMMM d HH:mm:ss"),                 UnicodeString("2009 7 14 08:43:57") },
   3832         { "",   TRUE,  FALSE, UnicodeString("y MMMM d HH:mm:ss"),                 UnicodeString("2009 7 14 08:43:57") },
   3833         { "en", FALSE, FALSE, UnicodeString("MMM d, y"),                          UnicodeString("Jul 14, 2009") },
   3834         { "en", TRUE,  FALSE, UnicodeString("MMM d, y"),                          UnicodeString("Jul 14, 2009") },
   3835         { "en", FALSE, TRUE,  UnicodeString("MMM d, y"),                          UnicodeString("7 14, 2009") },
   3836         { "en", TRUE,  FALSE, UnicodeString("MMM d, y"),                          UnicodeString("7 14, 2009") },
   3837         { "ja", FALSE, FALSE, UnicodeString("yyyy/MM/dd"),                        UnicodeString("2009/07/14")         },
   3838         { "ja", TRUE,  FALSE, UnicodeString("yyyy/MM/dd"),                        UnicodeString("2009/07/14")         },
   3839       //{ "ja", FALSE, FALSE, UnicodeString("yyyy/MMMMM/d"),                      UnicodeString("2009/7/14")          }, // #8860 covers test failure
   3840         { "ja", TRUE,  FALSE, UnicodeString("yyyy/MMMMM/d"),                      UnicodeString("2009/7/14")          },
   3841         { "ja", FALSE, FALSE, CharsToUnicodeString("y\\u5E74M\\u6708d\\u65E5"),   CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5")   },
   3842         { "ja", TRUE,  FALSE, CharsToUnicodeString("y\\u5E74M\\u6708d\\u65E5"),   CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5")   },
   3843         { "ja", FALSE, FALSE, CharsToUnicodeString("y\\u5E74MMMd\\u65E5"),        CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5")   },
   3844         { "ja", TRUE,  FALSE, CharsToUnicodeString("y\\u5E74MMMd\\u65E5"),        CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5")   }, // #8820 fixes test failure
   3845         { "ko", FALSE, FALSE, UnicodeString("yyyy. M. d."),                       UnicodeString("2009. 7. 14.")       },
   3846         { "ko", TRUE,  FALSE, UnicodeString("yyyy. M. d."),                       UnicodeString("2009. 7. 14.")       },
   3847         { "ko", FALSE, FALSE, UnicodeString("yyyy. MMMMM d."),                    CharsToUnicodeString("2009. 7\\uC6D4 14.")             },
   3848         { "ko", TRUE,  FALSE, UnicodeString("yyyy. MMMMM d."),                    CharsToUnicodeString("2009. 7\\uC6D4 14.")             }, // #8820 fixes test failure
   3849         { "ko", FALSE, FALSE, CharsToUnicodeString("y\\uB144 M\\uC6D4 d\\uC77C"), CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") },
   3850         { "ko", TRUE,  FALSE, CharsToUnicodeString("y\\uB144 M\\uC6D4 d\\uC77C"), CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") },
   3851         { "ko", FALSE, FALSE, CharsToUnicodeString("y\\uB144 MMM d\\uC77C"),      CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") },
   3852         { "ko", TRUE,  FALSE, CharsToUnicodeString("y\\uB144 MMM d\\uC77C"),      CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") }, // #8820 fixes test failure
   3853         { NULL, FALSE, FALSE, UnicodeString(""),                                  UnicodeString("")                   }
   3854     };
   3855     const NumAsStringItem * itemPtr;
   3856     for (itemPtr = items; itemPtr->localeStr != NULL; itemPtr++ ) {
   3857         Locale locale = Locale::createFromName(itemPtr->localeStr);
   3858         UErrorCode status = U_ZERO_ERROR;
   3859         SimpleDateFormat *formatter = new SimpleDateFormat(itemPtr->datePattern, locale, status);
   3860         if (formatter == NULL || U_FAILURE(status)) {
   3861             dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
   3862             return;
   3863         }
   3864 
   3865         formatter->setLenient(itemPtr->lenient);
   3866         formatter->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->lenient, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->lenient, status);
   3867         UDate date1 = formatter->parse(itemPtr->dateString, status);
   3868         if (U_FAILURE(status)) {
   3869             if (!itemPtr->expectFail) {
   3870                 errln("FAIL, err when expected success: Locale \"" + UnicodeString(itemPtr->localeStr) + "\", lenient " + itemPtr->lenient +
   3871                         ": using pattern \"" + itemPtr->datePattern + "\", could not parse \"" + itemPtr->dateString + "\"; err: " + u_errorName(status) );
   3872             }
   3873         } else if (itemPtr->expectFail) {
   3874                 errln("FAIL, expected err but got none: Locale \"" + UnicodeString(itemPtr->localeStr) + "\", lenient " + itemPtr->lenient +
   3875                         ": using pattern \"" + itemPtr->datePattern + "\", did parse \"" + itemPtr->dateString + "\"." );
   3876         } else if (!itemPtr->lenient) {
   3877             UnicodeString formatted;
   3878             formatter->format(date1, formatted);
   3879             if (formatted != itemPtr->dateString) {
   3880                 errln("FAIL, mismatch formatting parsed date: Locale \"" + UnicodeString(itemPtr->localeStr) + "\", lenient " + itemPtr->lenient +
   3881                         ": using pattern \"" + itemPtr->datePattern + "\", did parse \"" + itemPtr->dateString + "\", formatted result \"" + formatted + "\".");
   3882             }
   3883         }
   3884 
   3885         delete formatter;
   3886     }
   3887 }
   3888 
   3889 void DateFormatTest::TestISOEra() {
   3890 
   3891     const char* data[] = {
   3892     // input, output
   3893     "BC 4004-10-23T07:00:00Z", "BC 4004-10-23T07:00:00Z",
   3894     "AD 4004-10-23T07:00:00Z", "AD 4004-10-23T07:00:00Z",
   3895     "-4004-10-23T07:00:00Z"  , "BC 4005-10-23T07:00:00Z",
   3896     "4004-10-23T07:00:00Z"   , "AD 4004-10-23T07:00:00Z",
   3897     };
   3898 
   3899     int32_t numData = 8;
   3900 
   3901     UErrorCode status = U_ZERO_ERROR;
   3902 
   3903     // create formatter
   3904     SimpleDateFormat *fmt1 = new SimpleDateFormat(UnicodeString("GGG yyyy-MM-dd'T'HH:mm:ss'Z"), status);
   3905     failure(status, "new SimpleDateFormat", TRUE);
   3906     if (status == U_MISSING_RESOURCE_ERROR) {
   3907         if (fmt1 != NULL) {
   3908             delete fmt1;
   3909         }
   3910         return;
   3911     }
   3912     for(int i=0; i < numData; i+=2) {
   3913         // create input string
   3914         UnicodeString in = data[i];
   3915 
   3916         // parse string to date
   3917         UDate dt1 = fmt1->parse(in, status);
   3918         failure(status, "fmt->parse", TRUE);
   3919 
   3920         // format date back to string
   3921         UnicodeString out;
   3922         out = fmt1->format(dt1, out);
   3923         logln(out);
   3924 
   3925         // check that roundtrip worked as expected
   3926         UnicodeString expected = data[i+1];
   3927         if (out != expected) {
   3928             dataerrln((UnicodeString)"FAIL: " + in + " -> " + out + " expected -> " + expected);
   3929         }
   3930     }
   3931 
   3932     delete fmt1;
   3933 }
   3934 void DateFormatTest::TestFormalChineseDate() {
   3935 
   3936     UErrorCode status = U_ZERO_ERROR;
   3937     UnicodeString pattern ("y\\u5e74M\\u6708d\\u65e5", -1, US_INV );
   3938     pattern = pattern.unescape();
   3939     UnicodeString override ("y=hanidec;M=hans;d=hans", -1, US_INV );
   3940 
   3941     // create formatter
   3942     SimpleDateFormat *sdf = new SimpleDateFormat(pattern,override,Locale::getChina(),status);
   3943     if (failure(status, "new SimpleDateFormat with override", TRUE)) {
   3944         return;
   3945     }
   3946 
   3947     UDate thedate = date(2009-1900, UCAL_JULY, 28);
   3948     FieldPosition pos(FieldPosition::DONT_CARE);
   3949     UnicodeString result;
   3950     sdf->format(thedate,result,pos);
   3951 
   3952     UnicodeString expected = "\\u4e8c\\u3007\\u3007\\u4e5d\\u5e74\\u4e03\\u6708\\u4e8c\\u5341\\u516b\\u65e5";
   3953     expected = expected.unescape();
   3954     if (result != expected) {
   3955         dataerrln((UnicodeString)"FAIL: -> " + result + " expected -> " + expected);
   3956     }
   3957 
   3958     UDate parsedate = sdf->parse(expected,status);
   3959     if ( parsedate != thedate ) {
   3960         UnicodeString pat1 ("yyyy-MM-dd'T'HH:mm:ss'Z'", -1, US_INV );
   3961         SimpleDateFormat *usf = new SimpleDateFormat(pat1,Locale::getEnglish(),status);
   3962         UnicodeString parsedres,expres;
   3963         usf->format(parsedate,parsedres,pos);
   3964         usf->format(thedate,expres,pos);
   3965         dataerrln((UnicodeString)"FAIL: parsed -> " + parsedres + " expected -> " + expres);
   3966         delete usf;
   3967     }
   3968     delete sdf;
   3969 }
   3970 
   3971 // Test case for #8675
   3972 // Incorrect parse offset with stand alone GMT string on 2nd or later iteration.
   3973 void DateFormatTest::TestStandAloneGMTParse() {
   3974     UErrorCode status = U_ZERO_ERROR;
   3975     SimpleDateFormat *sdf = new SimpleDateFormat("ZZZZ", Locale(""), status);
   3976 
   3977     if (U_SUCCESS(status)) {
   3978 
   3979         UnicodeString inText("GMT$$$");
   3980         for (int32_t i = 0; i < 10; i++) {
   3981             ParsePosition pos(0);
   3982             sdf->parse(inText, pos);
   3983             if (pos.getIndex() != 3) {
   3984                 errln((UnicodeString)"FAIL: Incorrect output parse position: actual=" + pos.getIndex() + " expected=3");
   3985             }
   3986         }
   3987 
   3988         delete sdf;
   3989     } else {
   3990         dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
   3991     }
   3992 }
   3993 
   3994 void DateFormatTest::TestParsePosition() {
   3995     const char* TestData[][4] = {
   3996         // {<pattern>, <lead>, <date string>, <trail>}
   3997         {"yyyy-MM-dd HH:mm:ssZ", "", "2010-01-10 12:30:00+0500", ""},
   3998         {"yyyy-MM-dd HH:mm:ss ZZZZ", "", "2010-01-10 12:30:00 GMT+05:00", ""},
   3999         {"Z HH:mm:ss", "", "-0100 13:20:30", ""},
   4000         {"y-M-d Z", "", "2011-8-25 -0400", " Foo"},
   4001         {"y/M/d H:mm:ss z", "", "2011/7/1 12:34:00 PDT", ""},
   4002         {"y/M/d H:mm:ss z", "+123", "2011/7/1 12:34:00 PDT", " PST"},
   4003         {"vvvv a h:mm:ss", "", "Pacific Time AM 10:21:45", ""},
   4004         {"HH:mm v M/d", "111", "14:15 PT 8/10", " 12345"},
   4005         {"'time zone:' VVVV 'date:' yyyy-MM-dd", "xxxx", "time zone: Los Angeles Time date: 2010-02-25", "xxxx"},
   4006         {"yG", "", "2012AD", ""},
   4007         {"yG", "", "2012", "x"},
   4008         {0, 0, 0, 0},
   4009     };
   4010 
   4011     for (int32_t i = 0; TestData[i][0]; i++) {
   4012         UErrorCode status = U_ZERO_ERROR;
   4013         SimpleDateFormat *sdf = new SimpleDateFormat(UnicodeString(TestData[i][0]), status);
   4014         if (failure(status, "new SimpleDateFormat", TRUE)) return;
   4015 
   4016         int32_t startPos, resPos;
   4017 
   4018         // lead text
   4019         UnicodeString input(TestData[i][1]);
   4020         startPos = input.length();
   4021 
   4022         // date string
   4023         input += TestData[i][2];
   4024         resPos = input.length();
   4025 
   4026         // trail text
   4027         input += TestData[i][3];
   4028 
   4029         ParsePosition pos(startPos);
   4030         //UDate d = sdf->parse(input, pos);
   4031         (void)sdf->parse(input, pos);
   4032 
   4033         if (pos.getIndex() != resPos) {
   4034             errln(UnicodeString("FAIL: Parsing [") + input + "] with pattern [" + TestData[i][0] + "] returns position - "
   4035                 + pos.getIndex() + ", expected - " + resPos);
   4036         }
   4037 
   4038         delete sdf;
   4039     }
   4040 }
   4041 
   4042 
   4043 typedef struct {
   4044     int32_t era;
   4045     int32_t year;
   4046     int32_t month; // 1-based
   4047     int32_t isLeapMonth;
   4048     int32_t day;
   4049 } ChineseCalTestDate;
   4050 
   4051 #define NUM_TEST_DATES 3
   4052 
   4053 typedef struct {
   4054     const char *   locale;
   4055     int32_t        style; // <0 => custom
   4056     UnicodeString  dateString[NUM_TEST_DATES];
   4057 } MonthPatternItem;
   4058 
   4059 void DateFormatTest::TestMonthPatterns()
   4060 {
   4061     const ChineseCalTestDate dates[NUM_TEST_DATES] = {
   4062         // era yr mo lp da
   4063         {  78, 29, 4, 0, 2 }, // (in chinese era 78) gregorian 2012-4-22
   4064         {  78, 29, 4, 1, 2 }, // (in chinese era 78) gregorian 2012-5-22
   4065         {  78, 29, 5, 0, 2 }, // (in chinese era 78) gregorian 2012-6-20
   4066     };
   4067 
   4068     const MonthPatternItem items[] = {
   4069         // locale                     date style;           expected formats for the 3 dates above
   4070         { "root@calendar=chinese",    DateFormat::kLong,  { UnicodeString("2012(ren-chen) M04 2"),  UnicodeString("2012(ren-chen) M04bis 2"),  UnicodeString("2012(ren-chen) M05 2") } },
   4071         { "root@calendar=chinese",    DateFormat::kShort, { UnicodeString("2012-04-02"),    UnicodeString("2012-04bis-02"),         UnicodeString("2012-05-02") } },
   4072         { "root@calendar=chinese",    -1,                 { UnicodeString("29-4-2"),        UnicodeString("29-4bis-2"),             UnicodeString("29-5-2") } },
   4073         { "root@calendar=chinese",    -2,                 { UnicodeString("78x29-4-2"),     UnicodeString("78x29-4bis-2"),          UnicodeString("78x29-5-2") } },
   4074         { "root@calendar=chinese",    -3,                 { UnicodeString("ren-chen-4-2"),  UnicodeString("ren-chen-4bis-2"),       UnicodeString("ren-chen-5-2") } },
   4075         { "root@calendar=chinese",    -4,                 { UnicodeString("ren-chen M04 2"),  UnicodeString("ren-chen M04bis 2"),   UnicodeString("ren-chen M05 2") } },
   4076         { "en@calendar=gregorian",    -3,                 { UnicodeString("2012-4-22"),     UnicodeString("2012-5-22"),             UnicodeString("2012-6-20") } },
   4077         { "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)") } },
   4078         { "en@calendar=chinese",      DateFormat::kShort, { UnicodeString("4/2/2012"),      UnicodeString("4bis/2/2012"),           UnicodeString("5/2/2012") } },
   4079         { "zh@calendar=chinese",      DateFormat::kLong,  { CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u56DB\\u6708\\u521D\\u4E8C"),
   4080                                                             CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u95F0\\u56DB\\u6708\\u521D\\u4E8C"),
   4081                                                             CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u4E94\\u6708\\u521D\\u4E8C") } },
   4082         { "zh@calendar=chinese",      DateFormat::kShort, { CharsToUnicodeString("2012/4/2"),
   4083                                                             CharsToUnicodeString("2012/\\u95F04/2"),
   4084                                                             CharsToUnicodeString("2012/5/2") } },
   4085         { "zh@calendar=chinese",      -3,                 { CharsToUnicodeString("\\u58EC\\u8FB0-4-2"),
   4086                                                             CharsToUnicodeString("\\u58EC\\u8FB0-\\u95F04-2"),
   4087                                                             CharsToUnicodeString("\\u58EC\\u8FB0-5-2") } },
   4088         { "zh@calendar=chinese",      -4,                 { CharsToUnicodeString("\\u58EC\\u8FB0 \\u56DB\\u6708 2"),
   4089                                                             CharsToUnicodeString("\\u58EC\\u8FB0 \\u95F0\\u56DB\\u6708 2"),
   4090                                                             CharsToUnicodeString("\\u58EC\\u8FB0 \\u4E94\\u6708 2") } },
   4091         { "zh_Hant@calendar=chinese", DateFormat::kLong,  { CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u56DB\\u6708\\u521D\\u4E8C"),
   4092                                                             CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u958F\\u56DB\\u6708\\u521D\\u4E8C"),
   4093                                                             CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u4E94\\u6708\\u521D\\u4E8C") } },
   4094         { "zh_Hant@calendar=chinese", DateFormat::kShort, { CharsToUnicodeString("2012/4/2"),
   4095                                                             CharsToUnicodeString("2012/\\u958F4/2"),
   4096                                                             CharsToUnicodeString("2012/5/2") } },
   4097         { "fr@calendar=chinese",      DateFormat::kLong,  { CharsToUnicodeString("2 s\\u00ECyu\\u00E8 ren-chen"),
   4098                                                             CharsToUnicodeString("2 s\\u00ECyu\\u00E8bis ren-chen"),
   4099                                                             CharsToUnicodeString("2 w\\u01D4yu\\u00E8 ren-chen") } },
   4100         { "fr@calendar=chinese",      DateFormat::kShort, { UnicodeString("2/4/29"),        UnicodeString("2/4bis/29"),             UnicodeString("2/5/29") } },
   4101         { "en@calendar=dangi",        DateFormat::kLong,  { UnicodeString("Third Monthbis 2, 2012(ren-chen)"),  UnicodeString("Fourth Month 2, 2012(ren-chen)"),       UnicodeString("Fifth Month 1, 2012(ren-chen)") } },
   4102         { "en@calendar=dangi",        DateFormat::kShort, { UnicodeString("3bis/2/2012"),   UnicodeString("4/2/2012"),              UnicodeString("5/1/2012") } },
   4103         { "en@calendar=dangi",        -2,                 { UnicodeString("78x29-3bis-2"),  UnicodeString("78x29-4-2"),             UnicodeString("78x29-5-1") } },
   4104         { "ko@calendar=dangi",        DateFormat::kLong,  { CharsToUnicodeString("\\uC784\\uC9C4\\uB144 \\uC7243\\uC6D4 2\\uC77C"),
   4105                                                             CharsToUnicodeString("\\uC784\\uC9C4\\uB144 4\\uC6D4 2\\uC77C"),
   4106                                                             CharsToUnicodeString("\\uC784\\uC9C4\\uB144 5\\uC6D4 1\\uC77C") } },
   4107         { "ko@calendar=dangi",        DateFormat::kShort, { CharsToUnicodeString("29. \\uC7243. 2."),
   4108                                                             CharsToUnicodeString("29. 4. 2."),
   4109                                                             CharsToUnicodeString("29. 5. 1.") } },
   4110         // terminator
   4111         { NULL,                       0,                  { UnicodeString(""), UnicodeString(""), UnicodeString("") } }
   4112     };
   4113 
   4114     //.                               style: -1        -2            -3       -4
   4115     const UnicodeString customPatterns[] = { "y-Ml-d", "G'x'y-Ml-d", "U-M-d", "U MMM d" }; // like old root pattern, using 'l'
   4116 
   4117     UErrorCode status = U_ZERO_ERROR;
   4118     Locale rootChineseCalLocale = Locale::createFromName("root@calendar=chinese");
   4119     Calendar * rootChineseCalendar = Calendar::createInstance(rootChineseCalLocale, status);
   4120     if (U_SUCCESS(status)) {
   4121         const MonthPatternItem * itemPtr;
   4122         for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
   4123             Locale locale = Locale::createFromName(itemPtr->locale);
   4124             DateFormat * dmft = (itemPtr->style >= 0)?
   4125                     DateFormat::createDateInstance((DateFormat::EStyle)itemPtr->style, locale):
   4126                     new SimpleDateFormat(customPatterns[-itemPtr->style - 1], locale, status);
   4127             if ( dmft != NULL ) {
   4128                 if (U_SUCCESS(status)) {
   4129                     const ChineseCalTestDate * datePtr = dates;
   4130                     int32_t idate;
   4131                     for (idate = 0; idate < NUM_TEST_DATES; idate++, datePtr++) {
   4132                         rootChineseCalendar->clear();
   4133                         rootChineseCalendar->set(UCAL_ERA, datePtr->era);
   4134                         rootChineseCalendar->set(datePtr->year, datePtr->month-1, datePtr->day);
   4135                         rootChineseCalendar->set(UCAL_IS_LEAP_MONTH, datePtr->isLeapMonth);
   4136                         UnicodeString result;
   4137                         FieldPosition fpos(FieldPosition::DONT_CARE);
   4138                         dmft->format(*rootChineseCalendar, result, fpos);
   4139                         if ( result.compare(itemPtr->dateString[idate]) != 0 ) {
   4140                             errln( UnicodeString("FAIL: Chinese calendar format for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
   4141                                     ", expected \"" + itemPtr->dateString[idate] + "\", got \"" + result + "\"");
   4142                         } else {
   4143                             // formatted OK, try parse
   4144                             ParsePosition ppos(0);
   4145                             // ensure we are really parsing the fields we should be
   4146                             rootChineseCalendar->set(UCAL_YEAR, 1);
   4147                             rootChineseCalendar->set(UCAL_MONTH, 0);
   4148                             rootChineseCalendar->set(UCAL_IS_LEAP_MONTH, 0);
   4149                             rootChineseCalendar->set(UCAL_DATE, 1);
   4150                             //
   4151                             dmft->parse(result, *rootChineseCalendar, ppos);
   4152                             int32_t year = rootChineseCalendar->get(UCAL_YEAR, status);
   4153                             int32_t month = rootChineseCalendar->get(UCAL_MONTH, status) + 1;
   4154                             int32_t isLeapMonth = rootChineseCalendar->get(UCAL_IS_LEAP_MONTH, status);
   4155                             int32_t day = rootChineseCalendar->get(UCAL_DATE, status);
   4156                             if ( ppos.getIndex() < result.length() || year != datePtr->year || month != datePtr->month || isLeapMonth != datePtr->isLeapMonth || day != datePtr->day ) {
   4157                                 errln( UnicodeString("FAIL: Chinese calendar parse for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
   4158                                     ", string \"" + result + "\", expected " + datePtr->year +"-"+datePtr->month+"("+datePtr->isLeapMonth+")-"+datePtr->day + ", got pos " +
   4159                                     ppos.getIndex() + " " + year +"-"+month+"("+isLeapMonth+")-"+day);
   4160                             }
   4161                         }
   4162                     }
   4163                 } else {
   4164                     dataerrln("Error creating SimpleDateFormat for Chinese calendar- %s", u_errorName(status));
   4165                 }
   4166                 delete dmft;
   4167             } else {
   4168                 dataerrln("FAIL: Unable to create DateFormat for Chinese calendar- %s", u_errorName(status));
   4169             }
   4170         }
   4171         delete rootChineseCalendar;
   4172     } else {
   4173         errln(UnicodeString("FAIL: Unable to create Calendar for root@calendar=chinese"));
   4174     }
   4175 }
   4176 
   4177 typedef struct {
   4178     const char * locale;
   4179     UnicodeString pattern;
   4180     UDisplayContext capitalizationContext;
   4181     UnicodeString expectedFormat;
   4182 } TestContextItem;
   4183 
   4184 void DateFormatTest::TestContext()
   4185 {
   4186     const UDate july022008 = 1215000001979.0;
   4187     const TestContextItem items[] = {
   4188         //locale              pattern    capitalizationContext                              expected formatted date
   4189         { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_NONE,                      UnicodeString("juillet 2008") },
   4190 #if !UCONFIG_NO_BREAK_ITERATION
   4191         { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE,    UnicodeString("juillet 2008") },
   4192         { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UnicodeString("Juillet 2008") },
   4193         { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU,       UnicodeString("juillet 2008") },
   4194         { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_STANDALONE,            UnicodeString("Juillet 2008") },
   4195 #endif
   4196         { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_NONE,                      CharsToUnicodeString("\\u010Dervenec 2008") },
   4197 #if !UCONFIG_NO_BREAK_ITERATION
   4198         { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE,    CharsToUnicodeString("\\u010Dervenec 2008") },
   4199         { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, CharsToUnicodeString("\\u010Cervenec 2008") },
   4200         { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU,       CharsToUnicodeString("\\u010Cervenec 2008") },
   4201         { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_STANDALONE,            CharsToUnicodeString("\\u010Dervenec 2008") },
   4202 #endif
   4203         // terminator
   4204         { NULL, UnicodeString(""),       (UDisplayContext)0, UnicodeString("") }
   4205     };
   4206     UErrorCode status = U_ZERO_ERROR;
   4207     Calendar* cal = Calendar::createInstance(status);
   4208     if (U_FAILURE(status)) {
   4209         dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale."));
   4210     } else {
   4211         cal->setTime(july022008, status);
   4212         const TestContextItem * itemPtr;
   4213         for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
   4214            Locale locale = Locale::createFromName(itemPtr->locale);
   4215            status = U_ZERO_ERROR;
   4216            SimpleDateFormat * sdmft = new SimpleDateFormat(itemPtr->pattern, locale, status);
   4217            if (U_FAILURE(status)) {
   4218                 dataerrln(UnicodeString("FAIL: Unable to create SimpleDateFormat for specified pattern with locale ") + UnicodeString(itemPtr->locale));
   4219            } else {
   4220                sdmft->setContext(itemPtr->capitalizationContext, status);
   4221                UnicodeString result;
   4222                FieldPosition pos(FieldPosition::DONT_CARE);
   4223                sdmft->format(*cal, result, pos);
   4224                if (result.compare(itemPtr->expectedFormat) != 0) {
   4225                    errln(UnicodeString("FAIL: format for locale ") + UnicodeString(itemPtr->locale) +
   4226                            ", status " + (int)status +
   4227                            ", capitalizationContext " + (int)itemPtr->capitalizationContext +
   4228                            ", expected " + itemPtr->expectedFormat + ", got " + result);
   4229                }
   4230            }
   4231            if (sdmft) {
   4232                delete sdmft;
   4233            }
   4234         }
   4235     }
   4236     if (cal) {
   4237         delete cal;
   4238     }
   4239 }
   4240 
   4241 // test item for a particular locale + calendar and date format
   4242 typedef struct {
   4243     int32_t era;
   4244     int32_t year;
   4245     int32_t month;
   4246     int32_t day;
   4247     int32_t hour;
   4248     int32_t minute;
   4249     UnicodeString formattedDate;
   4250 } CalAndFmtTestItem;
   4251 
   4252 // test item giving locale + calendar, date format, and CalAndFmtTestItems
   4253 typedef struct {
   4254     const char * locale; // with calendar
   4255     DateFormat::EStyle style;
   4256     UnicodeString pattern; // ignored unless style == DateFormat::kNone
   4257     const CalAndFmtTestItem *caftItems;
   4258 } TestNonGregoItem;
   4259 
   4260 void DateFormatTest::TestNonGregoFmtParse()
   4261 {
   4262     // test items for he@calendar=hebrew, long date format
   4263     const CalAndFmtTestItem cafti_he_hebrew_long[] = {
   4264         {  0, 4999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05D3\\u05F3\\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") },
   4265         {  0, 5100,  0,  1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05E7\\u05F3") },
   4266         {  0, 5774,  5,  1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05D0\\u05D3\\u05E8 \\u05D0\\u05F3 \\u05EA\\u05E9\\u05E2\\u05F4\\u05D3") },
   4267         {  0, 5999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") },
   4268         {  0, 6100,  0,  1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05D5\\u05F3\\u05E7\\u05F3") },
   4269         {  0,    0,  0,  0,  0, 0, UnicodeString("") } // terminator
   4270     };
   4271     const CalAndFmtTestItem cafti_zh_chinese_custU[] = {
   4272         { 78,   31,  0,  1, 12, 0, CharsToUnicodeString("2014\\u7532\\u5348\\u5E74\\u6B63\\u67081") },
   4273         { 77,   31,  0,  1, 12, 0, CharsToUnicodeString("1954\\u7532\\u5348\\u5E74\\u6B63\\u67081") },
   4274         {  0,    0,  0,  0,  0, 0, UnicodeString("") } // terminator
   4275     };
   4276     const CalAndFmtTestItem cafti_zh_chinese_custNoU[] = {
   4277         { 78,   31,  0,  1, 12, 0, CharsToUnicodeString("2014\\u5E74\\u6B63\\u67081") },
   4278         { 77,   31,  0,  1, 12, 0, CharsToUnicodeString("1954\\u5E74\\u6B63\\u67081") },
   4279         {  0,    0,  0,  0,  0, 0, UnicodeString("") } // terminator
   4280     };
   4281     const CalAndFmtTestItem cafti_ja_japanese_custGy[] = {
   4282         {235,   26,  2,  5, 12, 0, CharsToUnicodeString("2014(\\u5E73\\u621026)\\u5E743\\u67085\\u65E5") },
   4283         {234,   60,  2,  5, 12, 0, CharsToUnicodeString("1985(\\u662D\\u548C60)\\u5E743\\u67085\\u65E5") },
   4284         {  0,    0,  0,  0,  0, 0, UnicodeString("") } // terminator
   4285     };
   4286     const CalAndFmtTestItem cafti_ja_japanese_custNoGy[] = {
   4287         {235,   26,  2,  5, 12, 0, CharsToUnicodeString("2014\\u5E743\\u67085\\u65E5") },
   4288         {234,   60,  2,  5, 12, 0, CharsToUnicodeString("1985\\u5E743\\u67085\\u65E5") },
   4289         {  0,    0,  0,  0,  0, 0, UnicodeString("") } // terminator
   4290     };
   4291     const CalAndFmtTestItem cafti_en_islamic_cust[] = {
   4292         {  0, 1384,  0,  1, 12, 0, UnicodeString("1 Muh. 1384 AH, 1964") },
   4293         {  0, 1436,  0,  1, 12, 0, UnicodeString("1 Muh. 1436 AH, 2014") },
   4294         {  0, 1487,  0,  1, 12, 0, UnicodeString("1 Muh. 1487 AH, 2064") },
   4295         {  0,    0,  0,  0,  0, 0, UnicodeString("") } // terminator
   4296     };
   4297     // overal test items
   4298     const TestNonGregoItem items[] = {
   4299         { "he@calendar=hebrew",   DateFormat::kLong, UnicodeString(""),                 cafti_he_hebrew_long },
   4300         { "zh@calendar=chinese",  DateFormat::kNone, CharsToUnicodeString("rU\\u5E74MMMd"),                cafti_zh_chinese_custU },
   4301         { "zh@calendar=chinese",  DateFormat::kNone, CharsToUnicodeString("r\\u5E74MMMd"),                 cafti_zh_chinese_custNoU },
   4302         { "ja@calendar=japanese", DateFormat::kNone, CharsToUnicodeString("r(Gy)\\u5E74M\\u6708d\\u65E5"), cafti_ja_japanese_custGy },
   4303         { "ja@calendar=japanese", DateFormat::kNone, CharsToUnicodeString("r\\u5E74M\\u6708d\\u65E5"),     cafti_ja_japanese_custNoGy },
   4304         { "en@calendar=islamic",  DateFormat::kNone, UnicodeString("d MMM y G, r"),     cafti_en_islamic_cust },
   4305         { NULL, DateFormat::kNone, UnicodeString(""), NULL } // terminator
   4306     };
   4307     const TestNonGregoItem * itemPtr;
   4308     for (itemPtr = items; itemPtr->locale != NULL; itemPtr++) {
   4309         Locale locale = Locale::createFromName(itemPtr->locale);
   4310         DateFormat * dfmt = NULL;
   4311         UErrorCode status = U_ZERO_ERROR;
   4312         if (itemPtr->style != DateFormat::kNone) {
   4313             dfmt = DateFormat::createDateInstance(itemPtr->style, locale);
   4314         } else {
   4315             dfmt = new SimpleDateFormat(itemPtr->pattern, locale, status);
   4316         }
   4317         if (U_FAILURE(status)) {
   4318             dataerrln("new SimpleDateFormat fails for locale %s", itemPtr->locale);
   4319         } else  if (dfmt == NULL) {
   4320             dataerrln("DateFormat::createDateInstance fails for locale %s", itemPtr->locale);
   4321         } else {
   4322             Calendar * cal = (dfmt->getCalendar())->clone();
   4323             if (cal == NULL) {
   4324                 dataerrln("(DateFormat::getCalendar)->clone() fails for locale %s", itemPtr->locale);
   4325             } else {
   4326                 const CalAndFmtTestItem * caftItemPtr;
   4327                 for (caftItemPtr = itemPtr->caftItems; caftItemPtr->year != 0; caftItemPtr++) {
   4328                     cal->clear();
   4329                     cal->set(UCAL_ERA,    caftItemPtr->era);
   4330                     cal->set(UCAL_YEAR,   caftItemPtr->year);
   4331                     cal->set(UCAL_MONTH,  caftItemPtr->month);
   4332                     cal->set(UCAL_DATE,   caftItemPtr->day);
   4333                     cal->set(UCAL_HOUR_OF_DAY, caftItemPtr->hour);
   4334                     cal->set(UCAL_MINUTE, caftItemPtr->minute);
   4335                     UnicodeString result;
   4336                     FieldPosition fpos(FieldPosition::DONT_CARE);
   4337                     dfmt->format(*cal, result, fpos);
   4338                     if ( result.compare(caftItemPtr->formattedDate) != 0 ) {
   4339                         errln( UnicodeString("FAIL: date format for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
   4340                                 ", expected \"" + caftItemPtr->formattedDate + "\", got \"" + result + "\"");
   4341                     } else {
   4342                         // formatted OK, try parse
   4343                         ParsePosition ppos(0);
   4344                         dfmt->parse(result, *cal, ppos);
   4345                         status = U_ZERO_ERROR;
   4346                         int32_t era = cal->get(UCAL_ERA, status);
   4347                         int32_t year = cal->get(UCAL_YEAR, status);
   4348                         int32_t month = cal->get(UCAL_MONTH, status);
   4349                         int32_t day = cal->get(UCAL_DATE, status);
   4350                         if ( U_FAILURE(status) || ppos.getIndex() < result.length() || era != caftItemPtr->era ||
   4351                                 year != caftItemPtr->year || month != caftItemPtr->month || day != caftItemPtr->day ) {
   4352                             errln( UnicodeString("FAIL: date parse for locale ") + UnicodeString(itemPtr->locale) +
   4353                                 ", style " + itemPtr->style + ", string \"" + result + "\", expected " +
   4354                                 caftItemPtr->era +":"+caftItemPtr->year +"-"+caftItemPtr->month+"-"+caftItemPtr->day + ", got pos " +
   4355                                 ppos.getIndex() + " " + year +"-"+month+"-"+day + " status " + UnicodeString(u_errorName(status)) );
   4356                         }
   4357                     }
   4358                 }
   4359                 delete cal;
   4360             }
   4361             delete dfmt;
   4362         }
   4363     }
   4364 }
   4365 
   4366 typedef struct {
   4367     const char*         localeID;
   4368     DateFormat::EStyle  style;
   4369     UnicodeString       expectPattern;
   4370     UnicodeString       expectFormat;
   4371 } TestFmtWithNumSysItem;
   4372 enum { kBBufMax = 128 };
   4373 void DateFormatTest::TestFormatsWithNumberSystems()
   4374 {
   4375     LocalPointer<TimeZone> zone(TimeZone::createTimeZone(UnicodeString("UTC")));
   4376     const UDate date = 1451556000000.0; // for UTC: grego 31-Dec-2015 10 AM, hebrew 19 tevet 5776, chinese yi-wei 11mo 21day
   4377     const TestFmtWithNumSysItem items[] = {
   4378         { "haw@calendar=gregorian", DateFormat::kShort, UnicodeString("d/M/yy"),               UnicodeString("31/xii/15") },
   4379         { "he@calendar=hebrew",     DateFormat::kLong, CharsToUnicodeString("d \\u05D1MMMM y"), CharsToUnicodeString("\\u05D9\\u05F4\\u05D8 \\u05D1\\u05D8\\u05D1\\u05EA \\u05EA\\u05E9\\u05E2\\u05F4\\u05D5") },
   4380         { "zh@calendar=chinese",      DateFormat::kLong, CharsToUnicodeString("rU\\u5E74MMMd"), CharsToUnicodeString("2015\\u4E59\\u672A\\u5E74\\u5341\\u4E00\\u6708\\u5EFF\\u4E00") },
   4381         { "zh_Hant@calendar=chinese", DateFormat::kLong, CharsToUnicodeString("rU\\u5E74MMMd"), CharsToUnicodeString("2015\\u4E59\\u672A\\u5E74\\u51AC\\u6708\\u5EFF\\u4E00") },
   4382         { "ja@calendar=chinese", DateFormat::kLong, CharsToUnicodeString("U\\u5E74MMMd\\u65E5"), CharsToUnicodeString("\\u4E59\\u672A\\u5E74\\u5341\\u4E00\\u6708\\u4E8C\\u4E00\\u65E5") },
   4383         { NULL, DateFormat::kNone, UnicodeString(""), UnicodeString("") },
   4384     };
   4385     const TestFmtWithNumSysItem * itemPtr;
   4386     for (itemPtr = items; itemPtr->localeID != NULL; itemPtr++) {
   4387         char bExpected[kBBufMax];
   4388         char bResult[kBBufMax];
   4389         UErrorCode status = U_ZERO_ERROR;
   4390         Locale locale = Locale::createFromName(itemPtr->localeID);
   4391         LocalPointer<Calendar> cal(Calendar::createInstance(zone.orphan(), locale, status));
   4392         if (U_FAILURE(status)) {
   4393             dataerrln("Calendar::createInstance fails for locale %s, status %s", itemPtr->localeID, u_errorName(status));
   4394             continue;
   4395         }
   4396         cal->setTime(date, status);
   4397         if (U_FAILURE(status)) {
   4398             dataerrln("Calendar::setTime fails for locale %s, date %.1f, status %s", itemPtr->localeID, date, u_errorName(status));
   4399             continue;
   4400         }
   4401         LocalPointer<SimpleDateFormat> sdfmt(static_cast<SimpleDateFormat *>(DateFormat::createDateInstance(itemPtr->style, locale)));
   4402         if (sdfmt.isNull()) {
   4403             dataerrln("DateFormat::createDateInstance fails for locale %s", itemPtr->localeID);
   4404             continue;
   4405         }
   4406         UnicodeString getFormat;
   4407         sdfmt->format(*(cal.getAlias()), getFormat, NULL, status);
   4408         if (U_FAILURE(status)) {
   4409             errln("DateFormat::format fails for locale %s, status %s", itemPtr->localeID, u_errorName(status));
   4410             continue;
   4411         }
   4412         if (getFormat.compare(itemPtr->expectFormat) != 0) {
   4413             itemPtr->expectFormat.extract(0, itemPtr->expectFormat.length(), bExpected, kBBufMax);
   4414             getFormat.extract(0, getFormat.length(), bResult, kBBufMax);
   4415             errln("DateFormat::format for locale %s, expected \"%s\", got \"%s\"", itemPtr->localeID, bExpected, bResult);
   4416         }
   4417         UnicodeString getPattern;
   4418         sdfmt->toPattern(getPattern);
   4419         if (getPattern.compare(itemPtr->expectPattern) != 0) {
   4420             itemPtr->expectPattern.extract(0, itemPtr->expectPattern.length(), bExpected, kBBufMax);
   4421             getPattern.extract(0, getPattern.length(), bResult, kBBufMax);
   4422             errln("DateFormat::toPattern() for locale %s, expected \"%s\", got \"%s\"", itemPtr->localeID, bExpected, bResult);
   4423         }
   4424     }
   4425 }
   4426 
   4427 static const UDate TEST_DATE = 1326585600000.;  // 2012-jan-15
   4428 
   4429 void DateFormatTest::TestDotAndAtLeniency() {
   4430     // Test for date/time parsing regression with CLDR 22.1/ICU 50 pattern strings.
   4431     // For details see http://bugs.icu-project.org/trac/ticket/9789
   4432     static const char *locales[] = { "en", "fr" };
   4433     for (int32_t i = 0; i < UPRV_LENGTHOF(locales); ++i) {
   4434         Locale locale(locales[i]);
   4435 
   4436         for (DateFormat::EStyle dateStyle = DateFormat::FULL; dateStyle <= DateFormat::SHORT;
   4437                   dateStyle = static_cast<DateFormat::EStyle>(dateStyle + 1)) {
   4438             LocalPointer<DateFormat> dateFormat(DateFormat::createDateInstance(dateStyle, locale));
   4439 
   4440             for (DateFormat::EStyle timeStyle = DateFormat::FULL; timeStyle <= DateFormat::SHORT;
   4441                       timeStyle = static_cast<DateFormat::EStyle>(timeStyle + 1)) {
   4442                 LocalPointer<DateFormat> format(DateFormat::createDateTimeInstance(dateStyle, timeStyle, locale));
   4443                 LocalPointer<DateFormat> timeFormat(DateFormat::createTimeInstance(timeStyle, locale));
   4444                 UnicodeString formattedString;
   4445                 if (format.isNull()) {
   4446                     dataerrln("Unable to create DateFormat");
   4447                     continue;
   4448                 }
   4449                 format->format(TEST_DATE, formattedString);
   4450 
   4451                 if (!showParse(*format, formattedString)) {
   4452                     errln(UnicodeString("    with date-time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle);
   4453                 }
   4454 
   4455                 UnicodeString ds, ts;
   4456                 formattedString = dateFormat->format(TEST_DATE, ds) + "  " + timeFormat->format(TEST_DATE, ts);
   4457                 if (!showParse(*format, formattedString)) {
   4458                     errln(UnicodeString("    with date sp sp time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle);
   4459                 }
   4460                 if (formattedString.indexOf("n ") >= 0) { // will add "." after the end of text ending in 'n', like Jan.
   4461                     UnicodeString plusDot(formattedString);
   4462                     plusDot.findAndReplace("n ", "n. ").append(".");
   4463                     if (!showParse(*format, plusDot)) {
   4464                         errln(UnicodeString("    with date plus-dot time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle);
   4465                     }
   4466                 }
   4467                 if (formattedString.indexOf(". ") >= 0) { // will subtract "." at the end of strings.
   4468                     UnicodeString minusDot(formattedString);
   4469                     minusDot.findAndReplace(". ", " ");
   4470                     if (!showParse(*format, minusDot)) {
   4471                         errln(UnicodeString("    with date minus-dot time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle);
   4472                     }
   4473                 }
   4474             }
   4475         }
   4476     }
   4477 }
   4478 
   4479 UBool DateFormatTest::showParse(DateFormat &format, const UnicodeString &formattedString) {
   4480     ParsePosition parsePosition;
   4481     UDate parsed = format.parse(formattedString, parsePosition);
   4482     UBool ok = TEST_DATE == parsed && parsePosition.getIndex() == formattedString.length();
   4483     UnicodeString pattern;
   4484     static_cast<SimpleDateFormat &>(format).toPattern(pattern);
   4485     if (ok) {
   4486         logln(pattern + "  parsed: " + formattedString);
   4487     } else {
   4488         errln(pattern + "  fails to parse: " + formattedString);
   4489     }
   4490     return ok;
   4491 }
   4492 
   4493 
   4494 typedef struct {
   4495     const char * locale;
   4496     UBool leniency;
   4497     UnicodeString parseString;
   4498     UnicodeString pattern;
   4499     UnicodeString expectedResult;       // empty string indicates expected error
   4500 } TestDateFormatLeniencyItem;
   4501 
   4502 void DateFormatTest::TestDateFormatLeniency() {
   4503     // For details see http://bugs.icu-project.org/trac/ticket/10261
   4504 
   4505     const UDate july022008 = 1215000001979.0;
   4506     const TestDateFormatLeniencyItem items[] = {
   4507         //locale    leniency    parse String                    pattern                             expected result
   4508         { "en",     true,       UnicodeString("2008-07 02"),    UnicodeString("yyyy-LLLL dd"),      UnicodeString("2008-July 02") },
   4509         { "en",     false,      UnicodeString("2008-07 02"),    UnicodeString("yyyy-LLLL dd"),      UnicodeString("") },
   4510         { "en",     true,       UnicodeString("2008-Jan 02"),   UnicodeString("yyyy-LLL. dd"),      UnicodeString("2008-Jan. 02") },
   4511         { "en",     false,      UnicodeString("2008-Jan 02"),   UnicodeString("yyyy-LLL. dd"),      UnicodeString("") },
   4512         { "en",     true,       UnicodeString("2008-Jan--02"),  UnicodeString("yyyy-MMM' -- 'dd"),  UnicodeString("2008-Jan -- 02") },
   4513         { "en",     false,      UnicodeString("2008-Jan--02"),  UnicodeString("yyyy-MMM' -- 'dd"),  UnicodeString("") },
   4514         // terminator
   4515         { NULL,     true,       UnicodeString(""),              UnicodeString(""),                  UnicodeString("") }
   4516     };
   4517     UErrorCode status = U_ZERO_ERROR;
   4518     LocalPointer<Calendar> cal(Calendar::createInstance(status));
   4519     if (U_FAILURE(status)) {
   4520         dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale."));
   4521         return;
   4522     }
   4523     cal->setTime(july022008, status);
   4524     const TestDateFormatLeniencyItem * itemPtr;
   4525     LocalPointer<SimpleDateFormat> sdmft;
   4526     for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
   4527 
   4528        Locale locale = Locale::createFromName(itemPtr->locale);
   4529        status = U_ZERO_ERROR;
   4530        ParsePosition pos(0);
   4531        sdmft.adoptInsteadAndCheckErrorCode(new SimpleDateFormat(itemPtr->pattern, locale, status), status);
   4532        if (U_FAILURE(status)) {
   4533            dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
   4534            continue;
   4535        }
   4536        sdmft->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->leniency, status).
   4537               setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->leniency, status).
   4538               setBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, itemPtr->leniency, status);
   4539        UDate d = sdmft->parse(itemPtr->parseString, pos);
   4540 
   4541        if(itemPtr->expectedResult.length() == 0) {
   4542            if(pos.getErrorIndex() != -1) {
   4543                continue;
   4544            } else {
   4545                 errln("error: unexpected parse success - " + itemPtr->parseString +
   4546                     " - pattern " + itemPtr->pattern +
   4547                     " - error index " + pos.getErrorIndex() +
   4548                     " - leniency " + itemPtr->leniency);
   4549                 continue;
   4550            }
   4551        }
   4552        if(pos.getErrorIndex() != -1) {
   4553            errln("error: parse error for string - "  + itemPtr->parseString +
   4554                  " - pattern " + itemPtr->pattern +
   4555                  " - idx " + pos.getIndex() +
   4556                  " - error index "+pos.getErrorIndex() +
   4557                  " - leniency " + itemPtr->leniency);
   4558             continue;
   4559         }
   4560 
   4561        UnicodeString formatResult("");
   4562        sdmft->format(d, formatResult);
   4563        if(formatResult.compare(itemPtr->expectedResult) != 0) {
   4564            errln("error: unexpected format result. pattern["+itemPtr->pattern+"] expected[" + itemPtr->expectedResult + "]  but result was[" + formatResult + "]");
   4565            continue;
   4566         } else {
   4567             logln("formatted results match! - " + formatResult);
   4568         }
   4569 
   4570     }
   4571 }
   4572 
   4573 
   4574 typedef struct {
   4575     UBool leniency;
   4576     UnicodeString parseString;
   4577     UnicodeString pattern;
   4578     UnicodeString expectedResult;       // empty string indicates expected error
   4579 } TestMultiPatternMatchItem;
   4580 
   4581 void DateFormatTest::TestParseMultiPatternMatch() {
   4582         // For details see http://bugs.icu-project.org/trac/ticket/10336
   4583     const TestMultiPatternMatchItem items[] = {
   4584           // leniency    parse String                                 pattern                               expected result
   4585             {true,       UnicodeString("2013-Sep 13"),                UnicodeString("yyyy-MMM dd"),         UnicodeString("2013-Sep 13")},
   4586             {true,       UnicodeString("2013-September 14"),          UnicodeString("yyyy-MMM dd"),         UnicodeString("2013-Sep 14")},
   4587             {false,      UnicodeString("2013-September 15"),          UnicodeString("yyyy-MMM dd"),         UnicodeString("")},
   4588             {false,      UnicodeString("2013-September 16"),          UnicodeString("yyyy-MMMM dd"),        UnicodeString("2013-September 16")},
   4589             {true,       UnicodeString("2013-Sep 17"),                UnicodeString("yyyy-LLL dd"),         UnicodeString("2013-Sep 17")},
   4590             {true,       UnicodeString("2013-September 18"),          UnicodeString("yyyy-LLL dd"),         UnicodeString("2013-Sep 18")},
   4591             {false,      UnicodeString("2013-September 19"),          UnicodeString("yyyy-LLL dd"),         UnicodeString("")},
   4592             {false,      UnicodeString("2013-September 20"),          UnicodeString("yyyy-LLLL dd"),        UnicodeString("2013-September 20")},
   4593             {true,       UnicodeString("2013 Sat Sep 21"),            UnicodeString("yyyy EEE MMM dd"),     UnicodeString("2013 Sat Sep 21")},
   4594             {true,       UnicodeString("2013 Sunday Sep 22"),         UnicodeString("yyyy EEE MMM dd"),     UnicodeString("2013 Sun Sep 22")},
   4595             {false,      UnicodeString("2013 Monday Sep 23"),         UnicodeString("yyyy EEE MMM dd"),     UnicodeString("")},
   4596             {false,      UnicodeString("2013 Tuesday Sep 24"),        UnicodeString("yyyy EEEE MMM dd"),    UnicodeString("2013 Tuesday Sep 24")},
   4597             {true,       UnicodeString("2013 Wed Sep 25"),            UnicodeString("yyyy eee MMM dd"),     UnicodeString("2013 Wed Sep 25")},
   4598             {true,       UnicodeString("2013 Thu Sep 26"),            UnicodeString("yyyy eee MMM dd"),     UnicodeString("2013 Thu Sep 26")},
   4599             {false,      UnicodeString("2013 Friday Sep 27"),         UnicodeString("yyyy eee MMM dd"),     UnicodeString("")},
   4600             {false,      UnicodeString("2013 Saturday Sep 28"),       UnicodeString("yyyy eeee MMM dd"),    UnicodeString("2013 Saturday Sep 28")},
   4601             {true,       UnicodeString("2013 Sun Sep 29"),            UnicodeString("yyyy ccc MMM dd"),     UnicodeString("2013 Sun Sep 29")},
   4602             {true,       UnicodeString("2013 Monday Sep 30"),         UnicodeString("yyyy ccc MMM dd"),     UnicodeString("2013 Mon Sep 30")},
   4603             {false,      UnicodeString("2013 Sunday Oct 13"),         UnicodeString("yyyy ccc MMM dd"),     UnicodeString("")},
   4604             {false,      UnicodeString("2013 Monday Oct 14"),         UnicodeString("yyyy cccc MMM dd"),    UnicodeString("2013 Monday Oct 14")},
   4605             {true,       UnicodeString("2013 Oct 15 Q4"),             UnicodeString("yyyy MMM dd QQQ"),     UnicodeString("2013 Oct 15 Q4")},
   4606             {true,       UnicodeString("2013 Oct 16 4th quarter"),    UnicodeString("yyyy MMM dd QQQ"),     UnicodeString("2013 Oct 16 Q4")},
   4607             {false,      UnicodeString("2013 Oct 17 4th quarter"),    UnicodeString("yyyy MMM dd QQQ"),     UnicodeString("")},
   4608             {false,      UnicodeString("2013 Oct 18 Q4"),             UnicodeString("yyyy MMM dd QQQ"),     UnicodeString("2013 Oct 18 Q4")},
   4609             {true,       UnicodeString("2013 Oct 19 Q4"),             UnicodeString("yyyy MMM dd qqqq"),    UnicodeString("2013 Oct 19 4th quarter")},
   4610             {true,       UnicodeString("2013 Oct 20 4th quarter"),    UnicodeString("yyyy MMM dd qqqq"),    UnicodeString("2013 Oct 20 4th quarter")},
   4611             {false,      UnicodeString("2013 Oct 21 Q4"),             UnicodeString("yyyy MMM dd qqqq"),    UnicodeString("")},
   4612             {false,      UnicodeString("2013 Oct 22 4th quarter"),    UnicodeString("yyyy MMM dd qqqq"),    UnicodeString("2013 Oct 22 4th quarter")},
   4613             {false,      UnicodeString("--end--"),                    UnicodeString(""),                    UnicodeString("")},
   4614     };
   4615 
   4616     UErrorCode status = U_ZERO_ERROR;
   4617     LocalPointer<Calendar> cal(Calendar::createInstance(status));
   4618     if (U_FAILURE(status)) {
   4619         dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale."));
   4620         return;
   4621     }
   4622     const TestMultiPatternMatchItem * itemPtr;
   4623     DateFormat* sdmft = DateFormat::createDateInstance();
   4624     if (sdmft == NULL) {
   4625         dataerrln(UnicodeString("FAIL: Unable to create DateFormat"));
   4626         return;
   4627     }
   4628     for (itemPtr = items; itemPtr->parseString != "--end--"; itemPtr++ ) {
   4629        status = U_ZERO_ERROR;
   4630        ParsePosition pos(0);
   4631        ((SimpleDateFormat*) sdmft)->applyPattern(itemPtr->pattern);
   4632        if (U_FAILURE(status)) {
   4633            dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
   4634            continue;
   4635        }
   4636        sdmft->setBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, itemPtr->leniency, status);
   4637        UDate d = sdmft->parse(itemPtr->parseString, pos);
   4638 
   4639        if(itemPtr->expectedResult.length() == 0) {
   4640            if(pos.getErrorIndex() != -1) {
   4641                continue;
   4642            } else {
   4643                 errln("error: unexpected parse success - " + itemPtr->parseString +
   4644                     " - error index " + pos.getErrorIndex() +
   4645                     " - leniency " + itemPtr->leniency);
   4646                 continue;
   4647            }
   4648         }
   4649         if(pos.getErrorIndex() != -1) {
   4650             errln("error: parse error for string - " +itemPtr->parseString + " -- idx["+pos.getIndex()+"] errIdx["+pos.getErrorIndex()+"]");
   4651             continue;
   4652         }
   4653 
   4654         UnicodeString formatResult("");
   4655         sdmft->format(d, formatResult);
   4656         if(formatResult.compare(itemPtr->expectedResult) != 0) {
   4657             errln("error: unexpected format result. expected[" + itemPtr->expectedResult + "]  but result was[" + formatResult + "]");
   4658         } else {
   4659             logln("formatted results match! - " + formatResult);
   4660         }
   4661     }
   4662     delete sdmft;
   4663 }
   4664 
   4665 void DateFormatTest::TestParseLeniencyAPIs() {
   4666     UErrorCode status = U_ZERO_ERROR;
   4667     LocalPointer<DateFormat> dateFormat(DateFormat::createDateInstance());
   4668     DateFormat *fmt = dateFormat.getAlias();
   4669     if (fmt == NULL) {
   4670         dataerrln("Failed calling dateFormat.getAlias()");
   4671         return;
   4672     }
   4673 
   4674     assertTrue("isLenient default", fmt->isLenient());
   4675     assertTrue("isCalendarLenient default", fmt->isCalendarLenient());
   4676     assertTrue("ALLOW_WHITESPACE default", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status));
   4677     assertTrue("ALLOW_NUMERIC default", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status));
   4678     assertTrue("PARTIAL_MATCH default", fmt->getBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, status));
   4679     assertTrue("MULTIPLE_PATTERNS default", fmt->getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status));
   4680 
   4681     // Set calendar to strict
   4682     fmt->setCalendarLenient(FALSE);
   4683 
   4684     assertFalse("isLeninent after setCalendarLenient(FALSE)", fmt->isLenient());
   4685     assertFalse("isCalendarLenient after setCalendarLenient(FALSE)", fmt->isCalendarLenient());
   4686     assertTrue("ALLOW_WHITESPACE after setCalendarLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status));
   4687     assertTrue("ALLOW_NUMERIC  after setCalendarLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status));
   4688 
   4689     // Set to strict
   4690     fmt->setLenient(FALSE);
   4691 
   4692     assertFalse("isLeninent after setLenient(FALSE)", fmt->isLenient());
   4693     assertFalse("isCalendarLenient after setLenient(FALSE)", fmt->isCalendarLenient());
   4694     assertFalse("ALLOW_WHITESPACE after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status));
   4695     assertFalse("ALLOW_NUMERIC  after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status));
   4696     // These two boolean attributes are NOT affected according to the API specification
   4697     assertTrue("PARTIAL_MATCH after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, status));
   4698     assertTrue("MULTIPLE_PATTERNS after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status));
   4699 
   4700     // Allow white space leniency
   4701     fmt->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, TRUE, status);
   4702 
   4703     assertFalse("isLeninent after ALLOW_WHITESPACE/TRUE", fmt->isLenient());
   4704     assertFalse("isCalendarLenient after ALLOW_WHITESPACE/TRUE", fmt->isCalendarLenient());
   4705     assertTrue("ALLOW_WHITESPACE after ALLOW_WHITESPACE/TRUE", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status));
   4706     assertFalse("ALLOW_NUMERIC  after ALLOW_WHITESPACE/TRUE", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status));
   4707 
   4708     // Set to lenient
   4709     fmt->setLenient(TRUE);
   4710 
   4711     assertTrue("isLenient after setLenient(TRUE)", fmt->isLenient());
   4712     assertTrue("isCalendarLenient after setLenient(TRUE)", fmt->isCalendarLenient());
   4713     assertTrue("ALLOW_WHITESPACE after setLenient(TRUE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status));
   4714     assertTrue("ALLOW_NUMERIC after setLenient(TRUE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status));
   4715 }
   4716 
   4717 void DateFormatTest::TestNumberFormatOverride() {
   4718     UErrorCode status = U_ZERO_ERROR;
   4719     UnicodeString fields = (UnicodeString) "M";
   4720 
   4721     LocalPointer<SimpleDateFormat> fmt;
   4722     fmt.adoptInsteadAndCheckErrorCode(new SimpleDateFormat((UnicodeString)"MM d", status), status);
   4723     if (!assertSuccess("SimpleDateFormat with pattern MM d", status)) {
   4724         return;
   4725     }
   4726 
   4727 
   4728     for(int i=0; i<3; i++){
   4729         NumberFormat* check_nf = NumberFormat::createInstance(Locale("en_US"), status);
   4730         assertSuccess("NumberFormat en_US", status);
   4731         fmt->adoptNumberFormat(fields, check_nf, status);
   4732         assertSuccess("adoptNumberFormat check_nf", status);
   4733 
   4734         const NumberFormat* get_nf = fmt->getNumberFormatForField((UChar)0x004D /*'M'*/);
   4735         if (get_nf != check_nf) errln("FAIL: getter and setter do not work");
   4736     }
   4737     NumberFormat* check_nf = NumberFormat::createInstance(Locale("en_US"), status);
   4738     assertSuccess("NumberFormat en_US", status);
   4739     fmt->adoptNumberFormat(check_nf); // make sure using the same NF will not crash
   4740 
   4741     const char * DATA [][2] = {
   4742         { "", "\\u521D\\u516D \\u5341\\u4E94"},
   4743         { "M", "\\u521D\\u516D 15"},
   4744         { "Mo", "\\u521D\\u516D 15"},
   4745         { "Md", "\\u521D\\u516D \\u5341\\u4E94"},
   4746         { "MdMMd", "\\u521D\\u516D \\u5341\\u4E94"},
   4747         { "mixed", "\\u521D\\u516D \\u5341\\u4E94"}
   4748     };
   4749 
   4750     UDate test_date = date(97, 6 - 1, 15);
   4751 
   4752     for(int i=0; i < UPRV_LENGTHOF(DATA); i++){
   4753         fields = DATA[i][0];
   4754 
   4755         LocalPointer<SimpleDateFormat> fmt;
   4756         fmt.adoptInsteadAndCheckErrorCode(new SimpleDateFormat((UnicodeString)"MM d", status), status);
   4757         assertSuccess("SimpleDateFormat with pattern MM d", status);
   4758         NumberFormat* overrideNF = NumberFormat::createInstance(Locale::createFromName("zh@numbers=hanidays"),status);
   4759         assertSuccess("NumberFormat zh@numbers=hanidays", status);
   4760 
   4761         if (fields == (UnicodeString) "") { // use the one w/o fields
   4762             fmt->adoptNumberFormat(overrideNF);
   4763         } else if (fields == (UnicodeString) "mixed") { // set 1 field at first but then full override, both(M & d) should be override
   4764             NumberFormat* singleOverrideNF = NumberFormat::createInstance(Locale::createFromName("en@numbers=hebr"),status);
   4765             assertSuccess("NumberFormat en@numbers=hebr", status);
   4766 
   4767             fields = (UnicodeString) "M";
   4768             fmt->adoptNumberFormat(fields, singleOverrideNF, status);
   4769             assertSuccess("adoptNumberFormat singleOverrideNF", status);
   4770 
   4771             fmt->adoptNumberFormat(overrideNF);
   4772         } else if (fields == (UnicodeString) "Mo"){ // o is invlid field
   4773             fmt->adoptNumberFormat(fields, overrideNF, status);
   4774             if(status == U_INVALID_FORMAT_ERROR) {
   4775                 status = U_ZERO_ERROR;
   4776                 continue;
   4777             }
   4778         } else {
   4779             fmt->adoptNumberFormat(fields, overrideNF, status);
   4780             assertSuccess("adoptNumberFormat overrideNF", status);
   4781         }
   4782 
   4783         UnicodeString result;
   4784         FieldPosition pos(FieldPosition::DONT_CARE);
   4785         fmt->format(test_date,result, pos);
   4786 
   4787         UnicodeString expected = ((UnicodeString)DATA[i][1]).unescape();;
   4788 
   4789         if (result != expected)
   4790             errln("FAIL: Expected " + expected + " get: " + result);
   4791     }
   4792 }
   4793 
   4794 void DateFormatTest::TestCreateInstanceForSkeleton() {
   4795     UErrorCode status = U_ZERO_ERROR;
   4796     LocalPointer<DateFormat> fmt(DateFormat::createInstanceForSkeleton(
   4797             "yMMMMd", "en", status));
   4798     if (!assertSuccess("Create with pattern yMMMMd", status)) {
   4799         return;
   4800     }
   4801     UnicodeString result;
   4802     FieldPosition pos(FieldPosition::DONT_CARE);
   4803     fmt->format(date(98, 5-1, 25), result, pos);
   4804     assertEquals("format yMMMMd", "May 25, 1998", result);
   4805     fmt.adoptInstead(DateFormat::createInstanceForSkeleton(
   4806             "yMd", "en", status));
   4807     if (!assertSuccess("Create with pattern yMd", status)) {
   4808         return;
   4809     }
   4810     result.remove();
   4811     fmt->format(date(98, 5-1, 25), result, pos);
   4812     assertEquals("format yMd", "5/25/1998", result);
   4813 }
   4814 
   4815 void DateFormatTest::TestCreateInstanceForSkeletonDefault() {
   4816     UErrorCode status = U_ZERO_ERROR;
   4817     Locale savedLocale;
   4818     Locale::setDefault(Locale::getUS(), status);
   4819     LocalPointer<DateFormat> fmt(DateFormat::createInstanceForSkeleton(
   4820             "yMMMd", status));
   4821     Locale::setDefault(savedLocale, status);
   4822     if (!assertSuccess("Create with pattern yMMMd", status)) {
   4823         return;
   4824     }
   4825     UnicodeString result;
   4826     FieldPosition pos(FieldPosition::DONT_CARE);
   4827     fmt->format(date(98, 5-1, 25), result, pos);
   4828     assertEquals("format yMMMd", "May 25, 1998", result);
   4829 }
   4830 
   4831 void DateFormatTest::TestCreateInstanceForSkeletonWithCalendar() {
   4832     UErrorCode status = U_ZERO_ERROR;
   4833     LocalPointer<DateFormat> fmt(
   4834             DateFormat::createInstanceForSkeleton(
   4835                     Calendar::createInstance(
   4836                             TimeZone::createTimeZone("GMT-3:00"),
   4837                             status),
   4838                     "yMdHm", "en", status));
   4839     if (!assertSuccess("Create with pattern yMMMMd", status)) {
   4840         return;
   4841     }
   4842     UnicodeString result;
   4843     FieldPosition pos(FieldPosition::DONT_CARE);
   4844 
   4845     LocalPointer<Calendar> cal(Calendar::createInstance(
   4846         TimeZone::createTimeZone("GMT-7:00"),
   4847         status));
   4848     if (!assertSuccess("Creating GMT-7 time zone failed", status)) {
   4849         return;
   4850     }
   4851     cal->clear();
   4852     cal->set(1998, 5-1, 25, 0, 0, 0);
   4853 
   4854     // date format time zone should be 4 hours ahead.
   4855     fmt->format(cal->getTime(status), result, pos);
   4856     assertEquals("format yMdHm", "5/25/1998, 04:00", result);
   4857     assertSuccess("", status);
   4858 }
   4859 
   4860 void DateFormatTest::TestDFSCreateForLocaleNonGregorianLocale() {
   4861     UErrorCode status = U_ZERO_ERROR;
   4862     Locale fa("fa");
   4863     LocalPointer<DateFormatSymbols> sym(
   4864             DateFormatSymbols::createForLocale(fa, status));
   4865     if (!assertSuccess("", status)) {
   4866         return;
   4867     }
   4868 
   4869     // Android: All locales default to Gregorian calendar:
   4870     int32_t count;
   4871     const UnicodeString *months = sym->getShortMonths(count);
   4872 
   4873     // First persian month.
   4874     UnicodeString expected("\\u0698\\u0627\\u0646\\u0648\\u06CC\\u0647\\u0654");  // Android-changed
   4875     assertEquals("", expected.unescape(), months[0]);
   4876 }
   4877 
   4878 void DateFormatTest::TestDFSCreateForLocaleWithCalendarInLocale() {
   4879     UErrorCode status = U_ZERO_ERROR;
   4880     Locale en_heb("en@calendar=hebrew");
   4881     LocalPointer<DateFormatSymbols> sym(
   4882             DateFormatSymbols::createForLocale(en_heb, status));
   4883     if (!assertSuccess("", status)) {
   4884         return;
   4885     }
   4886 
   4887     // We should get the months of the hebrew calendar, not the gregorian
   4888     // calendar.
   4889     int32_t count;
   4890     const UnicodeString *months = sym->getShortMonths(count);
   4891 
   4892     // First hebrew month.
   4893     UnicodeString expected("Tishri");
   4894     assertEquals("", expected, months[0]);
   4895 }
   4896 
   4897 void DateFormatTest::TestChangeCalendar() {
   4898     UErrorCode status = U_ZERO_ERROR;
   4899     Locale en("en");
   4900     Locale en_heb("en@calendar=hebrew");
   4901     LocalPointer<DateFormat> fmt(
   4902             DateFormat::createInstanceForSkeleton("yMMMd", en, status));
   4903     if (!assertSuccess("", status)) {
   4904         return;
   4905     }
   4906     fmt->adoptCalendar(Calendar::createInstance(en_heb, status));
   4907     if (!assertSuccess("", status)) {
   4908         return;
   4909     }
   4910     UnicodeString result;
   4911     FieldPosition pos(FieldPosition::DONT_CARE);
   4912     fmt->format(date(98, 5-1, 25), result, pos);
   4913     assertEquals("format yMMMd", "Iyar 29, 5758", result);
   4914 }
   4915 
   4916 void DateFormatTest::TestPatternFromSkeleton() {
   4917     static const struct {
   4918         const Locale& locale;
   4919         const char* const skeleton;
   4920         const char* const pattern;
   4921     } TESTDATA[] = {
   4922         // Ticket #11985
   4923         {Locale::getEnglish(), "jjmm", "h:mm a"},
   4924         {Locale::getEnglish(), "JJmm", "hh:mm"},
   4925         {Locale::getGerman(), "jjmm", "HH:mm"},
   4926         {Locale::getGerman(), "JJmm", "HH:mm"}
   4927     };
   4928 
   4929     for (size_t i = 0; i < UPRV_LENGTHOF(TESTDATA); i++) {
   4930         UErrorCode status = U_ZERO_ERROR;
   4931         LocalPointer<DateFormat> fmt(
   4932                 DateFormat::createInstanceForSkeleton(
   4933                         TESTDATA[i].skeleton, TESTDATA[i].locale, status));
   4934         if (!assertSuccess("createInstanceForSkeleton", status)) {
   4935             return;
   4936         }
   4937         UnicodeString pattern;
   4938         static_cast<const SimpleDateFormat*>(fmt.getAlias())->toPattern(pattern);
   4939         assertEquals("Format pattern", TESTDATA[i].pattern, pattern);
   4940     }
   4941 }
   4942 
   4943 void DateFormatTest::TestAmPmMidnightNoon() {
   4944     // Some times on 2015-11-13 (UTC+0).
   4945     UDate k000000 = 1447372800000.0;
   4946     UDate k000030 = 1447372830000.0;
   4947     UDate k003000 = 1447374600000.0;
   4948     UDate k060000 = 1447394400000.0;
   4949     UDate k120000 = 1447416000000.0;
   4950     UDate k180000 = 1447437600000.0;
   4951 
   4952     UErrorCode errorCode = U_ZERO_ERROR;
   4953     SimpleDateFormat sdf(UnicodeString(), errorCode);
   4954     if (U_FAILURE(errorCode)) {
   4955         dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
   4956         return;
   4957     }
   4958     const TimeZone *tz = TimeZone::getGMT();
   4959     sdf.setTimeZone(*tz);
   4960     UnicodeString out;
   4961 
   4962     // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
   4963     // For ICU 57 output of "midnight" is temporarily suppressed.
   4964 
   4965     // Short.
   4966     sdf.applyPattern(UnicodeString("hh:mm:ss bbb"));
   4967 
   4968     // assertEquals("hh:mm:ss bbb | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove()));
   4969     assertEquals("hh:mm:ss bbb | 00:00:00", "12:00:00 AM", sdf.format(k000000, out.remove()));
   4970     assertEquals("hh:mm:ss bbb | 00:00:30", "12:00:30 AM", sdf.format(k000030, out.remove()));
   4971     assertEquals("hh:mm:ss bbb | 00:30:00", "12:30:00 AM", sdf.format(k003000, out.remove()));
   4972     assertEquals("hh:mm:ss bbb | 06:00:00", "06:00:00 AM", sdf.format(k060000, out.remove()));
   4973     assertEquals("hh:mm:ss bbb | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove()));
   4974     assertEquals("hh:mm:ss bbb | 18:00:00", "06:00:00 PM", sdf.format(k180000, out.remove()));
   4975 
   4976     sdf.applyPattern(UnicodeString("hh:mm bbb"));
   4977 
   4978     // assertEquals("hh:mm bbb | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove()));
   4979     assertEquals("hh:mm bbb | 00:00:00", "12:00 AM", sdf.format(k000000, out.remove()));
   4980     // assertEquals("hh:mm bbb | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove()));
   4981     assertEquals("hh:mm bbb | 00:00:30", "12:00 AM", sdf.format(k000030, out.remove()));
   4982     assertEquals("hh:mm bbb | 00:30:00", "12:30 AM", sdf.format(k003000, out.remove()));
   4983 
   4984     sdf.applyPattern(UnicodeString("hh bbb"));
   4985 
   4986     // assertEquals("hh bbb | 00:00:00", "12 midnight", sdf.format(k000000, out.remove()));
   4987     assertEquals("hh bbb | 00:00:00", "12 AM", sdf.format(k000000, out.remove()));
   4988     // assertEquals("hh bbb | 00:00:30", "12 midnight", sdf.format(k000030, out.remove()));
   4989     assertEquals("hh bbb | 00:00:30", "12 AM", sdf.format(k000030, out.remove()));
   4990     // assertEquals("hh bbb | 00:30:00", "12 midnight", sdf.format(k003000, out.remove()));
   4991     assertEquals("hh bbb | 00:30:00", "12 AM", sdf.format(k003000, out.remove()));
   4992 
   4993     // Wide.
   4994     sdf.applyPattern(UnicodeString("hh:mm:ss bbbb"));
   4995 
   4996     // assertEquals("hh:mm:ss bbbb | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove()));
   4997     assertEquals("hh:mm:ss bbbb | 00:00:00", "12:00:00 AM", sdf.format(k000000, out.remove()));
   4998     assertEquals("hh:mm:ss bbbb | 00:00:30", "12:00:30 AM", sdf.format(k000030, out.remove()));
   4999     assertEquals("hh:mm:ss bbbb | 00:30:00", "12:30:00 AM", sdf.format(k003000, out.remove()));
   5000     assertEquals("hh:mm:ss bbbb | 06:00:00", "06:00:00 AM", sdf.format(k060000, out.remove()));
   5001     assertEquals("hh:mm:ss bbbb | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove()));
   5002     assertEquals("hh:mm:ss bbbb | 18:00:00", "06:00:00 PM", sdf.format(k180000, out.remove()));
   5003 
   5004     sdf.applyPattern(UnicodeString("hh:mm bbbb"));
   5005 
   5006     // assertEquals("hh:mm bbbb | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove()));
   5007     assertEquals("hh:mm bbbb | 00:00:00", "12:00 AM", sdf.format(k000000, out.remove()));
   5008     // assertEquals("hh:mm bbbb | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove()));
   5009     assertEquals("hh:mm bbbb | 00:00:30", "12:00 AM", sdf.format(k000030, out.remove()));
   5010     assertEquals("hh:mm bbbb | 00:30:00", "12:30 AM", sdf.format(k003000, out.remove()));
   5011 
   5012     sdf.applyPattern(UnicodeString("hh bbbb"));
   5013 
   5014     // assertEquals("hh bbbb | 00:00:00", "12 midnight", sdf.format(k000000, out.remove()));
   5015     assertEquals("hh bbbb | 00:00:00", "12 AM", sdf.format(k000000, out.remove()));
   5016     // assertEquals("hh bbbb | 00:00:30", "12 midnight", sdf.format(k000030, out.remove()));
   5017     assertEquals("hh bbbb | 00:00:30", "12 AM", sdf.format(k000030, out.remove()));
   5018     // assertEquals("hh bbbb | 00:30:00", "12 midnight", sdf.format(k003000, out.remove()));
   5019     assertEquals("hh bbbb | 00:30:00", "12 AM", sdf.format(k003000, out.remove()));
   5020 
   5021     // Narrow.
   5022     sdf.applyPattern(UnicodeString("hh:mm:ss bbbbb"));
   5023 
   5024     // assertEquals("hh:mm:ss bbbbb | 00:00:00", "12:00:00 mi", sdf.format(k000000, out.remove()));
   5025     assertEquals("hh:mm:ss bbbbb | 00:00:00", "12:00:00 a", sdf.format(k000000, out.remove()));
   5026     assertEquals("hh:mm:ss bbbbb | 00:00:30", "12:00:30 a", sdf.format(k000030, out.remove()));
   5027     assertEquals("hh:mm:ss bbbbb | 00:30:00", "12:30:00 a", sdf.format(k003000, out.remove()));
   5028     assertEquals("hh:mm:ss bbbbb | 06:00:00", "06:00:00 a", sdf.format(k060000, out.remove()));
   5029     assertEquals("hh:mm:ss bbbbb | 12:00:00", "12:00:00 n", sdf.format(k120000, out.remove()));
   5030     assertEquals("hh:mm:ss bbbbb | 18:00:00", "06:00:00 p", sdf.format(k180000, out.remove()));
   5031 
   5032     sdf.applyPattern(UnicodeString("hh:mm bbbbb"));
   5033 
   5034     // assertEquals("hh:mm bbbbb | 00:00:00", "12:00 mi", sdf.format(k000000, out.remove()));
   5035     assertEquals("hh:mm bbbbb | 00:00:00", "12:00 a", sdf.format(k000000, out.remove()));
   5036     // assertEquals("hh:mm bbbbb | 00:00:30", "12:00 mi", sdf.format(k000030, out.remove()));
   5037     assertEquals("hh:mm bbbbb | 00:00:30", "12:00 a", sdf.format(k000030, out.remove()));
   5038     assertEquals("hh:mm bbbbb | 00:30:00", "12:30 a", sdf.format(k003000, out.remove()));
   5039 
   5040     sdf.applyPattern(UnicodeString("hh bbbbb"));
   5041 
   5042     // assertEquals("hh bbbbb | 00:00:00", "12 mi", sdf.format(k000000, out.remove()));
   5043     assertEquals("hh bbbbb | 00:00:00", "12 a", sdf.format(k000000, out.remove()));
   5044     // assertEquals("hh bbbbb | 00:00:30", "12 mi", sdf.format(k000030, out.remove()));
   5045     assertEquals("hh bbbbb | 00:00:30", "12 a", sdf.format(k000030, out.remove()));
   5046     // assertEquals("hh bbbbb | 00:30:00", "12 mi", sdf.format(k003000, out.remove()));
   5047     assertEquals("hh bbbbb | 00:30:00", "12 a", sdf.format(k003000, out.remove()));
   5048 }
   5049 
   5050 void DateFormatTest::TestFlexibleDayPeriod() {
   5051     // Some times on 2015-11-13 (UTC+0).
   5052     UDate k000000 = 1447372800000.0;
   5053     UDate k000030 = 1447372830000.0;
   5054     UDate k003000 = 1447374600000.0;
   5055     UDate k060000 = 1447394400000.0;
   5056     UDate k120000 = 1447416000000.0;
   5057     UDate k180000 = 1447437600000.0;
   5058 
   5059     UErrorCode errorCode = U_ZERO_ERROR;
   5060     SimpleDateFormat sdf(UnicodeString(), errorCode);
   5061     if (U_FAILURE(errorCode)) {
   5062         dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
   5063         return;
   5064     }
   5065     const TimeZone *tz = TimeZone::getGMT();
   5066     sdf.setTimeZone(*tz);
   5067     UnicodeString out;
   5068 
   5069     // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
   5070     // For ICU 57 output of "midnight" is temporarily suppressed.
   5071 
   5072     // Short.
   5073     sdf.applyPattern(UnicodeString("hh:mm:ss BBB"));
   5074 
   5075     // assertEquals("hh:mm:ss BBB | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove()));
   5076     assertEquals("hh:mm:ss BBB | 00:00:00", "12:00:00 at night", sdf.format(k000000, out.remove()));
   5077     assertEquals("hh:mm:ss BBB | 00:00:30", "12:00:30 at night", sdf.format(k000030, out.remove()));
   5078     assertEquals("hh:mm:ss BBB | 00:30:00", "12:30:00 at night", sdf.format(k003000, out.remove()));
   5079     assertEquals("hh:mm:ss BBB | 06:00:00", "06:00:00 in the morning", sdf.format(k060000, out.remove()));
   5080     assertEquals("hh:mm:ss BBB | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove()));
   5081     assertEquals("hh:mm:ss BBB | 18:00:00", "06:00:00 in the evening", sdf.format(k180000, out.remove()));
   5082 
   5083     sdf.applyPattern(UnicodeString("hh:mm BBB"));
   5084 
   5085     // assertEquals("hh:mm BBB | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove()));
   5086     assertEquals("hh:mm BBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove()));
   5087     // assertEquals("hh:mm BBB | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove()));
   5088     assertEquals("hh:mm BBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove()));
   5089     assertEquals("hh:mm BBB | 00:30:00", "12:30 at night", sdf.format(k003000, out.remove()));
   5090 
   5091     sdf.applyPattern(UnicodeString("hh BBB"));
   5092 
   5093     // assertEquals("hh BBB | 00:00:00", "12 midnight", sdf.format(k000000, out.remove()));
   5094     assertEquals("hh BBB | 00:00:30", "12 at night", sdf.format(k000030, out.remove()));
   5095     // assertEquals("hh BBB | 00:00:30", "12 midnight", sdf.format(k000030, out.remove()));
   5096     assertEquals("hh BBB | 00:00:30", "12 at night", sdf.format(k000030, out.remove()));
   5097     // assertEquals("hh BBB | 00:30:00", "12 midnight", sdf.format(k003000, out.remove()));
   5098     assertEquals("hh BBB | 00:30:00", "12 at night", sdf.format(k003000, out.remove()));
   5099 
   5100     // Wide.
   5101     sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
   5102 
   5103     // assertEquals("hh:mm:ss BBBB | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove()));
   5104     assertEquals("hh:mm:ss BBBB | 00:00:00", "12:00:00 at night", sdf.format(k000000, out.remove()));
   5105     assertEquals("hh:mm:ss BBBB | 00:00:30", "12:00:30 at night", sdf.format(k000030, out.remove()));
   5106     assertEquals("hh:mm:ss BBBB | 00:30:00", "12:30:00 at night", sdf.format(k003000, out.remove()));
   5107     assertEquals("hh:mm:ss BBBB | 06:00:00", "06:00:00 in the morning", sdf.format(k060000, out.remove()));
   5108     assertEquals("hh:mm:ss BBBB | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove()));
   5109     assertEquals("hh:mm:ss BBBB | 18:00:00", "06:00:00 in the evening", sdf.format(k180000, out.remove()));
   5110 
   5111     sdf.applyPattern(UnicodeString("hh:mm BBBB"));
   5112 
   5113     // assertEquals("hh:mm BBBB | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove()));
   5114     assertEquals("hh:mm BBBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove()));
   5115     // assertEquals("hh:mm BBBB | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove()));
   5116     assertEquals("hh:mm BBBB | 00:00:30", "12:00 at night", sdf.format(k000030, out.remove()));
   5117     assertEquals("hh:mm BBBB | 00:30:00", "12:30 at night", sdf.format(k003000, out.remove()));
   5118 
   5119     sdf.applyPattern(UnicodeString("hh BBBB"));
   5120 
   5121     // assertEquals("hh BBBB | 00:00:00", "12 midnight", sdf.format(k000000, out.remove()));
   5122     assertEquals("hh BBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove()));
   5123     // assertEquals("hh BBBB | 00:00:30", "12 midnight", sdf.format(k000030, out.remove()));
   5124     assertEquals("hh BBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove()));
   5125     // assertEquals("hh BBBB | 00:80:00", "12 midnight", sdf.format(k003000, out.remove()));
   5126     assertEquals("hh BBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove()));
   5127 
   5128     // Narrow.
   5129     sdf.applyPattern(UnicodeString("hh:mm:ss BBBBB"));
   5130 
   5131     // assertEquals("hh:mm:ss BBBBB | 00:00:00", "12:00:00 mi", sdf.format(k000000, out.remove()));
   5132     assertEquals("hh:mm:ss BBBBB | 00:00:00", "12:00:00 at night", sdf.format(k000000, out.remove()));
   5133     assertEquals("hh:mm:ss BBBBB | 00:00:30", "12:00:30 at night", sdf.format(k000030, out.remove()));
   5134     assertEquals("hh:mm:ss BBBBB | 00:30:00", "12:30:00 at night", sdf.format(k003000, out.remove()));
   5135     assertEquals("hh:mm:ss BBBBB | 06:00:00", "06:00:00 in the morning", sdf.format(k060000, out.remove()));
   5136     assertEquals("hh:mm:ss BBBBB | 12:00:00", "12:00:00 n", sdf.format(k120000, out.remove()));
   5137     assertEquals("hh:mm:ss BBBBB | 18:00:00", "06:00:00 in the evening", sdf.format(k180000, out.remove()));
   5138 
   5139     sdf.applyPattern(UnicodeString("hh:mm BBBBB"));
   5140 
   5141     // assertEquals("hh:mm BBBBB | 00:00:00", "12:00 mi", sdf.format(k000000, out.remove()));
   5142     assertEquals("hh:mm BBBBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove()));
   5143     // assertEquals("hh:mm BBBBB | 00:00:30", "12:00 mi", sdf.format(k000030, out.remove()));
   5144     assertEquals("hh:mm BBBBB | 00:00:30", "12:00 at night", sdf.format(k000030, out.remove()));
   5145     assertEquals("hh:mm BBBBB | 00:30:00", "12:30 at night", sdf.format(k003000, out.remove()));
   5146 
   5147     sdf.applyPattern(UnicodeString("hh BBBBB"));
   5148 
   5149     // assertEquals("hh BBBBB | 00:00:00", "12 mi", sdf.format(k000000, out.remove()));
   5150     assertEquals("hh BBBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove()));
   5151     // assertEquals("hh BBBBB | 00:00:30", "12 mi", sdf.format(k000030, out.remove()));
   5152     assertEquals("hh BBBBB | 00:00:30", "12 at night", sdf.format(k000030, out.remove()));
   5153     // assertEquals("hh BBBBB | 00:30:00", "12 mi", sdf.format(k003000, out.remove()));
   5154     assertEquals("hh BBBBB | 00:30:00", "12 at night", sdf.format(k003000, out.remove()));
   5155 }
   5156 
   5157 void DateFormatTest::TestDayPeriodWithLocales() {
   5158     // Some times on 2015-11-13 (UTC+0).
   5159     UDate k000000 = 1447372800000.0;
   5160     UDate k010000 = 1447376400000.0;
   5161     UDate k120000 = 1447416000000.0;
   5162     UDate k220000 = 1447452000000.0;
   5163 
   5164     UErrorCode errorCode = U_ZERO_ERROR;
   5165     const TimeZone *tz = TimeZone::getGMT();
   5166     UnicodeString out;
   5167 
   5168     // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
   5169     // For ICU 57 output of "midnight" and its localized equivalentns is temporarily suppressed.
   5170 
   5171     // Locale de has a word for midnight, but not noon.
   5172     SimpleDateFormat sdf(UnicodeString(), Locale::getGermany(), errorCode);
   5173     if (U_FAILURE(errorCode)) {
   5174         dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
   5175         return;
   5176     }
   5177     sdf.setTimeZone(*tz);
   5178 
   5179     sdf.applyPattern(UnicodeString("hh:mm:ss bbbb"));
   5180 
   5181     // assertEquals("hh:mm:ss bbbb | 00:00:00 | de", "12:00:00 Mitternacht",
   5182     //     sdf.format(k000000, out.remove()));
   5183     assertEquals("hh:mm:ss bbbb | 00:00:00 | de", "12:00:00 vorm.",
   5184         sdf.format(k000000, out.remove()));
   5185     assertEquals("hh:mm:ss bbbb | 12:00:00 | de", "12:00:00 nachm.",
   5186         sdf.format(k120000, out.remove()));
   5187 
   5188     // Locale ee has a rule that wraps around midnight (21h - 4h).
   5189     sdf = SimpleDateFormat(UnicodeString(), Locale("ee"), errorCode);
   5190     sdf.setTimeZone(*tz);
   5191 
   5192     sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
   5193 
   5194     assertEquals("hh:mm:ss BBBB | 22:00:00 | ee", UnicodeString("10:00:00 z\\u00E3").unescape(),
   5195         sdf.format(k220000, out.remove()));
   5196     assertEquals("hh:mm:ss BBBB | 00:00:00 | ee", UnicodeString("12:00:00 z\\u00E3").unescape(),
   5197         sdf.format(k000000, out.remove()));
   5198     assertEquals("hh:mm:ss BBBB | 01:00:00 | ee", UnicodeString("01:00:00 z\\u00E3").unescape(),
   5199         sdf.format(k010000, out.remove()));
   5200 
   5201     // Locale root has rules for AM/PM only.
   5202     sdf = SimpleDateFormat(UnicodeString(), Locale("root"), errorCode);
   5203     sdf.setTimeZone(*tz);
   5204 
   5205     sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
   5206 
   5207     assertEquals("hh:mm:ss BBBB | 00:00:00 | root", "12:00:00 AM",
   5208         sdf.format(k000000, out.remove()));
   5209     assertEquals("hh:mm:ss BBBB | 12:00:00 | root", "12:00:00 PM",
   5210         sdf.format(k120000, out.remove()));
   5211 
   5212     // Empty string should behave exactly as root.
   5213     sdf = SimpleDateFormat(UnicodeString(), Locale(""), errorCode);
   5214     sdf.setTimeZone(*tz);
   5215 
   5216     sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
   5217 
   5218     assertEquals("hh:mm:ss BBBB | 00:00:00 | \"\" (root)", "12:00:00 AM",
   5219         sdf.format(k000000, out.remove()));
   5220     assertEquals("hh:mm:ss BBBB | 12:00:00 | \"\" (root)", "12:00:00 PM",
   5221         sdf.format(k120000, out.remove()));
   5222 
   5223     // Locale en_US should fall back to en.
   5224     sdf = SimpleDateFormat(UnicodeString(), Locale("en_US"), errorCode);
   5225     sdf.setTimeZone(*tz);
   5226 
   5227     sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
   5228 
   5229     // assertEquals("hh:mm:ss BBBB | 00:00:00 | en_US", "12:00:00 midnight",
   5230     //     sdf.format(k000000, out.remove()));
   5231     assertEquals("hh:mm:ss BBBB | 00:00:00 | en_US", "12:00:00 at night",
   5232          sdf.format(k000000, out.remove()));
   5233     assertEquals("hh:mm:ss BBBB | 01:00:00 | en_US", "01:00:00 at night",
   5234         sdf.format(k010000, out.remove()));
   5235     assertEquals("hh:mm:ss BBBB | 12:00:00 | en_US", "12:00:00 noon",
   5236         sdf.format(k120000, out.remove()));
   5237 
   5238     // Locale es_CO should not fall back to es and should have a
   5239     // different string for 1 in the morning.
   5240     // (es_CO: "de la manana" (first n has a tilde) vs. es: "de la madrugada")
   5241     sdf = SimpleDateFormat(UnicodeString(), Locale("es_CO"), errorCode);
   5242     sdf.setTimeZone(*tz);
   5243 
   5244     sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
   5245     assertEquals("hh:mm:ss BBBB | 01:00:00 | es_CO", UnicodeString("01:00:00 de la ma\\u00F1ana").unescape(),
   5246         sdf.format(k010000, out.remove()));
   5247 
   5248     sdf = SimpleDateFormat(UnicodeString(), Locale("es"), errorCode);
   5249     sdf.setTimeZone(*tz);
   5250 
   5251     sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
   5252     assertEquals("hh:mm:ss BBBB | 01:00:00 | es", "01:00:00 de la madrugada",
   5253         sdf.format(k010000, out.remove()));
   5254 
   5255     // #13215: for locales with keywords, check hang in DayPeriodRules""getInstance(const Locale, ...),
   5256     // which is called in SimpleDateFormat::format for patterns that include 'B'.
   5257     sdf = SimpleDateFormat(UnicodeString(), Locale("en@calendar=buddhist"), errorCode);
   5258     sdf.setTimeZone(*tz);
   5259 
   5260     sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
   5261     assertEquals("hh:mm:ss BBBB | 01:00:00 | en@calendar=buddhist", "01:00:00 at night",
   5262         sdf.format(k010000, out.remove()));
   5263 }
   5264 
   5265 void DateFormatTest::TestMinuteSecondFieldsInOddPlaces() {
   5266     // Some times on 2015-11-13 (UTC+0).
   5267     UDate k000000 = 1447372800000.0;
   5268     UDate k000030 = 1447372830000.0;
   5269     UDate k003000 = 1447374600000.0;
   5270     UDate k060030 = 1447394430000.0;
   5271     UDate k063000 = 1447396200000.0;
   5272 
   5273     UErrorCode errorCode = U_ZERO_ERROR;
   5274     const TimeZone *tz = TimeZone::getGMT();
   5275     UnicodeString out;
   5276 
   5277     // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
   5278     // For ICU 57 output of "midnight" is temporarily suppressed.
   5279 
   5280     // Seconds field is not present.
   5281 
   5282     // Apply pattern through constructor to make sure parsePattern() is called during initialization.
   5283     SimpleDateFormat sdf(UnicodeString("hh:mm 'ss' bbbb"), errorCode);
   5284     if (U_FAILURE(errorCode)) {
   5285         dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
   5286         return;
   5287     }
   5288     sdf.setTimeZone(*tz);
   5289 
   5290     // assertEquals("hh:mm 'ss' bbbb | 00:00:30", "12:00 ss midnight",
   5291     //     sdf.format(k000030, out.remove()));
   5292     assertEquals("hh:mm 'ss' bbbb | 00:00:30", "12:00 ss AM",
   5293         sdf.format(k000030, out.remove()));
   5294     assertEquals("hh:mm 'ss' bbbb | 06:00:30", "06:00 ss AM",
   5295         sdf.format(k060030, out.remove()));
   5296 
   5297     sdf.applyPattern(UnicodeString("hh:mm 'ss' BBBB"));
   5298 
   5299     // assertEquals("hh:mm 'ss' BBBB | 00:00:30", "12:00 ss midnight",
   5300     //     sdf.format(k000030, out.remove()));
   5301     assertEquals("hh:mm 'ss' BBBB | 00:00:30", "12:00 ss at night",
   5302         sdf.format(k000030, out.remove()));
   5303     assertEquals("hh:mm 'ss' BBBB | 06:00:30", "06:00 ss in the morning",
   5304         sdf.format(k060030, out.remove()));
   5305 
   5306     // Minutes field is not present.
   5307     sdf.applyPattern(UnicodeString("hh 'mm ss' bbbb"));
   5308 
   5309     // assertEquals("hh 'mm ss' bbbb | 00:30:00", "12 mm ss midnight",
   5310     //     sdf.format(k003000, out.remove()));
   5311     assertEquals("hh 'mm ss' bbbb | 00:30:00", "12 mm ss AM",
   5312         sdf.format(k003000, out.remove()));
   5313     assertEquals("hh 'mm ss' bbbb | 06:30:00", "06 mm ss AM",
   5314         sdf.format(k063000, out.remove()));
   5315 
   5316     sdf.applyPattern(UnicodeString("hh 'mm ss' BBBB"));
   5317 
   5318     // assertEquals("hh 'mm ss' BBBB | 00:30:00", "12 mm ss midnight",
   5319     //     sdf.format(k003000, out.remove()));
   5320     assertEquals("hh 'mm ss' BBBB | 00:30:00", "12 mm ss at night",
   5321         sdf.format(k003000, out.remove()));
   5322     assertEquals("hh 'mm ss' BBBB | 06:30:00", "06 mm ss in the morning",
   5323         sdf.format(k063000, out.remove()));
   5324 
   5325     // Minutes and seconds fields appear after day periods.
   5326     sdf.applyPattern(UnicodeString("bbbb hh:mm:ss"));
   5327 
   5328     // assertEquals("bbbb hh:mm:ss | 00:00:00", "midnight 12:00:00",
   5329     //     sdf.format(k000000, out.remove()));
   5330     assertEquals("bbbb hh:mm:ss | 00:00:00", "AM 12:00:00",
   5331         sdf.format(k000000, out.remove()));
   5332     assertEquals("bbbb hh:mm:ss | 00:00:30", "AM 12:00:30",
   5333         sdf.format(k000030, out.remove()));
   5334     assertEquals("bbbb hh:mm:ss | 00:30:00", "AM 12:30:00",
   5335         sdf.format(k003000, out.remove()));
   5336 
   5337     sdf.applyPattern(UnicodeString("BBBB hh:mm:ss"));
   5338 
   5339     // assertEquals("BBBB hh:mm:ss | 00:00:00", "midnight 12:00:00",
   5340     //     sdf.format(k000000, out.remove()));
   5341     assertEquals("BBBB hh:mm:ss | 00:00:00", "at night 12:00:00",
   5342         sdf.format(k000000, out.remove()));
   5343     assertEquals("BBBB hh:mm:ss | 00:00:30", "at night 12:00:30",
   5344         sdf.format(k000030, out.remove()));
   5345     assertEquals("BBBB hh:mm:ss | 00:30:00", "at night 12:30:00",
   5346         sdf.format(k003000, out.remove()));
   5347 
   5348     // Confirm applyPattern() reparses the pattern string.
   5349     sdf.applyPattern(UnicodeString("BBBB hh"));
   5350     // assertEquals("BBBB hh | 00:00:30", "midnight 12",
   5351     //     sdf.format(k000030, out.remove()));
   5352     assertEquals("BBBB hh | 00:00:30", "at night 12",
   5353          sdf.format(k000030, out.remove()));
   5354 
   5355     sdf.applyPattern(UnicodeString("BBBB hh:mm:'ss'"));
   5356     // assertEquals("BBBB hh:mm:'ss' | 00:00:30", "midnight 12:00:ss",
   5357     //     sdf.format(k000030, out.remove()));
   5358     assertEquals("BBBB hh | 00:00:30", "at night 12:00:ss",
   5359         sdf.format(k000030, out.remove()));
   5360 
   5361     sdf.applyPattern(UnicodeString("BBBB hh:mm:ss"));
   5362     assertEquals("BBBB hh:mm:ss | 00:00:30", "at night 12:00:30",
   5363         sdf.format(k000030, out.remove()));
   5364 }
   5365 
   5366 void DateFormatTest::TestDayPeriodParsing() {
   5367     // Some times on 2015-11-13 (UTC+0).
   5368     UDate k000000 = 1447372800000.0;
   5369     UDate k003700 = 1447375020000.0;
   5370     UDate k010000 = 1447376400000.0;
   5371     UDate k013000 = 1447378200000.0;
   5372     UDate k030000 = 1447383600000.0;
   5373     UDate k090000 = 1447405200000.0;
   5374     UDate k120000 = 1447416000000.0;
   5375     UDate k130000 = 1447419600000.0;
   5376     UDate k133700 = 1447421820000.0;
   5377     UDate k150000 = 1447426800000.0;
   5378     UDate k190000 = 1447441200000.0;
   5379     UDate k193000 = 1447443000000.0;
   5380     UDate k200000 = 1447444800000.0;
   5381     UDate k210000 = 1447448400000.0;
   5382 
   5383     UErrorCode errorCode = U_ZERO_ERROR;
   5384     SimpleDateFormat sdf(UnicodeString(), errorCode);
   5385     if (U_FAILURE(errorCode)) {
   5386         dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
   5387         return;
   5388     }
   5389     const TimeZone *tz = TimeZone::getGMT();
   5390     sdf.setTimeZone(*tz);
   5391     UnicodeString out;
   5392 
   5393     // 'B' -- flexible day periods
   5394     // A day period on its own parses to the center of that period.
   5395     sdf.applyPattern(UnicodeString("yyyy-MM-dd B"));
   5396     assertEquals("yyyy-MM-dd B | 2015-11-13 midnight",
   5397         k000000, sdf.parse(UnicodeString("2015-11-13 midnight"), errorCode));
   5398     assertEquals("yyyy-MM-dd B | 2015-11-13 noon",
   5399         k120000, sdf.parse(UnicodeString("2015-11-13 noon"), errorCode));
   5400     assertEquals("yyyy-MM-dd B | 2015-11-13 in the afternoon",
   5401         k150000, sdf.parse(UnicodeString("2015-11-13 in the afternoon"), errorCode));
   5402     assertEquals("yyyy-MM-dd B | 2015-11-13 in the evening",
   5403         k193000, sdf.parse(UnicodeString("2015-11-13 in the evening"), errorCode));
   5404     assertEquals("yyyy-MM-dd B | 2015-11-13 at night",
   5405         k013000, sdf.parse(UnicodeString("2015-11-13 at night"), errorCode));
   5406 
   5407     // If time and day period are consistent with each other then time is parsed accordingly.
   5408     sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm B"));
   5409     assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 12:00 midnight",
   5410         k000000, sdf.parse(UnicodeString("2015-11-13 12:00 midnight"), errorCode));
   5411     assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 12:00 noon",
   5412         k120000, sdf.parse(UnicodeString("2015-11-13 12:00 noon"), errorCode));
   5413     assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 01:00 at night",
   5414         k010000, sdf.parse(UnicodeString("2015-11-13 01:00 at night"), errorCode));
   5415     assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 01:00 in the afternoon",
   5416         k130000, sdf.parse(UnicodeString("2015-11-13 01:00 in the afternoon"), errorCode));
   5417     assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 09:00 in the morning",
   5418         k090000, sdf.parse(UnicodeString("2015-11-13 09:00 in the morning"), errorCode));
   5419     assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 09:00 at night",
   5420         k210000, sdf.parse(UnicodeString("2015-11-13 09:00 at night"), errorCode));
   5421 
   5422     // If the hour is 13 thru 23 then day period has no effect on time (since time is assumed
   5423     // to be in 24-hour format).
   5424     sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm B"));
   5425     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 midnight",
   5426         k133700, sdf.parse(UnicodeString("2015-11-13 13:37 midnight"), errorCode));
   5427     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 noon",
   5428         k133700, sdf.parse(UnicodeString("2015-11-13 13:37 noon"), errorCode));
   5429     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 at night",
   5430         k133700, sdf.parse(UnicodeString("2015-11-13 13:37 at night"), errorCode));
   5431     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 in the afternoon",
   5432         k133700, sdf.parse(UnicodeString("2015-11-13 13:37 in the afternoon"), errorCode));
   5433     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 in the morning",
   5434         k133700, sdf.parse(UnicodeString("2015-11-13 13:37 in the morning"), errorCode));
   5435     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 at night",
   5436         k133700, sdf.parse(UnicodeString("2015-11-13 13:37 at night"), errorCode));
   5437 
   5438     // Hour 0 is synonymous with hour 12 when parsed with 'h'.
   5439     // This unfortunately means we have to tolerate "0 noon" as it's synonymous with "12 noon".
   5440     sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm B"));
   5441     assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 00:00 midnight",
   5442         k000000, sdf.parse(UnicodeString("2015-11-13 00:00 midnight"), errorCode));
   5443     assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 00:00 noon",
   5444         k120000, sdf.parse(UnicodeString("2015-11-13 00:00 noon"), errorCode));
   5445 
   5446     // But when parsed with 'H', 0 indicates a 24-hour time, therefore we disregard the day period.
   5447     sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm B"));
   5448     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 midnight",
   5449         k003700, sdf.parse(UnicodeString("2015-11-13 00:37 midnight"), errorCode));
   5450     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 noon",
   5451         k003700, sdf.parse(UnicodeString("2015-11-13 00:37 noon"), errorCode));
   5452     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 at night",
   5453         k003700, sdf.parse(UnicodeString("2015-11-13 00:37 at night"), errorCode));
   5454     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 in the afternoon",
   5455         k003700, sdf.parse(UnicodeString("2015-11-13 00:37 in the afternoon"), errorCode));
   5456     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 in the morning",
   5457         k003700, sdf.parse(UnicodeString("2015-11-13 00:37 in the morning"), errorCode));
   5458     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 at night",
   5459         k003700, sdf.parse(UnicodeString("2015-11-13 00:37 at night"), errorCode));
   5460 
   5461     // Even when parsed with 'H', hours 1 thru 12 are considered 12-hour time and takes
   5462     // day period into account in parsing.
   5463     sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm B"));
   5464     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 12:00 midnight",
   5465         k000000, sdf.parse(UnicodeString("2015-11-13 12:00 midnight"), errorCode));
   5466     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 12:00 noon",
   5467         k120000, sdf.parse(UnicodeString("2015-11-13 12:00 noon"), errorCode));
   5468     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 01:00 at night",
   5469         k010000, sdf.parse(UnicodeString("2015-11-13 01:00 at night"), errorCode));
   5470     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 01:00 in the afternoon",
   5471         k130000, sdf.parse(UnicodeString("2015-11-13 01:00 in the afternoon"), errorCode));
   5472     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 09:00 in the morning",
   5473         k090000, sdf.parse(UnicodeString("2015-11-13 09:00 in the morning"), errorCode));
   5474     assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 09:00 at night",
   5475         k210000, sdf.parse(UnicodeString("2015-11-13 09:00 at night"), errorCode));
   5476 
   5477     // If a 12-hour time and the day period don't agree with each other, time is parsed as close
   5478     // to the given day period as possible.
   5479     sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm B"));
   5480 
   5481     // AFTERNOON1 is [12, 18), but "7 in the afternoon" parses to 19:00.
   5482     assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 07:00 in the afternoon",
   5483         k190000, sdf.parse(UnicodeString("2015-11-13 07:00 in the afternoon"), errorCode));
   5484     // NIGHT1 is [21, 6), but "8 at night" parses to 20:00.
   5485     assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 08:00 at night",
   5486         k200000, sdf.parse(UnicodeString("2015-11-13 08:00 at night"), errorCode));
   5487 
   5488     // 'b' -- fixed day periods (AM, PM, midnight, noon)
   5489     // On their own, "midnight" parses to 00:00 and "noon" parses to 12:00.
   5490     // AM and PM are handled by the 'a' parser (which doesn't handle this case well).
   5491     sdf.applyPattern(UnicodeString("yyyy-MM-dd b"));
   5492     assertEquals("yyyy-MM-dd b | 2015-11-13 midnight",
   5493         k000000, sdf.parse(UnicodeString("2015-11-13 midnight"), errorCode));
   5494     assertEquals("yyyy-MM-dd b | 2015-11-13 noon",
   5495         k120000, sdf.parse(UnicodeString("2015-11-13 noon"), errorCode));
   5496 
   5497     // For 12-hour times, AM and PM should be parsed as if with pattern character 'a'.
   5498     sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm b"));
   5499     assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 01:00 AM",
   5500         k010000, sdf.parse(UnicodeString("2015-11-13 01:00 AM"), errorCode));
   5501     assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 01:00 PM",
   5502         k130000, sdf.parse(UnicodeString("2015-11-13 01:00 PM"), errorCode));
   5503 
   5504     // 12 midnight parses to 00:00, and 12 noon parses to 12:00.
   5505     assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 12:00 midnight",
   5506         k000000, sdf.parse(UnicodeString("2015-11-13 12:00 midnight"), errorCode));
   5507     assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 12:00 noon",
   5508         k120000, sdf.parse(UnicodeString("2015-11-13 12:00 noon"), errorCode));
   5509 
   5510     // Hours 13-23 indicate 24-hour time so we disregard "midnight" or "noon".
   5511     // Again, AM and PM are handled by the 'a' parser which doesn't handle this case well.
   5512     sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm b"));
   5513     assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 13:37 midnight",
   5514         k133700, sdf.parse(UnicodeString("2015-11-13 13:37 midnight"), errorCode));
   5515     assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 13:37 noon",
   5516         k133700, sdf.parse(UnicodeString("2015-11-13 13:37 noon"), errorCode));
   5517 
   5518     // Hour 0 is synonymous with hour 12 when parsed with 'h'.
   5519     // Again, this means we have to tolerate "0 noon" as it's synonymous with "12 noon".
   5520     sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm b"));
   5521     assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 00:00 midnight",
   5522         k000000, sdf.parse(UnicodeString("2015-11-13 00:00 midnight"), errorCode));
   5523     assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 00:00 noon",
   5524         k120000, sdf.parse(UnicodeString("2015-11-13 00:00 noon"), errorCode));
   5525 
   5526     // With 'H' though 0 indicates a 24-hour time, therefore we disregard the day period.
   5527     sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm b"));
   5528     assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 00:37 midnight",
   5529         k003700, sdf.parse(UnicodeString("2015-11-13 00:37 midnight"), errorCode));
   5530     assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 00:37 noon",
   5531         k003700, sdf.parse(UnicodeString("2015-11-13 00:37 noon"), errorCode));
   5532 
   5533     // If "midnight" or "noon" is parsed with a 12-hour time other than 12:00, choose
   5534     // the version that's closer to the period given.
   5535     sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm b"));
   5536     assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 03:00 midnight",
   5537         k030000, sdf.parse(UnicodeString("2015-11-13 03:00 midnight"), errorCode));
   5538     assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 03:00 noon",
   5539         k150000, sdf.parse(UnicodeString("2015-11-13 03:00 noon"), errorCode));
   5540 }
   5541 
   5542 #endif /* #if !UCONFIG_NO_FORMATTING */
   5543 
   5544 //eof
   5545