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