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