1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2013, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 ********************************************************************/
6
7#include "unicode/utypes.h"
8
9#if !UCONFIG_NO_FORMATTING
10
11#include "dtfmttst.h"
12#include "unicode/localpointer.h"
13#include "unicode/timezone.h"
14#include "unicode/gregocal.h"
15#include "unicode/smpdtfmt.h"
16#include "unicode/datefmt.h"
17#include "unicode/dtptngen.h"
18#include "unicode/simpletz.h"
19#include "unicode/strenum.h"
20#include "unicode/dtfmtsym.h"
21#include "cmemory.h"
22#include "cstring.h"
23#include "caltest.h"  // for fieldName
24#include <stdio.h> // for sprintf
25
26#if U_PLATFORM_HAS_WIN32_API
27#include "windttst.h"
28#endif
29
30#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
31
32#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
33
34#define ASSERT_OK(status)  if(U_FAILURE(status)) {errcheckln(status, #status " = %s @ %s:%d", u_errorName(status), __FILE__, __LINE__); return; }
35
36// *****************************************************************************
37// class DateFormatTest
38// *****************************************************************************
39
40void DateFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
41{
42    if(exec) {
43        logln("TestSuite DateFormatTest: ");
44    }
45    TESTCASE_AUTO_BEGIN;
46    TESTCASE_AUTO(TestPatterns);
47    TESTCASE_AUTO(TestEquals);
48    TESTCASE_AUTO(TestTwoDigitYearDSTParse);
49    TESTCASE_AUTO(TestFieldPosition);
50    TESTCASE_AUTO(TestPartialParse994);
51    TESTCASE_AUTO(TestRunTogetherPattern985);
52    TESTCASE_AUTO(TestRunTogetherPattern917);
53    TESTCASE_AUTO(TestCzechMonths459);
54    TESTCASE_AUTO(TestLetterDPattern212);
55    TESTCASE_AUTO(TestDayOfYearPattern195);
56    TESTCASE_AUTO(TestQuotePattern161);
57    TESTCASE_AUTO(TestBadInput135);
58    TESTCASE_AUTO(TestBadInput135a);
59    TESTCASE_AUTO(TestTwoDigitYear);
60    TESTCASE_AUTO(TestDateFormatZone061);
61    TESTCASE_AUTO(TestDateFormatZone146);
62    TESTCASE_AUTO(TestLocaleDateFormat);
63    TESTCASE_AUTO(TestWallyWedel);
64    TESTCASE_AUTO(TestDateFormatCalendar);
65    TESTCASE_AUTO(TestSpaceParsing);
66    TESTCASE_AUTO(TestExactCountFormat);
67    TESTCASE_AUTO(TestWhiteSpaceParsing);
68    TESTCASE_AUTO(TestInvalidPattern);
69    TESTCASE_AUTO(TestGeneral);
70    TESTCASE_AUTO(TestGreekMay);
71    TESTCASE_AUTO(TestGenericTime);
72    TESTCASE_AUTO(TestGenericTimeZoneOrder);
73    TESTCASE_AUTO(TestHost);
74    TESTCASE_AUTO(TestEras);
75    TESTCASE_AUTO(TestNarrowNames);
76    TESTCASE_AUTO(TestShortDays);
77    TESTCASE_AUTO(TestStandAloneDays);
78    TESTCASE_AUTO(TestStandAloneMonths);
79    TESTCASE_AUTO(TestQuarters);
80    TESTCASE_AUTO(TestZTimeZoneParsing);
81    TESTCASE_AUTO(TestRelative);
82    TESTCASE_AUTO(TestRelativeClone);
83    TESTCASE_AUTO(TestHostClone);
84    TESTCASE_AUTO(TestTimeZoneDisplayName);
85    TESTCASE_AUTO(TestRoundtripWithCalendar);
86    TESTCASE_AUTO(Test6338);
87    TESTCASE_AUTO(Test6726);
88    TESTCASE_AUTO(TestGMTParsing);
89    TESTCASE_AUTO(Test6880);
90    TESTCASE_AUTO(TestISOEra);
91    TESTCASE_AUTO(TestFormalChineseDate);
92    TESTCASE_AUTO(TestNumberAsStringParsing);
93    TESTCASE_AUTO(TestStandAloneGMTParse);
94    TESTCASE_AUTO(TestParsePosition);
95    TESTCASE_AUTO(TestMonthPatterns);
96    TESTCASE_AUTO(TestContext);
97    TESTCASE_AUTO(TestNonGregoFmtParse);
98    /*
99    TESTCASE_AUTO(TestRelativeError);
100    TESTCASE_AUTO(TestRelativeOther);
101    */
102    TESTCASE_AUTO(TestDotAndAtLeniency);
103    TESTCASE_AUTO_END;
104}
105
106void DateFormatTest::TestPatterns() {
107    static const struct {
108        const char *actualPattern;
109        const char *expectedPattern;
110        const char *localeID;
111        const char *expectedLocalPattern;
112    } EXPECTED[] = {
113        {UDAT_YEAR, "y","en","y"},
114
115        {UDAT_QUARTER, "QQQQ", "en", "QQQQ"},
116        {UDAT_ABBR_QUARTER, "QQQ", "en", "QQQ"},
117        {UDAT_YEAR_QUARTER, "yQQQQ", "en", "QQQQ y"},
118        {UDAT_YEAR_ABBR_QUARTER, "yQQQ", "en", "QQQ y"},
119
120        {UDAT_NUM_MONTH, "M", "en", "L"},
121        {UDAT_ABBR_MONTH, "MMM", "en", "LLL"},
122        {UDAT_MONTH, "MMMM", "en", "LLLL"},
123        {UDAT_YEAR_NUM_MONTH, "yM","en","M/y"},
124        {UDAT_YEAR_ABBR_MONTH, "yMMM","en","MMM y"},
125        {UDAT_YEAR_MONTH, "yMMMM","en","MMMM y"},
126
127        {UDAT_DAY, "d","en","d"},
128        {UDAT_YEAR_NUM_MONTH_DAY, "yMd", "en", "M/d/y"},
129        {UDAT_YEAR_ABBR_MONTH_DAY, "yMMMd", "en", "MMM d, y"},
130        {UDAT_YEAR_MONTH_DAY, "yMMMMd", "en", "MMMM d, y"},
131        {UDAT_YEAR_NUM_MONTH_WEEKDAY_DAY, "yMEd", "en", "EEE, M/d/y"},
132        {UDAT_YEAR_ABBR_MONTH_WEEKDAY_DAY, "yMMMEd", "en", "EEE, MMM d, y"},
133        {UDAT_YEAR_MONTH_WEEKDAY_DAY, "yMMMMEEEEd", "en", "EEEE, MMMM d, y"},
134
135        {UDAT_NUM_MONTH_DAY, "Md","en","M/d"},
136        {UDAT_ABBR_MONTH_DAY, "MMMd","en","MMM d"},
137        {UDAT_MONTH_DAY, "MMMMd","en","MMMM d"},
138        {UDAT_NUM_MONTH_WEEKDAY_DAY, "MEd","en","EEE, M/d"},
139        {UDAT_ABBR_MONTH_WEEKDAY_DAY, "MMMEd","en","EEE, MMM d"},
140        {UDAT_MONTH_WEEKDAY_DAY, "MMMMEEEEd","en","EEEE, MMMM d"},
141
142        {UDAT_HOUR, "j", "en", "h a"}, // (fixed expected result per ticket 6872<-6626)
143        {UDAT_HOUR24, "H", "en", "HH"}, // (fixed expected result per ticket 6872<-6626
144
145        {UDAT_MINUTE, "m", "en", "m"},
146        {UDAT_HOUR_MINUTE, "jm","en","h:mm a"}, // (fixed expected result per ticket 6872<-7180)
147        {UDAT_HOUR24_MINUTE, "Hm", "en", "HH:mm"}, // (fixed expected result per ticket 6872<-6626)
148
149        {UDAT_SECOND, "s", "en", "s"},
150        {UDAT_HOUR_MINUTE_SECOND, "jms","en","h:mm:ss a"}, // (fixed expected result per ticket 6872<-7180)
151        {UDAT_HOUR24_MINUTE_SECOND, "Hms","en","HH:mm:ss"}, // (fixed expected result per ticket 6872<-6626)
152        {UDAT_MINUTE_SECOND, "ms", "en", "mm:ss"}, // (fixed expected result per ticket 6872<-6626)
153
154        {UDAT_LOCATION_TZ, "VVVV", "en", "VVVV"},
155        {UDAT_GENERIC_TZ, "vvvv", "en", "vvvv"},
156        {UDAT_ABBR_GENERIC_TZ, "v", "en", "v"},
157        {UDAT_SPECIFIC_TZ, "zzzz", "en", "zzzz"},
158        {UDAT_ABBR_SPECIFIC_TZ, "z", "en", "z"},
159        {UDAT_ABBR_UTC_TZ, "ZZZZ", "en", "ZZZZ"},
160
161        {UDAT_YEAR_NUM_MONTH_DAY UDAT_ABBR_UTC_TZ, "yMdZZZZ", "en", "M/d/y, ZZZZ"},
162        {UDAT_MONTH_DAY UDAT_LOCATION_TZ, "MMMMdVVVV", "en", "MMMM d, VVVV"}
163    };
164
165    IcuTestErrorCode errorCode(*this, "TestPatterns()");
166    for (int32_t i = 0; i < LENGTHOF(EXPECTED); i++) {
167        // Verify that patterns have the correct values
168        UnicodeString actualPattern(EXPECTED[i].actualPattern, -1, US_INV);
169        UnicodeString expectedPattern(EXPECTED[i].expectedPattern, -1, US_INV);
170        Locale locale(EXPECTED[i].localeID);
171        if (actualPattern != expectedPattern) {
172            errln("FAILURE! Expected pattern: " + expectedPattern +
173                    " but was: " + actualPattern);
174        }
175
176        // Verify that DataFormat instances produced contain the correct
177        // localized patterns
178        // TODO: use DateFormat::getInstanceForSkeleton(), ticket #9029
179        // Java test code:
180        // DateFormat date1 = DateFormat.getPatternInstance(actualPattern,
181        //         locale);
182        // DateFormat date2 = DateFormat.getPatternInstance(Calendar.getInstance(locale),
183        //         actualPattern, locale);
184        LocalPointer<DateTimePatternGenerator> generator(
185                DateTimePatternGenerator::createInstance(locale, errorCode));
186        if(errorCode.logDataIfFailureAndReset("DateTimePatternGenerator::createInstance() failed for locale ID \"%s\"", EXPECTED[i].localeID)) {
187            continue;
188        }
189        UnicodeString pattern = generator->getBestPattern(actualPattern, errorCode);
190        SimpleDateFormat date1(pattern, locale, errorCode);
191        SimpleDateFormat date2(pattern, locale, errorCode);
192        date2.adoptCalendar(Calendar::createInstance(locale, errorCode));
193        if(errorCode.logIfFailureAndReset("DateFormat::getInstanceForSkeleton() failed")) {
194            errln("  for actualPattern \"%s\" & locale ID \"%s\"",
195                  EXPECTED[i].actualPattern, EXPECTED[i].localeID);
196            continue;
197        }
198
199        UnicodeString expectedLocalPattern(EXPECTED[i].expectedLocalPattern, -1, US_INV);
200        UnicodeString actualLocalPattern1;
201        UnicodeString actualLocalPattern2;
202        date1.toLocalizedPattern(actualLocalPattern1, errorCode);
203        date2.toLocalizedPattern(actualLocalPattern2, errorCode);
204        if (actualLocalPattern1 != expectedLocalPattern) {
205            errln("FAILURE! Expected local pattern: " + expectedLocalPattern
206                    + " but was: " + actualLocalPattern1);
207        }
208        if (actualLocalPattern2 != expectedLocalPattern) {
209            errln("FAILURE! Expected local pattern: " + expectedLocalPattern
210                    + " but was: " + actualLocalPattern2);
211        }
212    }
213}
214
215// Test written by Wally Wedel and emailed to me.
216void DateFormatTest::TestWallyWedel()
217{
218    UErrorCode status = U_ZERO_ERROR;
219    /*
220     * Instantiate a TimeZone so we can get the ids.
221     */
222    TimeZone *tz = new SimpleTimeZone(7,"");
223    /*
224     * Computational variables.
225     */
226    int32_t offset, hours, minutes, seconds;
227    /*
228     * Instantiate a SimpleDateFormat set up to produce a full time
229     zone name.
230     */
231    SimpleDateFormat *sdf = new SimpleDateFormat((UnicodeString)"zzzz", status);
232    /*
233     * A String array for the time zone ids.
234     */
235    int32_t ids_length;
236    StringEnumeration* ids = TimeZone::createEnumeration();
237    if (ids == NULL) {
238        dataerrln("Unable to create TimeZone enumeration.");
239        if (sdf != NULL) {
240            delete sdf;
241        }
242        return;
243    }
244    ids_length = ids->count(status);
245    /*
246     * How many ids do we have?
247     */
248    logln("Time Zone IDs size: %d", ids_length);
249    /*
250     * Column headings (sort of)
251     */
252    logln("Ordinal ID offset(h:m) name");
253    /*
254     * Loop through the tzs.
255     */
256    UDate today = Calendar::getNow();
257    Calendar *cal = Calendar::createInstance(status);
258    for (int32_t i = 0; i < ids_length; i++) {
259        // logln(i + " " + ids[i]);
260        const UnicodeString* id = ids->snext(status);
261        TimeZone *ttz = TimeZone::createTimeZone(*id);
262        // offset = ttz.getRawOffset();
263        cal->setTimeZone(*ttz);
264        cal->setTime(today, status);
265        offset = cal->get(UCAL_ZONE_OFFSET, status) + cal->get(UCAL_DST_OFFSET, status);
266        // logln(i + " " + ids[i] + " offset " + offset);
267        const char* sign = "+";
268        if (offset < 0) {
269            sign = "-";
270            offset = -offset;
271        }
272        hours = offset/3600000;
273        minutes = (offset%3600000)/60000;
274        seconds = (offset%60000)/1000;
275        UnicodeString dstOffset = (UnicodeString)"" + sign + (hours < 10 ? "0" : "") +
276            (int32_t)hours + ":" + (minutes < 10 ? "0" : "") + (int32_t)minutes;
277        if (seconds != 0) {
278            dstOffset = dstOffset + ":" + (seconds < 10 ? "0" : "") + seconds;
279        }
280        /*
281         * Instantiate a date so we can display the time zone name.
282         */
283        sdf->setTimeZone(*ttz);
284        /*
285         * Format the output.
286         */
287        UnicodeString fmtOffset;
288        FieldPosition pos(0);
289        sdf->format(today,fmtOffset, pos);
290        // UnicodeString fmtOffset = tzS.toString();
291        UnicodeString *fmtDstOffset = 0;
292        if (fmtOffset.startsWith("GMT") && fmtOffset.length() != 3)
293        {
294            //fmtDstOffset = fmtOffset->substring(3);
295            fmtDstOffset = new UnicodeString();
296            fmtOffset.extract(3, fmtOffset.length(), *fmtDstOffset);
297        }
298        /*
299         * Show our result.
300         */
301        UBool ok = fmtDstOffset == 0 || *fmtDstOffset == dstOffset;
302        if (ok)
303        {
304            logln(UnicodeString() + i + " " + *id + " " + dstOffset +
305                  " " + fmtOffset +
306                  (fmtDstOffset != 0 ? " ok" : " ?"));
307        }
308        else
309        {
310            errln(UnicodeString() + i + " " + *id + " " + dstOffset +
311                  " " + fmtOffset + " *** FAIL ***");
312        }
313        delete ttz;
314        delete fmtDstOffset;
315    }
316    delete cal;
317    //  delete ids;   // TODO:  BAD API
318    delete ids;
319    delete sdf;
320    delete tz;
321}
322
323// -------------------------------------
324
325/**
326 * Test operator==
327 */
328void
329DateFormatTest::TestEquals()
330{
331    DateFormat* fmtA = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL);
332    DateFormat* fmtB = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL);
333    if ( fmtA == NULL || fmtB == NULL){
334        dataerrln("Error calling DateFormat::createDateTimeInstance");
335        delete fmtA;
336        delete fmtB;
337        return;
338    }
339
340    if (!(*fmtA == *fmtB)) errln((UnicodeString)"FAIL");
341    delete fmtA;
342    delete fmtB;
343
344    TimeZone* test = TimeZone::createTimeZone("PDT");
345    delete test;
346}
347
348// -------------------------------------
349
350/**
351 * Test the parsing of 2-digit years.
352 */
353void
354DateFormatTest::TestTwoDigitYearDSTParse(void)
355{
356    UErrorCode status = U_ZERO_ERROR;
357    SimpleDateFormat* fullFmt = new SimpleDateFormat((UnicodeString)"EEE MMM dd HH:mm:ss.SSS zzz yyyy G", status);
358    SimpleDateFormat *fmt = new SimpleDateFormat((UnicodeString)"dd-MMM-yy h:mm:ss 'o''clock' a z", Locale::getEnglish(), status);
359    //DateFormat* fmt = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL, Locale::ENGLISH);
360    UnicodeString* s = new UnicodeString("03-Apr-04 2:20:47 o'clock AM PST", "");
361    TimeZone* defaultTZ = TimeZone::createDefault();
362    TimeZone* PST = TimeZone::createTimeZone("PST");
363    int32_t defaultOffset = defaultTZ->getRawOffset();
364    int32_t PSTOffset = PST->getRawOffset();
365    int32_t hour = 2 + (defaultOffset - PSTOffset) / (60*60*1000);
366    // hour is the expected hour of day, in units of seconds
367    hour = ((hour < 0) ? hour + 24 : hour) * 60*60;
368
369    UnicodeString str;
370
371    if(U_FAILURE(status)) {
372        dataerrln("Could not set up test. exitting - %s", u_errorName(status));
373        return;
374    }
375
376    UDate d = fmt->parse(*s, status);
377    logln(*s + " P> " + ((DateFormat*)fullFmt)->format(d, str));
378    int32_t y, m, day, hr, min, sec;
379    dateToFields(d, y, m, day, hr, min, sec);
380    hour += defaultTZ->inDaylightTime(d, status) ? 1 : 0;
381    hr = hr*60*60;
382    if (hr != hour)
383        errln((UnicodeString)"FAIL: Should parse to hour " + hour + " but got " + hr);
384
385    if (U_FAILURE(status))
386        errln((UnicodeString)"FAIL: " + (int32_t)status);
387
388    delete s;
389    delete fmt;
390    delete fullFmt;
391    delete PST;
392    delete defaultTZ;
393}
394
395// -------------------------------------
396
397UChar toHexString(int32_t i) { return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10))); }
398
399UnicodeString&
400DateFormatTest::escape(UnicodeString& s)
401{
402    UnicodeString buf;
403    for (int32_t i=0; i<s.length(); ++i)
404    {
405        UChar c = s[(int32_t)i];
406        if (c <= (UChar)0x7F) buf += c;
407        else {
408            buf += (UChar)0x5c; buf += (UChar)0x55;
409            buf += toHexString((c & 0xF000) >> 12);
410            buf += toHexString((c & 0x0F00) >> 8);
411            buf += toHexString((c & 0x00F0) >> 4);
412            buf += toHexString(c & 0x000F);
413        }
414    }
415    return (s = buf);
416}
417
418// -------------------------------------
419
420/**
421 * This MUST be kept in sync with DateFormatSymbols.gPatternChars.
422 */
423static const char* PATTERN_CHARS = "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXx";
424
425/**
426 * A list of the names of all the fields in DateFormat.
427 * This MUST be kept in sync with DateFormat.
428 */
429static const char* DATEFORMAT_FIELD_NAMES[] = {
430    "ERA_FIELD",
431    "YEAR_FIELD",
432    "MONTH_FIELD",
433    "DATE_FIELD",
434    "HOUR_OF_DAY1_FIELD",
435    "HOUR_OF_DAY0_FIELD",
436    "MINUTE_FIELD",
437    "SECOND_FIELD",
438    "MILLISECOND_FIELD",
439    "DAY_OF_WEEK_FIELD",
440    "DAY_OF_YEAR_FIELD",
441    "DAY_OF_WEEK_IN_MONTH_FIELD",
442    "WEEK_OF_YEAR_FIELD",
443    "WEEK_OF_MONTH_FIELD",
444    "AM_PM_FIELD",
445    "HOUR1_FIELD",
446    "HOUR0_FIELD",
447    "TIMEZONE_FIELD",
448    "YEAR_WOY_FIELD",
449    "DOW_LOCAL_FIELD",
450    "EXTENDED_YEAR_FIELD",
451    "JULIAN_DAY_FIELD",
452    "MILLISECONDS_IN_DAY_FIELD",
453    "TIMEZONE_RFC_FIELD",
454    "GENERIC_TIMEZONE_FIELD",
455    "STAND_ALONE_DAY_FIELD",
456    "STAND_ALONE_MONTH_FIELD",
457    "QUARTER_FIELD",
458    "STAND_ALONE_QUARTER_FIELD",
459    "TIMEZONE_SPECIAL_FIELD",
460    "YEAR_NAME_FIELD",
461    "TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD",
462    "TIMEZONE_ISO_FIELD",
463    "TIMEZONE_ISO_LOCAL_FIELD",
464};
465
466static const int32_t DATEFORMAT_FIELD_NAMES_LENGTH =
467    sizeof(DATEFORMAT_FIELD_NAMES) / sizeof(DATEFORMAT_FIELD_NAMES[0]);
468
469/**
470 * Verify that returned field position indices are correct.
471 */
472void DateFormatTest::TestFieldPosition() {
473    UErrorCode ec = U_ZERO_ERROR;
474    int32_t i, j, exp;
475    UnicodeString buf;
476
477    // Verify data
478    DateFormatSymbols rootSyms(Locale(""), ec);
479    if (U_FAILURE(ec)) {
480        dataerrln("Unable to create DateFormatSymbols - %s", u_errorName(ec));
481        return;
482    }
483
484    // local pattern chars data is not longer loaded
485    // from icu locale bundle
486    assertEquals("patternChars", PATTERN_CHARS, rootSyms.getLocalPatternChars(buf));
487    assertEquals("patternChars", PATTERN_CHARS, DateFormatSymbols::getPatternUChars());
488    assertTrue("DATEFORMAT_FIELD_NAMES", DATEFORMAT_FIELD_NAMES_LENGTH == UDAT_FIELD_COUNT);
489    assertTrue("Data", UDAT_FIELD_COUNT == uprv_strlen(PATTERN_CHARS));
490
491    // Create test formatters
492    const int32_t COUNT = 4;
493    DateFormat* dateFormats[COUNT];
494    dateFormats[0] = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale::getUS());
495    dateFormats[1] = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale::getFrance());
496    // Make the pattern "G y M d..."
497    buf.remove().append(PATTERN_CHARS);
498    for (j=buf.length()-1; j>=0; --j) buf.insert(j, (UChar)32/*' '*/);
499    dateFormats[2] = new SimpleDateFormat(buf, Locale::getUS(), ec);
500    // Make the pattern "GGGG yyyy MMMM dddd..."
501    for (j=buf.length()-1; j>=0; j-=2) {
502        for (i=0; i<3; ++i) {
503            buf.insert(j, buf.charAt(j));
504        }
505    }
506    dateFormats[3] = new SimpleDateFormat(buf, Locale::getUS(), ec);
507    if(U_FAILURE(ec)){
508        errln(UnicodeString("Could not create SimpleDateFormat object for locale en_US. Error: " )+ UnicodeString(u_errorName(ec)));
509        return;
510    }
511    UDate aug13 = 871508052513.0;
512
513    // Expected output field values for above DateFormats on aug13
514    // Fields are given in order of DateFormat field number
515    const char* EXPECTED[] = {
516        "", "1997", "August", "13", "", "", "34", "12", "", "Wednesday",
517        "", "", "", "", "PM", "2", "", "Pacific Daylight Time", "", "",
518        "", "", "", "", "", "", "", "", "", "",
519        "", "", "", "",
520
521        "", "1997", "ao\\u00FBt", "13", "", "14", "34", "12", "", "mercredi",
522        "", "", "", "", "", "", "", "heure avanc\\u00e9e du Pacifique", "", "",
523        "", "", "", "", "",  "", "", "", "", "",
524        "", "", "", "",
525
526        "AD", "1997", "8", "13", "14", "14", "34", "12", "5", "Wed",
527        "225", "2", "33", "3", "PM", "2", "2", "PDT", "1997", "4",
528        "1997", "2450674", "52452513", "-0700", "PT",  "4", "8", "3", "3", "uslax",
529        "1997", "GMT-7", "-07", "-07",
530
531        "Anno Domini", "1997", "August", "0013", "0014", "0014", "0034", "0012", "5130", "Wednesday",
532        "0225", "0002", "0033", "0003", "PM", "0002", "0002", "Pacific Daylight Time", "1997", "Wednesday",
533        "1997", "2450674", "52452513", "GMT-07:00", "Pacific Time",  "Wednesday", "August", "3rd quarter", "3rd quarter", "Los Angeles Time",
534        "1997", "GMT-07:00", "-0700", "-0700",
535    };
536
537    const int32_t EXPECTED_LENGTH = sizeof(EXPECTED)/sizeof(EXPECTED[0]);
538
539    assertTrue("data size", EXPECTED_LENGTH == COUNT * UDAT_FIELD_COUNT);
540
541    TimeZone* PT = TimeZone::createTimeZone("America/Los_Angeles");
542    for (j = 0, exp = 0; j < COUNT; ++j) {
543        //  String str;
544        DateFormat* df = dateFormats[j];
545        df->setTimeZone(*PT);
546        SimpleDateFormat* sdtfmt = dynamic_cast<SimpleDateFormat*>(df);
547        if (sdtfmt != NULL) {
548            logln(" Pattern = " + sdtfmt->toPattern(buf.remove()));
549        } else {
550            logln(" Pattern = ? (not a SimpleDateFormat)");
551        }
552        logln((UnicodeString)"  Result = " + df->format(aug13, buf.remove()));
553
554        int32_t expBase = exp; // save for later
555        for (i = 0; i < UDAT_FIELD_COUNT; ++i, ++exp) {
556            FieldPosition pos(i);
557            buf.remove();
558            df->format(aug13, buf, pos);
559            UnicodeString field;
560            buf.extractBetween(pos.getBeginIndex(), pos.getEndIndex(), field);
561            assertEquals((UnicodeString)"field #" + i + " " + DATEFORMAT_FIELD_NAMES[i],
562                         ctou(EXPECTED[exp]), field);
563        }
564
565        // test FieldPositionIterator API
566        logln("FieldPositionIterator");
567        {
568          UErrorCode status = U_ZERO_ERROR;
569          FieldPositionIterator posIter;
570          FieldPosition fp;
571
572          buf.remove();
573          df->format(aug13, buf, &posIter, status);
574          while (posIter.next(fp)) {
575            int32_t i = fp.getField();
576            UnicodeString field;
577            buf.extractBetween(fp.getBeginIndex(), fp.getEndIndex(), field);
578            assertEquals((UnicodeString)"field #" + i + " " + DATEFORMAT_FIELD_NAMES[i],
579                         ctou(EXPECTED[expBase + i]), field);
580          }
581
582        }
583    }
584
585
586    // test null posIter
587    buf.remove();
588    UErrorCode status = U_ZERO_ERROR;
589    dateFormats[0]->format(aug13, buf, NULL, status);
590    // if we didn't crash, we succeeded.
591
592    for (i=0; i<COUNT; ++i) {
593        delete dateFormats[i];
594    }
595    delete PT;
596}
597
598// -------------------------------------
599
600/**
601 * General parse/format tests.  Add test cases as needed.
602 */
603void DateFormatTest::TestGeneral() {
604    const char* DATA[] = {
605        "yyyy MM dd HH:mm:ss.SSS",
606
607        // Milliseconds are left-justified, since they format as fractions of a second
608        "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",
609        "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",
610        "y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567",
611        "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",
612    };
613    expect(DATA, ARRAY_SIZE(DATA), Locale("en", "", ""));
614}
615
616// -------------------------------------
617
618/**
619 * Verify that strings which contain incomplete specifications are parsed
620 * correctly.  In some instances, this means not being parsed at all, and
621 * returning an appropriate error.
622 */
623void
624DateFormatTest::TestPartialParse994()
625{
626    UErrorCode status = U_ZERO_ERROR;
627    SimpleDateFormat* f = new SimpleDateFormat(status);
628    if (U_FAILURE(status)) {
629        dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
630        delete f;
631        return;
632    }
633    UDate null = 0;
634    tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:11:42", date(97, 1 - 1, 17, 10, 11, 42));
635    tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:", null);
636    tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10", null);
637    tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 ", null);
638    tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17", null);
639    if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
640    delete f;
641}
642
643// -------------------------------------
644
645void
646DateFormatTest::tryPat994(SimpleDateFormat* format, const char* pat, const char* str, UDate expected)
647{
648    UErrorCode status = U_ZERO_ERROR;
649    UDate null = 0;
650    logln(UnicodeString("Pattern \"") + pat + "\"   String \"" + str + "\"");
651    //try {
652        format->applyPattern(pat);
653        UDate date = format->parse(str, status);
654        if (U_FAILURE(status) || date == null)
655        {
656            logln((UnicodeString)"ParseException: " + (int32_t)status);
657            if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
658        }
659        else
660        {
661            UnicodeString f;
662            ((DateFormat*)format)->format(date, f);
663            logln(UnicodeString(" parse(") + str + ") -> " + dateToString(date));
664            logln((UnicodeString)" format -> " + f);
665            if (expected == null ||
666                !(date == expected)) errln((UnicodeString)"FAIL: Expected null");//" + expected);
667            if (!(f == str)) errln(UnicodeString("FAIL: Expected ") + str);
668        }
669    //}
670    //catch(ParseException e) {
671    //    logln((UnicodeString)"ParseException: " + e.getMessage());
672    //    if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
673    //}
674    //catch(Exception e) {
675    //    errln((UnicodeString)"*** Exception:");
676    //    e.printStackTrace();
677    //}
678}
679
680// -------------------------------------
681
682/**
683 * Verify the behavior of patterns in which digits for different fields run together
684 * without intervening separators.
685 */
686void
687DateFormatTest::TestRunTogetherPattern985()
688{
689    UErrorCode status = U_ZERO_ERROR;
690    UnicodeString format("yyyyMMddHHmmssSSS");
691    UnicodeString now, then;
692    //UBool flag;
693    SimpleDateFormat *formatter = new SimpleDateFormat(format, status);
694    if (U_FAILURE(status)) {
695        dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
696        delete formatter;
697        return;
698    }
699    UDate date1 = Calendar::getNow();
700    ((DateFormat*)formatter)->format(date1, now);
701    logln(now);
702    ParsePosition pos(0);
703    UDate date2 = formatter->parse(now, pos);
704    if (date2 == 0) then = UnicodeString("Parse stopped at ") + pos.getIndex();
705    else ((DateFormat*)formatter)->format(date2, then);
706    logln(then);
707    if (!(date2 == date1)) errln((UnicodeString)"FAIL");
708    delete formatter;
709    if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
710}
711
712// -------------------------------------
713
714/**
715 * Verify the behavior of patterns in which digits for different fields run together
716 * without intervening separators.
717 */
718void
719DateFormatTest::TestRunTogetherPattern917()
720{
721    UErrorCode status = U_ZERO_ERROR;
722    SimpleDateFormat* fmt;
723    UnicodeString myDate;
724    fmt = new SimpleDateFormat((UnicodeString)"yyyy/MM/dd", status);
725    if (U_FAILURE(status)) {
726        dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
727        delete fmt;
728        return;
729    }
730    myDate = "1997/02/03";
731    testIt917(fmt, myDate, date(97, 2 - 1, 3));
732    delete fmt;
733    fmt = new SimpleDateFormat((UnicodeString)"yyyyMMdd", status);
734    myDate = "19970304";
735    testIt917(fmt, myDate, date(97, 3 - 1, 4));
736    delete fmt;
737    if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
738}
739
740// -------------------------------------
741
742void
743DateFormatTest::testIt917(SimpleDateFormat* fmt, UnicodeString& str, UDate expected)
744{
745    UErrorCode status = U_ZERO_ERROR;
746    UnicodeString pattern;
747    logln((UnicodeString)"pattern=" + fmt->toPattern(pattern) + "   string=" + str);
748    Formattable o;
749    //try {
750        ((Format*)fmt)->parseObject(str, o, status);
751    //}
752    if (U_FAILURE(status)) return;
753    //catch(ParseException e) {
754    //    e.printStackTrace();
755    //    return;
756    //}
757    logln((UnicodeString)"Parsed object: " + dateToString(o.getDate()));
758    if (!(o.getDate() == expected)) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
759    UnicodeString formatted; ((Format*)fmt)->format(o, formatted, status);
760    logln((UnicodeString)"Formatted string: " + formatted);
761    if (!(formatted == str)) errln((UnicodeString)"FAIL: Expected " + str);
762    if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
763}
764
765// -------------------------------------
766
767/**
768 * Verify the handling of Czech June and July, which have the unique attribute that
769 * one is a proper prefix substring of the other.
770 */
771void
772DateFormatTest::TestCzechMonths459()
773{
774    UErrorCode status = U_ZERO_ERROR;
775    DateFormat* fmt = DateFormat::createDateInstance(DateFormat::FULL, Locale("cs", "", ""));
776    if (fmt == NULL){
777        dataerrln("Error calling DateFormat::createDateInstance()");
778        return;
779    }
780
781    UnicodeString pattern;
782    logln((UnicodeString)"Pattern " + ((SimpleDateFormat*) fmt)->toPattern(pattern));
783    UDate june = date(97, UCAL_JUNE, 15);
784    UDate july = date(97, UCAL_JULY, 15);
785    UnicodeString juneStr; fmt->format(june, juneStr);
786    UnicodeString julyStr; fmt->format(july, julyStr);
787    //try {
788        logln((UnicodeString)"format(June 15 1997) = " + juneStr);
789        UDate d = fmt->parse(juneStr, status);
790        UnicodeString s; fmt->format(d, s);
791        int32_t month,yr,day,hr,min,sec; dateToFields(d,yr,month,day,hr,min,sec);
792        logln((UnicodeString)"  -> parse -> " + s + " (month = " + month + ")");
793        if (month != UCAL_JUNE) errln((UnicodeString)"FAIL: Month should be June");
794        logln((UnicodeString)"format(July 15 1997) = " + julyStr);
795        d = fmt->parse(julyStr, status);
796        fmt->format(d, s);
797        dateToFields(d,yr,month,day,hr,min,sec);
798        logln((UnicodeString)"  -> parse -> " + s + " (month = " + month + ")");
799        if (month != UCAL_JULY) errln((UnicodeString)"FAIL: Month should be July");
800    //}
801    //catch(ParseException e) {
802    if (U_FAILURE(status))
803        errln((UnicodeString)"Exception: " + (int32_t)status);
804    //}
805    delete fmt;
806}
807
808// -------------------------------------
809
810/**
811 * Test the handling of 'D' in patterns.
812 */
813void
814DateFormatTest::TestLetterDPattern212()
815{
816    UErrorCode status = U_ZERO_ERROR;
817    UnicodeString dateString("1995-040.05:01:29");
818    UnicodeString bigD("yyyy-DDD.hh:mm:ss");
819    UnicodeString littleD("yyyy-ddd.hh:mm:ss");
820    UDate expLittleD = date(95, 0, 1, 5, 1, 29);
821    UDate expBigD = expLittleD + 39 * 24 * 3600000.0;
822    expLittleD = expBigD; // Expect the same, with default lenient parsing
823    logln((UnicodeString)"dateString= " + dateString);
824    SimpleDateFormat *formatter = new SimpleDateFormat(bigD, status);
825    if (U_FAILURE(status)) {
826        dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
827        delete formatter;
828        return;
829    }
830    ParsePosition pos(0);
831    UDate myDate = formatter->parse(dateString, pos);
832    logln((UnicodeString)"Using " + bigD + " -> " + myDate);
833    if (myDate != expBigD) errln((UnicodeString)"FAIL: bigD - Expected " + dateToString(expBigD));
834    delete formatter;
835    formatter = new SimpleDateFormat(littleD, status);
836    ASSERT_OK(status);
837    pos = ParsePosition(0);
838    myDate = formatter->parse(dateString, pos);
839    logln((UnicodeString)"Using " + littleD + " -> " + dateToString(myDate));
840    if (myDate != expLittleD) errln((UnicodeString)"FAIL: littleD - Expected " + dateToString(expLittleD));
841    delete formatter;
842    if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
843}
844
845// -------------------------------------
846
847/**
848 * Test the day of year pattern.
849 */
850void
851DateFormatTest::TestDayOfYearPattern195()
852{
853    UErrorCode status = U_ZERO_ERROR;
854    UDate today = Calendar::getNow();
855    int32_t year,month,day,hour,min,sec; dateToFields(today,year,month,day,hour,min,sec);
856    UDate expected = date(year, month, day);
857    logln((UnicodeString)"Test Date: " + dateToString(today));
858    SimpleDateFormat* sdf = (SimpleDateFormat*)DateFormat::createDateInstance();
859    if (sdf == NULL){
860        dataerrln("Error calling DateFormat::createDateInstance()");
861        return;
862    }
863    tryPattern(*sdf, today, 0, expected);
864    tryPattern(*sdf, today, "G yyyy DDD", expected);
865    delete sdf;
866    if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
867}
868
869// -------------------------------------
870
871void
872DateFormatTest::tryPattern(SimpleDateFormat& sdf, UDate d, const char* pattern, UDate expected)
873{
874    UErrorCode status = U_ZERO_ERROR;
875    if (pattern != 0) sdf.applyPattern(pattern);
876    UnicodeString thePat;
877    logln((UnicodeString)"pattern: " + sdf.toPattern(thePat));
878    UnicodeString formatResult; (*(DateFormat*)&sdf).format(d, formatResult);
879    logln((UnicodeString)" format -> " + formatResult);
880    // try {
881        UDate d2 = sdf.parse(formatResult, status);
882        logln((UnicodeString)" parse(" + formatResult + ") -> " + dateToString(d2));
883        if (d2 != expected) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
884        UnicodeString format2; (*(DateFormat*)&sdf).format(d2, format2);
885        logln((UnicodeString)" format -> " + format2);
886        if (!(formatResult == format2)) errln((UnicodeString)"FAIL: Round trip drift");
887    //}
888    //catch(Exception e) {
889    if (U_FAILURE(status))
890        errln((UnicodeString)"Error: " + (int32_t)status);
891    //}
892}
893
894// -------------------------------------
895
896/**
897 * Test the handling of single quotes in patterns.
898 */
899void
900DateFormatTest::TestQuotePattern161()
901{
902    UErrorCode status = U_ZERO_ERROR;
903    SimpleDateFormat* formatter = new SimpleDateFormat((UnicodeString)"MM/dd/yyyy 'at' hh:mm:ss a zzz", status);
904    if (U_FAILURE(status)) {
905        dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
906        delete formatter;
907        return;
908    }
909    UDate currentTime_1 = date(97, UCAL_AUGUST, 13, 10, 42, 28);
910    UnicodeString dateString; ((DateFormat*)formatter)->format(currentTime_1, dateString);
911    UnicodeString exp("08/13/1997 at 10:42:28 AM ");
912    logln((UnicodeString)"format(" + dateToString(currentTime_1) + ") = " + dateString);
913    if (0 != dateString.compareBetween(0, exp.length(), exp, 0, exp.length())) errln((UnicodeString)"FAIL: Expected " + exp);
914    delete formatter;
915    if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
916}
917
918// -------------------------------------
919
920/**
921 * Verify the correct behavior when handling invalid input strings.
922 */
923void
924DateFormatTest::TestBadInput135()
925{
926    UErrorCode status = U_ZERO_ERROR;
927    DateFormat::EStyle looks[] = {
928        DateFormat::SHORT, DateFormat::MEDIUM, DateFormat::LONG, DateFormat::FULL
929    };
930    int32_t looks_length = (int32_t)(sizeof(looks) / sizeof(looks[0]));
931    const char* strings[] = {
932        "Mar 15", "Mar 15 1997", "asdf", "3/1/97 1:23:", "3/1/00 1:23:45 AM"
933    };
934    int32_t strings_length = (int32_t)(sizeof(strings) / sizeof(strings[0]));
935    DateFormat *full = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::LONG);
936    if(full==NULL) {
937      dataerrln("could not create date time instance");
938      return;
939    }
940    UnicodeString expected("March 1, 2000 at 1:23:45 AM ");
941    for (int32_t i = 0; i < strings_length;++i) {
942        const char* text = strings[i];
943        for (int32_t j = 0; j < looks_length;++j) {
944            DateFormat::EStyle dateLook = looks[j];
945            for (int32_t k = 0; k < looks_length;++k) {
946                DateFormat::EStyle timeLook = looks[k];
947                DateFormat *df = DateFormat::createDateTimeInstance(dateLook, timeLook);
948                if (df == NULL){
949                    dataerrln("Error calling DateFormat::createDateTimeInstance()");
950                    continue;
951                }
952                UnicodeString prefix = UnicodeString(text) + ", " + dateLook + "/" + timeLook + ": ";
953                //try {
954                    UDate when = df->parse(text, status);
955                    if (when == 0 && U_SUCCESS(status)) {
956                        errln(prefix + "SHOULD NOT HAPPEN: parse returned 0.");
957                        continue;
958                    }
959                    if (U_SUCCESS(status))
960                    {
961                        UnicodeString format;
962                        UnicodeString pattern;
963                        SimpleDateFormat* sdtfmt = dynamic_cast<SimpleDateFormat*>(df);
964                        if (sdtfmt != NULL) {
965                            sdtfmt->toPattern(pattern);
966                        }
967                        full->format(when, format);
968                        logln(prefix + "OK: " + format);
969                        if (0!=format.compareBetween(0, expected.length(), expected, 0, expected.length()))
970                            errln((UnicodeString)"FAIL: Parse \"" + text + "\", pattern \"" + pattern + "\", expected " + expected + " got " + format);
971                    }
972                //}
973                //catch(ParseException e) {
974                    else
975                        status = U_ZERO_ERROR;
976                //}
977                //catch(StringIndexOutOfBoundsException e) {
978                //    errln(prefix + "SHOULD NOT HAPPEN: " + (int)status);
979                //}
980                delete df;
981            }
982        }
983    }
984    delete full;
985    if (U_FAILURE(status))
986        errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
987}
988
989static const char* const parseFormats[] = {
990    "MMMM d, yyyy",
991    "MMMM d yyyy",
992    "M/d/yy",
993    "d MMMM, yyyy",
994    "d MMMM yyyy",
995    "d MMMM",
996    "MMMM d",
997    "yyyy",
998    "h:mm a MMMM d, yyyy"
999};
1000
1001#if 0
1002// strict inputStrings
1003static const char* const inputStrings[] = {
1004    "bogus string", 0, 0, 0, 0, 0, 0, 0, 0, 0,
1005    "April 1, 1997", "April 1, 1997", 0, 0, 0, 0, 0, "April 1", 0, 0,
1006    "Jan 1, 1970", "January 1, 1970", 0, 0, 0, 0, 0, "January 1", 0, 0,
1007    "Jan 1 2037", 0, "January 1 2037", 0, 0, 0, 0, "January 1", 0, 0,
1008    "1/1/70", 0, 0, "1/1/70", 0, 0, 0, 0, "0001", 0,
1009    "5 May 1997", 0, 0, 0, 0, "5 May 1997", "5 May", 0, "0005", 0,
1010    "16 May", 0, 0, 0, 0, 0, "16 May", 0, "0016", 0,
1011    "April 30", 0, 0, 0, 0, 0, 0, "April 30", 0, 0,
1012    "1998", 0, 0, 0, 0, 0, 0, 0, "1998", 0,
1013    "1", 0, 0, 0, 0, 0, 0, 0, "0001", 0,
1014    "3:00 pm Jan 1, 1997", 0, 0, 0, 0, 0, 0, 0, "0003", "3:00 PM January 1, 1997",
1015};
1016#else
1017// lenient inputStrings
1018static const char* const inputStrings[] = {
1019    "bogus string", 0, 0, 0, 0, 0, 0, 0, 0, 0,
1020    "April 1, 1997", "April 1, 1997", "April 1 1997", "4/1/97", 0, 0, 0, "April 1", 0, 0,
1021    "Jan 1, 1970", "January 1, 1970", "January 1 1970", "1/1/70", 0, 0, 0, "January 1", 0, 0,
1022    "Jan 1 2037", "January 1, 2037", "January 1 2037", "1/1/37", 0, 0, 0, "January 1", 0, 0,
1023    "1/1/70", "January 1, 0070", "January 1 0070", "1/1/70", "1 January, 0070", "1 January 0070", "1 January", "January 1", "0001", 0,
1024    "5 May 1997", 0, 0, 0, "5 May, 1997", "5 May 1997", "5 May", 0, "0005", 0,
1025    "16 May", 0, 0, 0, 0, 0, "16 May", 0, "0016", 0,
1026    "April 30", 0, 0, 0, 0, 0, 0, "April 30", 0, 0,
1027    "1998", 0, 0, 0, 0, 0, 0, 0, "1998", 0,
1028    "1", 0, 0, 0, 0, 0, 0, 0, "0001", 0,
1029    "3:00 pm Jan 1, 1997", 0, 0, 0, 0, 0, 0, 0, "0003", "3:00 PM January 1, 1997",
1030};
1031#endif
1032
1033// -------------------------------------
1034
1035/**
1036 * Verify the correct behavior when parsing an array of inputs against an
1037 * array of patterns, with known results.  The results are encoded after
1038 * the input strings in each row.
1039 */
1040void
1041DateFormatTest::TestBadInput135a()
1042{
1043  UErrorCode status = U_ZERO_ERROR;
1044  SimpleDateFormat* dateParse = new SimpleDateFormat(status);
1045  if(U_FAILURE(status)) {
1046    dataerrln("Failed creating SimpleDateFormat with %s. Quitting test", u_errorName(status));
1047    delete dateParse;
1048    return;
1049  }
1050  const char* s;
1051  UDate date;
1052  const uint32_t PF_LENGTH = (int32_t)(sizeof(parseFormats)/sizeof(parseFormats[0]));
1053  const uint32_t INPUT_LENGTH = (int32_t)(sizeof(inputStrings)/sizeof(inputStrings[0]));
1054
1055  dateParse->applyPattern("d MMMM, yyyy");
1056  dateParse->adoptTimeZone(TimeZone::createDefault());
1057  s = "not parseable";
1058  UnicodeString thePat;
1059  logln(UnicodeString("Trying to parse \"") + s + "\" with " + dateParse->toPattern(thePat));
1060  //try {
1061  date = dateParse->parse(s, status);
1062  if (U_SUCCESS(status))
1063    errln((UnicodeString)"FAIL: Expected exception during parse");
1064  //}
1065  //catch(Exception ex) {
1066  else
1067    logln((UnicodeString)"Exception during parse: " + (int32_t)status);
1068  status = U_ZERO_ERROR;
1069  //}
1070  for (uint32_t i = 0; i < INPUT_LENGTH; i += (PF_LENGTH + 1)) {
1071    ParsePosition parsePosition(0);
1072    UnicodeString s( inputStrings[i]);
1073    for (uint32_t index = 0; index < PF_LENGTH;++index) {
1074      const char* expected = inputStrings[i + 1 + index];
1075      dateParse->applyPattern(parseFormats[index]);
1076      dateParse->adoptTimeZone(TimeZone::createDefault());
1077      //try {
1078      parsePosition.setIndex(0);
1079      date = dateParse->parse(s, parsePosition);
1080      if (parsePosition.getIndex() != 0) {
1081        UnicodeString s1, s2;
1082        s.extract(0, parsePosition.getIndex(), s1);
1083        s.extract(parsePosition.getIndex(), s.length(), s2);
1084        if (date == 0) {
1085          errln((UnicodeString)"ERROR: null result fmt=\"" +
1086                     parseFormats[index] +
1087                     "\" pos=" + parsePosition.getIndex() + " " +
1088                     s1 + "|" + s2);
1089        }
1090        else {
1091          UnicodeString result;
1092          ((DateFormat*)dateParse)->format(date, result);
1093          logln((UnicodeString)"Parsed \"" + s + "\" using \"" + dateParse->toPattern(thePat) + "\" to: " + result);
1094          if (expected == 0)
1095            errln((UnicodeString)"FAIL: Expected parse failure, got " + result);
1096          else if (!(result == expected))
1097            errln(UnicodeString("FAIL: Parse \"") + s + UnicodeString("\", expected ") + expected + UnicodeString(", got ") + result);
1098        }
1099      }
1100      else if (expected != 0) {
1101        errln(UnicodeString("FAIL: Expected ") + expected + " from \"" +
1102                     s + "\" with \"" + dateParse->toPattern(thePat) + "\"");
1103      }
1104      //}
1105      //catch(Exception ex) {
1106      if (U_FAILURE(status))
1107        errln((UnicodeString)"An exception was thrown during parse: " + (int32_t)status);
1108      //}
1109    }
1110  }
1111  delete dateParse;
1112  if (U_FAILURE(status))
1113    errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
1114}
1115
1116// -------------------------------------
1117
1118/**
1119 * Test the parsing of two-digit years.
1120 */
1121void
1122DateFormatTest::TestTwoDigitYear()
1123{
1124    UErrorCode ec = U_ZERO_ERROR;
1125    SimpleDateFormat fmt("dd/MM/yy", Locale::getUK(), ec);
1126    if (U_FAILURE(ec)) {
1127        dataerrln("FAIL: SimpleDateFormat constructor - %s", u_errorName(ec));
1128        return;
1129    }
1130    parse2DigitYear(fmt, "5/6/17", date(117, UCAL_JUNE, 5));
1131    parse2DigitYear(fmt, "4/6/34", date(34, UCAL_JUNE, 4));
1132}
1133
1134// -------------------------------------
1135
1136void
1137DateFormatTest::parse2DigitYear(DateFormat& fmt, const char* str, UDate expected)
1138{
1139    UErrorCode status = U_ZERO_ERROR;
1140    //try {
1141        UDate d = fmt.parse(str, status);
1142        UnicodeString thePat;
1143        logln(UnicodeString("Parsing \"") + str + "\" with " + ((SimpleDateFormat*)&fmt)->toPattern(thePat) +
1144            "  => " + dateToString(d));
1145        if (d != expected) errln((UnicodeString)"FAIL: Expected " + expected);
1146    //}
1147    //catch(ParseException e) {
1148        if (U_FAILURE(status))
1149        errln((UnicodeString)"FAIL: Got exception");
1150    //}
1151}
1152
1153// -------------------------------------
1154
1155/**
1156 * Test the formatting of time zones.
1157 */
1158void
1159DateFormatTest::TestDateFormatZone061()
1160{
1161    UErrorCode status = U_ZERO_ERROR;
1162    UDate date;
1163    DateFormat *formatter;
1164    date= 859248000000.0;
1165    logln((UnicodeString)"Date 1997/3/25 00:00 GMT: " + date);
1166    formatter = new SimpleDateFormat((UnicodeString)"dd-MMM-yyyyy HH:mm", Locale::getUK(), status);
1167    if(U_FAILURE(status)) {
1168      dataerrln("Failed creating SimpleDateFormat with %s. Quitting test", u_errorName(status));
1169      delete formatter;
1170      return;
1171    }
1172    formatter->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1173    UnicodeString temp; formatter->format(date, temp);
1174    logln((UnicodeString)"Formatted in GMT to: " + temp);
1175    //try {
1176        UDate tempDate = formatter->parse(temp, status);
1177        logln((UnicodeString)"Parsed to: " + dateToString(tempDate));
1178        if (tempDate != date) errln((UnicodeString)"FAIL: Expected " + dateToString(date));
1179    //}
1180    //catch(Throwable t) {
1181    if (U_FAILURE(status))
1182        errln((UnicodeString)"Date Formatter throws: " + (int32_t)status);
1183    //}
1184    delete formatter;
1185}
1186
1187// -------------------------------------
1188
1189/**
1190 * Test the formatting of time zones.
1191 */
1192void
1193DateFormatTest::TestDateFormatZone146()
1194{
1195    TimeZone *saveDefault = TimeZone::createDefault();
1196
1197        //try {
1198    TimeZone *thedefault = TimeZone::createTimeZone("GMT");
1199    TimeZone::setDefault(*thedefault);
1200            // java.util.Locale.setDefault(new java.util.Locale("ar", "", ""));
1201
1202            // check to be sure... its GMT all right
1203        TimeZone *testdefault = TimeZone::createDefault();
1204        UnicodeString testtimezone;
1205        testdefault->getID(testtimezone);
1206        if (testtimezone == "GMT")
1207            logln("Test timezone = " + testtimezone);
1208        else
1209            dataerrln("Test timezone should be GMT, not " + testtimezone);
1210
1211        UErrorCode status = U_ZERO_ERROR;
1212        // now try to use the default GMT time zone
1213        GregorianCalendar *greenwichcalendar =
1214            new GregorianCalendar(1997, 3, 4, 23, 0, status);
1215        if (U_FAILURE(status)) {
1216            dataerrln("Fail new GregorianCalendar: %s", u_errorName(status));
1217        } else {
1218            //*****************************greenwichcalendar.setTimeZone(TimeZone.getDefault());
1219            //greenwichcalendar.set(1997, 3, 4, 23, 0);
1220            // try anything to set hour to 23:00 !!!
1221            greenwichcalendar->set(UCAL_HOUR_OF_DAY, 23);
1222            // get time
1223            UDate greenwichdate = greenwichcalendar->getTime(status);
1224            // format every way
1225            UnicodeString DATA [] = {
1226                UnicodeString("simple format:  "), UnicodeString("04/04/97 23:00 GMT"),
1227                    UnicodeString("MM/dd/yy HH:mm z"),
1228                UnicodeString("full format:    "), UnicodeString("Friday, April 4, 1997 11:00:00 o'clock PM GMT"),
1229                    UnicodeString("EEEE, MMMM d, yyyy h:mm:ss 'o''clock' a z"),
1230                UnicodeString("long format:    "), UnicodeString("April 4, 1997 11:00:00 PM GMT"),
1231                    UnicodeString("MMMM d, yyyy h:mm:ss a z"),
1232                UnicodeString("default format: "), UnicodeString("04-Apr-97 11:00:00 PM"),
1233                    UnicodeString("dd-MMM-yy h:mm:ss a"),
1234                UnicodeString("short format:   "), UnicodeString("4/4/97 11:00 PM"),
1235                    UnicodeString("M/d/yy h:mm a")
1236            };
1237            int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0]));
1238
1239            for (int32_t i=0; i<DATA_length; i+=3) {
1240                DateFormat *fmt = new SimpleDateFormat(DATA[i+2], Locale::getEnglish(), status);
1241                if (U_FAILURE(status)) {
1242                    dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
1243                    break;
1244                }
1245                fmt->setCalendar(*greenwichcalendar);
1246                UnicodeString result;
1247                result = fmt->format(greenwichdate, result);
1248                logln(DATA[i] + result);
1249                if (result != DATA[i+1])
1250                    errln("FAIL: Expected " + DATA[i+1] + ", got " + result);
1251                delete fmt;
1252            }
1253        }
1254    //}
1255    //finally {
1256        TimeZone::adoptDefault(saveDefault);
1257    //}
1258        delete testdefault;
1259        delete greenwichcalendar;
1260        delete thedefault;
1261
1262
1263}
1264
1265// -------------------------------------
1266
1267/**
1268 * Test the formatting of dates in different locales.
1269 */
1270void
1271DateFormatTest::TestLocaleDateFormat() // Bug 495
1272{
1273    UDate testDate = date(97, UCAL_SEPTEMBER, 15);
1274    DateFormat *dfFrench = DateFormat::createDateTimeInstance(DateFormat::FULL,
1275        DateFormat::FULL, Locale::getFrench());
1276    DateFormat *dfUS = DateFormat::createDateTimeInstance(DateFormat::FULL,
1277        DateFormat::FULL, Locale::getUS());
1278    UnicodeString expectedFRENCH ( "lundi 15 septembre 1997 00:00:00 heure avanc\\u00E9e du Pacifique", -1, US_INV );
1279    expectedFRENCH = expectedFRENCH.unescape();
1280    UnicodeString expectedUS ( "Monday, September 15, 1997 at 12:00:00 AM Pacific Daylight Time" );
1281    logln((UnicodeString)"Date set to : " + dateToString(testDate));
1282    UnicodeString out;
1283    if (dfUS == NULL || dfFrench == NULL){
1284        dataerrln("Error calling DateFormat::createDateTimeInstance)");
1285        delete dfUS;
1286        delete dfFrench;
1287        return;
1288    }
1289
1290    dfFrench->format(testDate, out);
1291    logln((UnicodeString)"Date Formated with French Locale " + out);
1292    if (!(out == expectedFRENCH))
1293        errln((UnicodeString)"FAIL: Expected " + expectedFRENCH);
1294    out.truncate(0);
1295    dfUS->format(testDate, out);
1296    logln((UnicodeString)"Date Formated with US Locale " + out);
1297    if (!(out == expectedUS))
1298        errln((UnicodeString)"FAIL: Expected " + expectedUS);
1299    delete dfUS;
1300    delete dfFrench;
1301}
1302
1303/**
1304 * Test DateFormat(Calendar) API
1305 */
1306void DateFormatTest::TestDateFormatCalendar() {
1307    DateFormat *date=0, *time=0, *full=0;
1308    Calendar *cal=0;
1309    UnicodeString str;
1310    ParsePosition pos;
1311    UDate when;
1312    UErrorCode ec = U_ZERO_ERROR;
1313
1314    /* Create a formatter for date fields. */
1315    date = DateFormat::createDateInstance(DateFormat::kShort, Locale::getUS());
1316    if (date == NULL) {
1317        dataerrln("FAIL: createDateInstance failed");
1318        goto FAIL;
1319    }
1320
1321    /* Create a formatter for time fields. */
1322    time = DateFormat::createTimeInstance(DateFormat::kShort, Locale::getUS());
1323    if (time == NULL) {
1324        errln("FAIL: createTimeInstance failed");
1325        goto FAIL;
1326    }
1327
1328    /* Create a full format for output */
1329    full = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull,
1330                                              Locale::getUS());
1331    if (full == NULL) {
1332        errln("FAIL: createInstance failed");
1333        goto FAIL;
1334    }
1335
1336    /* Create a calendar */
1337    cal = Calendar::createInstance(Locale::getUS(), ec);
1338    if (cal == NULL || U_FAILURE(ec)) {
1339        errln((UnicodeString)"FAIL: Calendar::createInstance failed with " +
1340              u_errorName(ec));
1341        goto FAIL;
1342    }
1343
1344    /* Parse the date */
1345    cal->clear();
1346    str = UnicodeString("4/5/2001", "");
1347    pos.setIndex(0);
1348    date->parse(str, *cal, pos);
1349    if (pos.getIndex() != str.length()) {
1350        errln((UnicodeString)"FAIL: DateFormat::parse(4/5/2001) failed at " +
1351              pos.getIndex());
1352        goto FAIL;
1353    }
1354
1355    /* Parse the time */
1356    str = UnicodeString("5:45 PM", "");
1357    pos.setIndex(0);
1358    time->parse(str, *cal, pos);
1359    if (pos.getIndex() != str.length()) {
1360        errln((UnicodeString)"FAIL: DateFormat::parse(17:45) failed at " +
1361              pos.getIndex());
1362        goto FAIL;
1363    }
1364
1365    /* Check result */
1366    when = cal->getTime(ec);
1367    if (U_FAILURE(ec)) {
1368        errln((UnicodeString)"FAIL: cal->getTime() failed with " + u_errorName(ec));
1369        goto FAIL;
1370    }
1371    str.truncate(0);
1372    full->format(when, str);
1373    // Thursday, April 5, 2001 5:45:00 PM PDT 986517900000
1374    if (when == 986517900000.0) {
1375        logln("Ok: Parsed result: " + str);
1376    } else {
1377        errln("FAIL: Parsed result: " + str + ", exp 4/5/2001 5:45 PM");
1378    }
1379
1380 FAIL:
1381    delete date;
1382    delete time;
1383    delete full;
1384    delete cal;
1385}
1386
1387/**
1388 * Test DateFormat's parsing of space characters.  See jitterbug 1916.
1389 */
1390void DateFormatTest::TestSpaceParsing() {
1391    const char* DATA[] = {
1392        "yyyy MM dd HH:mm:ss",
1393
1394        // pattern, input, expected parse or NULL if expect parse failure
1395        "MMMM d yy", " 04 05 06",  "2006 04 05 00:00:00",
1396        NULL,        "04 05 06",   "2006 04 05 00:00:00",
1397
1398        "MM d yy",   " 04 05 06",    "2006 04 05 00:00:00",
1399        NULL,        "04 05 06",     "2006 04 05 00:00:00",
1400        NULL,        "04/05/06",     "2006 04 05 00:00:00",
1401        NULL,        "04-05-06",     "2006 04 05 00:00:00",
1402        NULL,        "04.05.06",     "2006 04 05 00:00:00",
1403        NULL,        "04 / 05 / 06", "2006 04 05 00:00:00",
1404        NULL,        "Apr / 05/ 06", "2006 04 05 00:00:00",
1405        NULL,        "Apr-05-06",    "2006 04 05 00:00:00",
1406        NULL,        "Apr 05, 2006", "2006 04 05 00:00:00",
1407
1408        "MMMM d yy", " Apr 05 06", "2006 04 05 00:00:00",
1409        NULL,        "Apr 05 06",  "2006 04 05 00:00:00",
1410        NULL,        "Apr05 06",   "2006 04 05 00:00:00",
1411
1412        "hh:mm:ss a", "12:34:56 PM", "1970 01 01 12:34:56",
1413        NULL,         "12:34:56PM",  "1970 01 01 12:34:56",
1414        NULL,         "12.34.56PM",  "1970 01 01 12:34:56",
1415        NULL,         "12-34-56 PM", "1970 01 01 12:34:56",
1416        NULL,         "12 : 34 : 56  PM", "1970 01 01 12:34:56",
1417
1418        "MM d yy 'at' hh:mm:ss a", "04/05/06 12:34:56 PM", "2006 04 05 12:34:56",
1419
1420        "MMMM dd yyyy hh:mm a", "September 27, 1964 21:56 PM", "1964 09 28 09:56:00",
1421        NULL,                   "November 4, 2008 0:13 AM",    "2008 11 04 00:13:00",
1422
1423        "HH'h'mm'min'ss's'", "12h34min56s", "1970 01 01 12:34:56",
1424        NULL,                "12h34mi56s",  "1970 01 01 12:34:56",
1425        NULL,                "12h34m56s",   "1970 01 01 12:34:56",
1426        NULL,                "12:34:56",    "1970 01 01 12:34:56"
1427    };
1428    const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
1429
1430    expectParse(DATA, DATA_len, Locale("en"));
1431}
1432
1433/**
1434 * Test handling of "HHmmss" pattern.
1435 */
1436void DateFormatTest::TestExactCountFormat() {
1437    const char* DATA[] = {
1438        "yyyy MM dd HH:mm:ss",
1439
1440        // pattern, input, expected parse or NULL if expect parse failure
1441        "HHmmss", "123456", "1970 01 01 12:34:56",
1442        NULL,     "12345",  "1970 01 01 01:23:45",
1443        NULL,     "1234",   NULL,
1444        NULL,     "00-05",  NULL,
1445        NULL,     "12-34",  NULL,
1446        NULL,     "00+05",  NULL,
1447        "ahhmm",  "PM730",  "1970 01 01 19:30:00",
1448    };
1449    const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
1450
1451    expectParse(DATA, DATA_len, Locale("en"));
1452}
1453
1454/**
1455 * Test handling of white space.
1456 */
1457void DateFormatTest::TestWhiteSpaceParsing() {
1458    const char* DATA[] = {
1459        "yyyy MM dd",
1460
1461        // pattern, input, expected parse or null if expect parse failure
1462
1463        // Pattern space run should parse input text space run
1464        "MM   d yy",   " 04 01 03",    "2003 04 01",
1465        NULL,          " 04  01   03 ", "2003 04 01",
1466    };
1467    const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
1468
1469    expectParse(DATA, DATA_len, Locale("en"));
1470}
1471
1472
1473void DateFormatTest::TestInvalidPattern() {
1474    UErrorCode ec = U_ZERO_ERROR;
1475    SimpleDateFormat f(UnicodeString("Yesterday"), ec);
1476    if (U_FAILURE(ec)) {
1477        dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(ec));
1478        return;
1479    }
1480    UnicodeString out;
1481    FieldPosition pos;
1482    f.format((UDate)0, out, pos);
1483    logln(out);
1484    // The bug is that the call to format() will crash.  By not
1485    // crashing, the test passes.
1486}
1487
1488void DateFormatTest::TestGreekMay() {
1489    UErrorCode ec = U_ZERO_ERROR;
1490    UDate date = -9896080848000.0;
1491    SimpleDateFormat fmt("EEEE, dd MMMM yyyy h:mm:ss a", Locale("el", "", ""), ec);
1492    if (U_FAILURE(ec)) {
1493        dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(ec));
1494        return;
1495    }
1496    UnicodeString str;
1497    fmt.format(date, str);
1498    ParsePosition pos(0);
1499    UDate d2 = fmt.parse(str, pos);
1500    if (date != d2) {
1501        errln("FAIL: unable to parse strings where case-folding changes length");
1502    }
1503}
1504
1505void DateFormatTest::TestStandAloneMonths()
1506{
1507    const char *EN_DATA[] = {
1508        "yyyy MM dd HH:mm:ss",
1509
1510        "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",
1511        "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",
1512        "yyyy LLLL dd H:mm:ss", "F",  "2004 03 10 16:36:31", "2004 March 10 16:36:31",
1513        "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",
1514
1515        "LLLL", "fp", "1970 01 01 0:00:00", "January",   "1970 01 01 0:00:00",
1516        "LLLL", "fp", "1970 02 01 0:00:00", "February",  "1970 02 01 0:00:00",
1517        "LLLL", "fp", "1970 03 01 0:00:00", "March",     "1970 03 01 0:00:00",
1518        "LLLL", "fp", "1970 04 01 0:00:00", "April",     "1970 04 01 0:00:00",
1519        "LLLL", "fp", "1970 05 01 0:00:00", "May",       "1970 05 01 0:00:00",
1520        "LLLL", "fp", "1970 06 01 0:00:00", "June",      "1970 06 01 0:00:00",
1521        "LLLL", "fp", "1970 07 01 0:00:00", "July",      "1970 07 01 0:00:00",
1522        "LLLL", "fp", "1970 08 01 0:00:00", "August",    "1970 08 01 0:00:00",
1523        "LLLL", "fp", "1970 09 01 0:00:00", "September", "1970 09 01 0:00:00",
1524        "LLLL", "fp", "1970 10 01 0:00:00", "October",   "1970 10 01 0:00:00",
1525        "LLLL", "fp", "1970 11 01 0:00:00", "November",  "1970 11 01 0:00:00",
1526        "LLLL", "fp", "1970 12 01 0:00:00", "December",  "1970 12 01 0:00:00",
1527
1528        "LLL", "fp", "1970 01 01 0:00:00", "Jan", "1970 01 01 0:00:00",
1529        "LLL", "fp", "1970 02 01 0:00:00", "Feb", "1970 02 01 0:00:00",
1530        "LLL", "fp", "1970 03 01 0:00:00", "Mar", "1970 03 01 0:00:00",
1531        "LLL", "fp", "1970 04 01 0:00:00", "Apr", "1970 04 01 0:00:00",
1532        "LLL", "fp", "1970 05 01 0:00:00", "May", "1970 05 01 0:00:00",
1533        "LLL", "fp", "1970 06 01 0:00:00", "Jun", "1970 06 01 0:00:00",
1534        "LLL", "fp", "1970 07 01 0:00:00", "Jul", "1970 07 01 0:00:00",
1535        "LLL", "fp", "1970 08 01 0:00:00", "Aug", "1970 08 01 0:00:00",
1536        "LLL", "fp", "1970 09 01 0:00:00", "Sep", "1970 09 01 0:00:00",
1537        "LLL", "fp", "1970 10 01 0:00:00", "Oct", "1970 10 01 0:00:00",
1538        "LLL", "fp", "1970 11 01 0:00:00", "Nov", "1970 11 01 0:00:00",
1539        "LLL", "fp", "1970 12 01 0:00:00", "Dec", "1970 12 01 0:00:00",
1540    };
1541
1542    const char *CS_DATA[] = {
1543        "yyyy MM dd HH:mm:ss",
1544
1545        "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",
1546        "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",
1547        "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",
1548        "yyyy LLLL dd H:mm:ss", "F",  "2004 04 10 16:36:31", "2004 duben 10 16:36:31",
1549        "yyyy MMMM dd H:mm:ss", "F",  "2004 04 10 16:36:31", "2004 dubna 10 16:36:31",
1550        "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",
1551        "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",
1552
1553        "LLLL", "fp", "1970 01 01 0:00:00", "leden",               "1970 01 01 0:00:00",
1554        "LLLL", "fp", "1970 02 01 0:00:00", "\\u00FAnor",           "1970 02 01 0:00:00",
1555        "LLLL", "fp", "1970 03 01 0:00:00", "b\\u0159ezen",         "1970 03 01 0:00:00",
1556        "LLLL", "fp", "1970 04 01 0:00:00", "duben",               "1970 04 01 0:00:00",
1557        "LLLL", "fp", "1970 05 01 0:00:00", "kv\\u011Bten",         "1970 05 01 0:00:00",
1558        "LLLL", "fp", "1970 06 01 0:00:00", "\\u010Derven",         "1970 06 01 0:00:00",
1559        "LLLL", "fp", "1970 07 01 0:00:00", "\\u010Dervenec",       "1970 07 01 0:00:00",
1560        "LLLL", "fp", "1970 08 01 0:00:00", "srpen",               "1970 08 01 0:00:00",
1561        "LLLL", "fp", "1970 09 01 0:00:00", "z\\u00E1\\u0159\\u00ED", "1970 09 01 0:00:00",
1562        "LLLL", "fp", "1970 10 01 0:00:00", "\\u0159\\u00EDjen",     "1970 10 01 0:00:00",
1563        "LLLL", "fp", "1970 11 01 0:00:00", "listopad",            "1970 11 01 0:00:00",
1564        "LLLL", "fp", "1970 12 01 0:00:00", "prosinec",            "1970 12 01 0:00:00",
1565
1566        "LLL", "fp", "1970 01 01 0:00:00", "led",  "1970 01 01 0:00:00",
1567        "LLL", "fp", "1970 02 01 0:00:00", "\\u00FAno",  "1970 02 01 0:00:00",
1568        "LLL", "fp", "1970 03 01 0:00:00", "b\\u0159e",  "1970 03 01 0:00:00",
1569        "LLL", "fp", "1970 04 01 0:00:00", "dub",  "1970 04 01 0:00:00",
1570        "LLL", "fp", "1970 05 01 0:00:00", "kv\\u011B",  "1970 05 01 0:00:00",
1571        "LLL", "fp", "1970 06 01 0:00:00", "\\u010Dvn",  "1970 06 01 0:00:00",
1572        "LLL", "fp", "1970 07 01 0:00:00", "\\u010Dvc",  "1970 07 01 0:00:00",
1573        "LLL", "fp", "1970 08 01 0:00:00", "srp",  "1970 08 01 0:00:00",
1574        "LLL", "fp", "1970 09 01 0:00:00", "z\\u00E1\\u0159",  "1970 09 01 0:00:00",
1575        "LLL", "fp", "1970 10 01 0:00:00", "\\u0159\\u00EDj", "1970 10 01 0:00:00",
1576        "LLL", "fp", "1970 11 01 0:00:00", "lis", "1970 11 01 0:00:00",
1577        "LLL", "fp", "1970 12 01 0:00:00", "pro", "1970 12 01 0:00:00",
1578    };
1579
1580    expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
1581    expect(CS_DATA, ARRAY_SIZE(CS_DATA), Locale("cs", "", ""));
1582}
1583
1584void DateFormatTest::TestStandAloneDays()
1585{
1586    const char *EN_DATA[] = {
1587        "yyyy MM dd HH:mm:ss",
1588
1589        "cccc", "fp", "1970 01 04 0:00:00", "Sunday",    "1970 01 04 0:00:00",
1590        "cccc", "fp", "1970 01 05 0:00:00", "Monday",    "1970 01 05 0:00:00",
1591        "cccc", "fp", "1970 01 06 0:00:00", "Tuesday",   "1970 01 06 0:00:00",
1592        "cccc", "fp", "1970 01 07 0:00:00", "Wednesday", "1970 01 07 0:00:00",
1593        "cccc", "fp", "1970 01 01 0:00:00", "Thursday",  "1970 01 01 0:00:00",
1594        "cccc", "fp", "1970 01 02 0:00:00", "Friday",    "1970 01 02 0:00:00",
1595        "cccc", "fp", "1970 01 03 0:00:00", "Saturday",  "1970 01 03 0:00:00",
1596
1597        "ccc", "fp", "1970 01 04 0:00:00", "Sun", "1970 01 04 0:00:00",
1598        "ccc", "fp", "1970 01 05 0:00:00", "Mon", "1970 01 05 0:00:00",
1599        "ccc", "fp", "1970 01 06 0:00:00", "Tue", "1970 01 06 0:00:00",
1600        "ccc", "fp", "1970 01 07 0:00:00", "Wed", "1970 01 07 0:00:00",
1601        "ccc", "fp", "1970 01 01 0:00:00", "Thu", "1970 01 01 0:00:00",
1602        "ccc", "fp", "1970 01 02 0:00:00", "Fri", "1970 01 02 0:00:00",
1603        "ccc", "fp", "1970 01 03 0:00:00", "Sat", "1970 01 03 0:00:00",
1604    };
1605
1606    const char *CS_DATA[] = {
1607        "yyyy MM dd HH:mm:ss",
1608
1609        "cccc", "fp", "1970 01 04 0:00:00", "ned\\u011Ble",       "1970 01 04 0:00:00",
1610        "cccc", "fp", "1970 01 05 0:00:00", "pond\\u011Bl\\u00ED", "1970 01 05 0:00:00",
1611        "cccc", "fp", "1970 01 06 0:00:00", "\\u00FAter\\u00FD",   "1970 01 06 0:00:00",
1612        "cccc", "fp", "1970 01 07 0:00:00", "st\\u0159eda",       "1970 01 07 0:00:00",
1613        "cccc", "fp", "1970 01 01 0:00:00", "\\u010Dtvrtek",      "1970 01 01 0:00:00",
1614        "cccc", "fp", "1970 01 02 0:00:00", "p\\u00E1tek",        "1970 01 02 0:00:00",
1615        "cccc", "fp", "1970 01 03 0:00:00", "sobota",            "1970 01 03 0:00:00",
1616
1617        "ccc", "fp", "1970 01 04 0:00:00", "ne",      "1970 01 04 0:00:00",
1618        "ccc", "fp", "1970 01 05 0:00:00", "po",      "1970 01 05 0:00:00",
1619        "ccc", "fp", "1970 01 06 0:00:00", "\\u00FAt", "1970 01 06 0:00:00",
1620        "ccc", "fp", "1970 01 07 0:00:00", "st",      "1970 01 07 0:00:00",
1621        "ccc", "fp", "1970 01 01 0:00:00", "\\u010Dt", "1970 01 01 0:00:00",
1622        "ccc", "fp", "1970 01 02 0:00:00", "p\\u00E1", "1970 01 02 0:00:00",
1623        "ccc", "fp", "1970 01 03 0:00:00", "so",      "1970 01 03 0:00:00",
1624    };
1625
1626    expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
1627    expect(CS_DATA, ARRAY_SIZE(CS_DATA), Locale("cs", "", ""));
1628}
1629
1630void DateFormatTest::TestShortDays()
1631{
1632    const char *EN_DATA[] = {
1633        "yyyy MM dd HH:mm:ss",
1634
1635        "EEEEEE, MMM d y", "fp", "2013 01 13 0:00:00", "Su, Jan 13 2013", "2013 01 13 0:00:00",
1636        "EEEEEE, MMM d y", "fp", "2013 01 16 0:00:00", "We, Jan 16 2013", "2013 01 16 0:00:00",
1637        "EEEEEE d",        "fp", "1970 01 17 0:00:00", "Sa 17",           "1970 01 17 0:00:00",
1638        "cccccc d",        "fp", "1970 01 17 0:00:00", "Sa 17",           "1970 01 17 0:00:00",
1639        "cccccc",          "fp", "1970 01 03 0:00:00", "Sa",              "1970 01 03 0:00:00",
1640    };
1641    const char *SV_DATA[] = {
1642        "yyyy MM dd HH:mm:ss",
1643
1644        "EEEEEE d MMM y",  "fp", "2013 01 13 0:00:00", "s\\u00F6 13 jan 2013", "2013 01 13 0:00:00",
1645        "EEEEEE d MMM y",  "fp", "2013 01 16 0:00:00", "on 16 jan 2013",       "2013 01 16 0:00:00",
1646        "EEEEEE d",        "fp", "1970 01 17 0:00:00", "l\\u00F6 17",          "1970 01 17 0:00:00",
1647        "cccccc d",        "fp", "1970 01 17 0:00:00", "L\\u00F6 17",          "1970 01 17 0:00:00",
1648        "cccccc",          "fp", "1970 01 03 0:00:00", "L\\u00F6",             "1970 01 03 0:00:00",
1649    };
1650    expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
1651    expect(SV_DATA, ARRAY_SIZE(SV_DATA), Locale("sv", "", ""));
1652}
1653
1654void DateFormatTest::TestNarrowNames()
1655{
1656    const char *EN_DATA[] = {
1657            "yyyy MM dd HH:mm:ss",
1658
1659            "yyyy MMMMM dd H:mm:ss", "2004 03 10 16:36:31", "2004 M 10 16:36:31",
1660            "yyyy LLLLL dd H:mm:ss",  "2004 03 10 16:36:31", "2004 M 10 16:36:31",
1661
1662            "MMMMM", "1970 01 01 0:00:00", "J",
1663            "MMMMM", "1970 02 01 0:00:00", "F",
1664            "MMMMM", "1970 03 01 0:00:00", "M",
1665            "MMMMM", "1970 04 01 0:00:00", "A",
1666            "MMMMM", "1970 05 01 0:00:00", "M",
1667            "MMMMM", "1970 06 01 0:00:00", "J",
1668            "MMMMM", "1970 07 01 0:00:00", "J",
1669            "MMMMM", "1970 08 01 0:00:00", "A",
1670            "MMMMM", "1970 09 01 0:00:00", "S",
1671            "MMMMM", "1970 10 01 0:00:00", "O",
1672            "MMMMM", "1970 11 01 0:00:00", "N",
1673            "MMMMM", "1970 12 01 0:00:00", "D",
1674
1675            "LLLLL", "1970 01 01 0:00:00", "J",
1676            "LLLLL", "1970 02 01 0:00:00", "F",
1677            "LLLLL", "1970 03 01 0:00:00", "M",
1678            "LLLLL", "1970 04 01 0:00:00", "A",
1679            "LLLLL", "1970 05 01 0:00:00", "M",
1680            "LLLLL", "1970 06 01 0:00:00", "J",
1681            "LLLLL", "1970 07 01 0:00:00", "J",
1682            "LLLLL", "1970 08 01 0:00:00", "A",
1683            "LLLLL", "1970 09 01 0:00:00", "S",
1684            "LLLLL", "1970 10 01 0:00:00", "O",
1685            "LLLLL", "1970 11 01 0:00:00", "N",
1686            "LLLLL", "1970 12 01 0:00:00", "D",
1687
1688            "EEEEE", "1970 01 04 0:00:00", "S",
1689            "EEEEE", "1970 01 05 0:00:00", "M",
1690            "EEEEE", "1970 01 06 0:00:00", "T",
1691            "EEEEE", "1970 01 07 0:00:00", "W",
1692            "EEEEE", "1970 01 01 0:00:00", "T",
1693            "EEEEE", "1970 01 02 0:00:00", "F",
1694            "EEEEE", "1970 01 03 0:00:00", "S",
1695
1696            "ccccc", "1970 01 04 0:00:00", "S",
1697            "ccccc", "1970 01 05 0:00:00", "M",
1698            "ccccc", "1970 01 06 0:00:00", "T",
1699            "ccccc", "1970 01 07 0:00:00", "W",
1700            "ccccc", "1970 01 01 0:00:00", "T",
1701            "ccccc", "1970 01 02 0:00:00", "F",
1702            "ccccc", "1970 01 03 0:00:00", "S",
1703        };
1704
1705        const char *CS_DATA[] = {
1706            "yyyy MM dd HH:mm:ss",
1707
1708            "yyyy LLLLL dd H:mm:ss", "2004 04 10 16:36:31", "2004 d 10 16:36:31",
1709            "yyyy MMMMM dd H:mm:ss", "2004 04 10 16:36:31", "2004 4 10 16:36:31",
1710
1711            "MMMMM", "1970 01 01 0:00:00", "1",
1712            "MMMMM", "1970 02 01 0:00:00", "2",
1713            "MMMMM", "1970 03 01 0:00:00", "3",
1714            "MMMMM", "1970 04 01 0:00:00", "4",
1715            "MMMMM", "1970 05 01 0:00:00", "5",
1716            "MMMMM", "1970 06 01 0:00:00", "6",
1717            "MMMMM", "1970 07 01 0:00:00", "7",
1718            "MMMMM", "1970 08 01 0:00:00", "8",
1719            "MMMMM", "1970 09 01 0:00:00", "9",
1720            "MMMMM", "1970 10 01 0:00:00", "10",
1721            "MMMMM", "1970 11 01 0:00:00", "11",
1722            "MMMMM", "1970 12 01 0:00:00", "12",
1723
1724            "LLLLL", "1970 01 01 0:00:00", "l",
1725            "LLLLL", "1970 02 01 0:00:00", "\\u00FA",
1726            "LLLLL", "1970 03 01 0:00:00", "b",
1727            "LLLLL", "1970 04 01 0:00:00", "d",
1728            "LLLLL", "1970 05 01 0:00:00", "k",
1729            "LLLLL", "1970 06 01 0:00:00", "\\u010D",
1730            "LLLLL", "1970 07 01 0:00:00", "\\u010D",
1731            "LLLLL", "1970 08 01 0:00:00", "s",
1732            "LLLLL", "1970 09 01 0:00:00", "z",
1733            "LLLLL", "1970 10 01 0:00:00", "\\u0159",
1734            "LLLLL", "1970 11 01 0:00:00", "l",
1735            "LLLLL", "1970 12 01 0:00:00", "p",
1736
1737            "EEEEE", "1970 01 04 0:00:00", "N",
1738            "EEEEE", "1970 01 05 0:00:00", "P",
1739            "EEEEE", "1970 01 06 0:00:00", "\\u00DA",
1740            "EEEEE", "1970 01 07 0:00:00", "S",
1741            "EEEEE", "1970 01 01 0:00:00", "\\u010C",
1742            "EEEEE", "1970 01 02 0:00:00", "P",
1743            "EEEEE", "1970 01 03 0:00:00", "S",
1744
1745            "ccccc", "1970 01 04 0:00:00", "N",
1746            "ccccc", "1970 01 05 0:00:00", "P",
1747            "ccccc", "1970 01 06 0:00:00", "\\u00DA",
1748            "ccccc", "1970 01 07 0:00:00", "S",
1749            "ccccc", "1970 01 01 0:00:00", "\\u010C",
1750            "ccccc", "1970 01 02 0:00:00", "P",
1751            "ccccc", "1970 01 03 0:00:00", "S",
1752        };
1753
1754      expectFormat(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
1755      expectFormat(CS_DATA, ARRAY_SIZE(CS_DATA), Locale("cs", "", ""));
1756}
1757
1758void DateFormatTest::TestEras()
1759{
1760    const char *EN_DATA[] = {
1761        "yyyy MM dd",
1762
1763        "MMMM dd yyyy G",    "fp", "1951 07 17", "July 17 1951 AD",          "1951 07 17",
1764        "MMMM dd yyyy GG",   "fp", "1951 07 17", "July 17 1951 AD",          "1951 07 17",
1765        "MMMM dd yyyy GGG",  "fp", "1951 07 17", "July 17 1951 AD",          "1951 07 17",
1766        "MMMM dd yyyy GGGG", "fp", "1951 07 17", "July 17 1951 Anno Domini", "1951 07 17",
1767
1768        "MMMM dd yyyy G",    "fp", "-438 07 17", "July 17 0439 BC",            "-438 07 17",
1769        "MMMM dd yyyy GG",   "fp", "-438 07 17", "July 17 0439 BC",            "-438 07 17",
1770        "MMMM dd yyyy GGG",  "fp", "-438 07 17", "July 17 0439 BC",            "-438 07 17",
1771        "MMMM dd yyyy GGGG", "fp", "-438 07 17", "July 17 0439 Before Christ", "-438 07 17",
1772    };
1773
1774    expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
1775}
1776
1777void DateFormatTest::TestQuarters()
1778{
1779    const char *EN_DATA[] = {
1780        "yyyy MM dd",
1781
1782        "Q",    "fp", "1970 01 01", "1",           "1970 01 01",
1783        "QQ",   "fp", "1970 04 01", "02",          "1970 04 01",
1784        "QQQ",  "fp", "1970 07 01", "Q3",          "1970 07 01",
1785        "QQQQ", "fp", "1970 10 01", "4th quarter", "1970 10 01",
1786
1787        "q",    "fp", "1970 01 01", "1",           "1970 01 01",
1788        "qq",   "fp", "1970 04 01", "02",          "1970 04 01",
1789        "qqq",  "fp", "1970 07 01", "Q3",          "1970 07 01",
1790        "qqqq", "fp", "1970 10 01", "4th quarter", "1970 10 01",
1791    };
1792
1793    expect(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
1794}
1795
1796/**
1797 * Test parsing.  Input is an array that starts with the following
1798 * header:
1799 *
1800 * [0]   = pattern string to parse [i+2] with
1801 *
1802 * followed by test cases, each of which is 3 array elements:
1803 *
1804 * [i]   = pattern, or NULL to reuse prior pattern
1805 * [i+1] = input string
1806 * [i+2] = expected parse result (parsed with pattern [0])
1807 *
1808 * If expect parse failure, then [i+2] should be NULL.
1809 */
1810void DateFormatTest::expectParse(const char** data, int32_t data_length,
1811                                 const Locale& loc) {
1812    const UDate FAIL = (UDate) -1;
1813    const UnicodeString FAIL_STR("parse failure");
1814    int32_t i = 0;
1815
1816    UErrorCode ec = U_ZERO_ERROR;
1817    SimpleDateFormat fmt("", loc, ec);
1818    SimpleDateFormat ref(data[i++], loc, ec);
1819    SimpleDateFormat gotfmt("G yyyy MM dd HH:mm:ss z", loc, ec);
1820    if (U_FAILURE(ec)) {
1821        dataerrln("FAIL: SimpleDateFormat constructor - %s", u_errorName(ec));
1822        return;
1823    }
1824
1825    const char* currentPat = NULL;
1826    while (i<data_length) {
1827        const char* pattern  = data[i++];
1828        const char* input    = data[i++];
1829        const char* expected = data[i++];
1830
1831        ec = U_ZERO_ERROR;
1832        if (pattern != NULL) {
1833            fmt.applyPattern(pattern);
1834            currentPat = pattern;
1835        }
1836        UDate got = fmt.parse(input, ec);
1837        UnicodeString gotstr(FAIL_STR);
1838        if (U_FAILURE(ec)) {
1839            got = FAIL;
1840        } else {
1841            gotstr.remove();
1842            gotfmt.format(got, gotstr);
1843        }
1844
1845        UErrorCode ec2 = U_ZERO_ERROR;
1846        UDate exp = FAIL;
1847        UnicodeString expstr(FAIL_STR);
1848        if (expected != NULL) {
1849            expstr = expected;
1850            exp = ref.parse(expstr, ec2);
1851            if (U_FAILURE(ec2)) {
1852                // This only happens if expected is in wrong format --
1853                // should never happen once test is debugged.
1854                errln("FAIL: Internal test error");
1855                return;
1856            }
1857        }
1858
1859        if (got == exp) {
1860            logln((UnicodeString)"Ok: " + input + " x " +
1861                  currentPat + " => " + gotstr);
1862        } else {
1863            errln((UnicodeString)"FAIL: " + input + " x " +
1864                  currentPat + " => " + gotstr + ", expected " +
1865                  expstr);
1866        }
1867    }
1868}
1869
1870/**
1871 * Test formatting and parsing.  Input is an array that starts
1872 * with the following header:
1873 *
1874 * [0]   = pattern string to parse [i+2] with
1875 *
1876 * followed by test cases, each of which is 3 array elements:
1877 *
1878 * [i]   = pattern, or null to reuse prior pattern
1879 * [i+1] = control string, either "fp", "pf", or "F".
1880 * [i+2..] = data strings
1881 *
1882 * The number of data strings depends on the control string.
1883 * Examples:
1884 * 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",
1885 * 'f': Format date [i+2] (as parsed using pattern [0]) and expect string [i+3].
1886 * 'p': Parse string [i+3] and expect date [i+4].
1887 *
1888 * 2. "y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567"
1889 * 'F': Format date [i+2] and expect string [i+3],
1890 *      then parse string [i+3] and expect date [i+2].
1891 *
1892 * 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",
1893 * 'p': Parse string [i+2] and expect date [i+3].
1894 * 'f': Format date [i+3] and expect string [i+4].
1895 */
1896void DateFormatTest::expect(const char** data, int32_t data_length,
1897                            const Locale& loc) {
1898    int32_t i = 0;
1899    UErrorCode ec = U_ZERO_ERROR;
1900    UnicodeString str, str2;
1901    SimpleDateFormat fmt("", loc, ec);
1902    SimpleDateFormat ref(data[i++], loc, ec);
1903    SimpleDateFormat univ("EE G yyyy MM dd HH:mm:ss.SSS z", loc, ec);
1904    if (U_FAILURE(ec)) {
1905        dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(ec));
1906        return;
1907    }
1908
1909    UnicodeString currentPat;
1910    while (i<data_length) {
1911        const char* pattern  = data[i++];
1912        if (pattern != NULL) {
1913            fmt.applyPattern(pattern);
1914            currentPat = pattern;
1915        }
1916
1917        const char* control = data[i++];
1918
1919        if (uprv_strcmp(control, "fp") == 0) {
1920            // 'f'
1921            const char* datestr = data[i++];
1922            const char* string = data[i++];
1923            UDate date = ref.parse(ctou(datestr), ec);
1924            if (!assertSuccess("parse", ec)) return;
1925            assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
1926                         ctou(string),
1927                         fmt.format(date, str.remove()));
1928            // 'p'
1929            datestr = data[i++];
1930            date = ref.parse(ctou(datestr), ec);
1931            if (!assertSuccess("parse", ec)) return;
1932            UDate parsedate = fmt.parse(ctou(string), ec);
1933            if (assertSuccess((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")", ec)) {
1934                assertEquals((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")",
1935                             univ.format(date, str.remove()),
1936                             univ.format(parsedate, str2.remove()));
1937            }
1938        }
1939
1940        else if (uprv_strcmp(control, "pf") == 0) {
1941            // 'p'
1942            const char* string = data[i++];
1943            const char* datestr = data[i++];
1944            UDate date = ref.parse(ctou(datestr), ec);
1945            if (!assertSuccess("parse", ec)) return;
1946            UDate parsedate = fmt.parse(ctou(string), ec);
1947            if (assertSuccess((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")", ec)) {
1948                assertEquals((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")",
1949                             univ.format(date, str.remove()),
1950                             univ.format(parsedate, str2.remove()));
1951            }
1952            // 'f'
1953            string = data[i++];
1954            assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
1955                         ctou(string),
1956                         fmt.format(date, str.remove()));
1957        }
1958
1959        else if (uprv_strcmp(control, "F") == 0) {
1960            const char* datestr  = data[i++];
1961            const char* string   = data[i++];
1962            UDate date = ref.parse(ctou(datestr), ec);
1963            if (!assertSuccess("parse", ec)) return;
1964            assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
1965                         ctou(string),
1966                         fmt.format(date, str.remove()));
1967
1968            UDate parsedate = fmt.parse(string, ec);
1969            if (assertSuccess((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")", ec)) {
1970                assertEquals((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")",
1971                             univ.format(date, str.remove()),
1972                             univ.format(parsedate, str2.remove()));
1973            }
1974        }
1975
1976        else {
1977            errln((UnicodeString)"FAIL: Invalid control string " + control);
1978            return;
1979        }
1980    }
1981}
1982
1983/**
1984 * Test formatting.  Input is an array that starts
1985 * with the following header:
1986 *
1987 * [0]   = pattern string to parse [i+2] with
1988 *
1989 * followed by test cases, each of which is 3 array elements:
1990 *
1991 * [i]   = pattern, or null to reuse prior pattern
1992 * [i+1] = data string a
1993 * [i+2] = data string b
1994 *
1995 * Examples:
1996 * Format date [i+1] and expect string [i+2].
1997 *
1998 * "y/M/d H:mm:ss.SSSS", "2004/3/10 16:36:31.5679", "2004 03 10 16:36:31.567"
1999 */
2000void DateFormatTest::expectFormat(const char** data, int32_t data_length,
2001                            const Locale& loc) {
2002    int32_t i = 0;
2003    UErrorCode ec = U_ZERO_ERROR;
2004    UnicodeString str, str2;
2005    SimpleDateFormat fmt("", loc, ec);
2006    SimpleDateFormat ref(data[i++], loc, ec);
2007    SimpleDateFormat univ("EE G yyyy MM dd HH:mm:ss.SSS z", loc, ec);
2008    if (U_FAILURE(ec)) {
2009        dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(ec));
2010        return;
2011    }
2012
2013    UnicodeString currentPat;
2014
2015    while (i<data_length) {
2016        const char* pattern  = data[i++];
2017        if (pattern != NULL) {
2018            fmt.applyPattern(pattern);
2019            currentPat = pattern;
2020        }
2021
2022        const char* datestr = data[i++];
2023        const char* string = data[i++];
2024        UDate date = ref.parse(ctou(datestr), ec);
2025        if (!assertSuccess("parse", ec)) return;
2026        assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
2027                        ctou(string),
2028                        fmt.format(date, str.remove()));
2029    }
2030}
2031
2032void DateFormatTest::TestGenericTime() {
2033  const Locale en("en");
2034  // Note: We no longer parse strings in different styles.
2035/*
2036  const char* ZDATA[] = {
2037        "yyyy MM dd HH:mm zzz",
2038        // round trip
2039        "y/M/d H:mm zzzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Standard Time",
2040        "y/M/d H:mm zzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
2041        "y/M/d H:mm vvvv", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
2042        "y/M/d H:mm v", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PT",
2043        // non-generic timezone string influences dst offset even if wrong for date/time
2044        "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",
2045        "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",
2046        "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",
2047        "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",
2048        // generic timezone generates dst offset appropriate for local time
2049        "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",
2050        "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",
2051        "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",
2052        "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",
2053        // daylight savings time transition edge cases.
2054        // time to parse does not really exist, PT interpreted as earlier time
2055        "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",
2056        "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",
2057        "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",
2058        "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",
2059        "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",
2060        "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",
2061        "y/M/d H:mm", "pf", "2005/4/3 2:30", "2005 04 03 03:30 PDT", "2005/4/3 3:30",
2062        // time to parse is ambiguous, PT interpreted as later time
2063        "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",
2064        "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",
2065        "y/M/d H:mm", "pf", "2005/10/30 1:30 PT", "2005 10 30 01:30 PST", "2005/10/30 1:30",
2066
2067        "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",
2068        "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",
2069        "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",
2070        "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",
2071        "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",
2072        "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",
2073        "y/M/d H:mm", "pf", "2004/10/31 1:30", "2004 10 31 01:30 PST", "2004/10/31 1:30",
2074  };
2075*/
2076  const char* ZDATA[] = {
2077        "yyyy MM dd HH:mm zzz",
2078        // round trip
2079        "y/M/d H:mm zzzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Standard Time",
2080        "y/M/d H:mm zzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
2081        "y/M/d H:mm vvvv", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
2082        "y/M/d H:mm v", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PT",
2083        // non-generic timezone string influences dst offset even if wrong for date/time
2084        "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",
2085        "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",
2086        // generic timezone generates dst offset appropriate for local time
2087        "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",
2088        "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",
2089        "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",
2090        "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",
2091        // daylight savings time transition edge cases.
2092        // time to parse does not really exist, PT interpreted as earlier time
2093        "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",
2094        "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",
2095        "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",
2096        "y/M/d H:mm", "pf", "2005/4/3 2:30", "2005 04 03 03:30 PDT", "2005/4/3 3:30",
2097        // time to parse is ambiguous, PT interpreted as later time
2098        "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",
2099        "y/M/d H:mm", "pf", "2005/10/30 1:30 PT", "2005 10 30 01:30 PST", "2005/10/30 1:30",
2100
2101        "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",
2102        "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",
2103        "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",
2104        "y/M/d H:mm", "pf", "2004/10/31 1:30", "2004 10 31 01:30 PST", "2004/10/31 1:30",
2105  };
2106
2107  const int32_t ZDATA_length = sizeof(ZDATA)/ sizeof(ZDATA[0]);
2108  expect(ZDATA, ZDATA_length, en);
2109
2110  UErrorCode status = U_ZERO_ERROR;
2111
2112  logln("cross format/parse tests");    // Note: We no longer support cross format/parse
2113  UnicodeString basepat("yy/MM/dd H:mm ");
2114  SimpleDateFormat formats[] = {
2115    SimpleDateFormat(basepat + "vvv", en, status),
2116    SimpleDateFormat(basepat + "vvvv", en, status),
2117    SimpleDateFormat(basepat + "zzz", en, status),
2118    SimpleDateFormat(basepat + "zzzz", en, status)
2119  };
2120  if (U_FAILURE(status)) {
2121    dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(status));
2122    return;
2123  }
2124  const int32_t formats_length = sizeof(formats)/sizeof(formats[0]);
2125
2126  UnicodeString test;
2127  SimpleDateFormat univ("yyyy MM dd HH:mm zzz", en, status);
2128  ASSERT_OK(status);
2129  const UnicodeString times[] = {
2130    "2004 01 02 03:04 PST",
2131    "2004 07 08 09:10 PDT"
2132  };
2133  int32_t times_length = sizeof(times)/sizeof(times[0]);
2134  for (int i = 0; i < times_length; ++i) {
2135    UDate d = univ.parse(times[i], status);
2136    logln(UnicodeString("\ntime: ") + d);
2137    for (int j = 0; j < formats_length; ++j) {
2138      test.remove();
2139      formats[j].format(d, test);
2140      logln("\ntest: '" + test + "'");
2141      for (int k = 0; k < formats_length; ++k) {
2142        UDate t = formats[k].parse(test, status);
2143        if (U_SUCCESS(status)) {
2144          if (d != t) {
2145            errln((UnicodeString)"FAIL: format " + k +
2146                  " incorrectly parsed output of format " + j +
2147                  " (" + test + "), returned " +
2148                  dateToString(t) + " instead of " + dateToString(d));
2149          } else {
2150            logln((UnicodeString)"OK: format " + k + " parsed ok");
2151          }
2152        } else if (status == U_PARSE_ERROR) {
2153          errln((UnicodeString)"FAIL: format " + k +
2154                " could not parse output of format " + j +
2155                " (" + test + ")");
2156        }
2157      }
2158    }
2159  }
2160}
2161
2162void DateFormatTest::TestGenericTimeZoneOrder() {
2163  // generic times should parse the same no matter what the placement of the time zone string
2164
2165  // Note: We no longer support cross style format/parse
2166
2167  //const char* XDATA[] = {
2168  //  "yyyy MM dd HH:mm zzz",
2169  //  // standard time, explicit daylight/standard
2170  //  "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",
2171  //  "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",
2172  //  "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",
2173
2174  //  // standard time, generic
2175  //  "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",
2176  //  "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",
2177  //  "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",
2178
2179  //  // dahylight time, explicit daylight/standard
2180  //  "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",
2181  //  "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",
2182  //  "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",
2183
2184  //  // daylight time, generic
2185  //  "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",
2186  //  "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",
2187  //  "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",
2188  //};
2189  const char* XDATA[] = {
2190    "yyyy MM dd HH:mm zzz",
2191    // standard time, explicit daylight/standard
2192    "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",
2193    "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",
2194    "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",
2195
2196    // standard time, generic
2197    "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",
2198    "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",
2199    "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",
2200
2201    // dahylight time, explicit daylight/standard
2202    "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",
2203    "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",
2204    "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",
2205
2206    // daylight time, generic
2207    "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",
2208    "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",
2209    "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",
2210  };
2211  const int32_t XDATA_length = sizeof(XDATA)/sizeof(XDATA[0]);
2212  Locale en("en");
2213  expect(XDATA, XDATA_length, en);
2214}
2215
2216void DateFormatTest::TestZTimeZoneParsing(void) {
2217    UErrorCode status = U_ZERO_ERROR;
2218    const Locale en("en");
2219    UnicodeString test;
2220    //SimpleDateFormat univ("yyyy-MM-dd'T'HH:mm Z", en, status);
2221    SimpleDateFormat univ("HH:mm Z", en, status);
2222    if (failure(status, "construct SimpleDateFormat", TRUE)) return;
2223    const TimeZone *t = TimeZone::getGMT();
2224    univ.setTimeZone(*t);
2225
2226    univ.setLenient(false);
2227    ParsePosition pp(0);
2228    struct {
2229        UnicodeString input;
2230        UnicodeString expected_result;
2231    } tests[] = {
2232        { "11:00 -0200", "13:00 +0000" },
2233        { "11:00 +0200", "09:00 +0000" },
2234        { "11:00 +0400", "07:00 +0000" },
2235        { "11:00 +0530", "05:30 +0000" }
2236    };
2237
2238    UnicodeString result;
2239    int32_t tests_length = sizeof(tests)/sizeof(tests[0]);
2240    for (int i = 0; i < tests_length; ++i) {
2241        pp.setIndex(0);
2242        UDate d = univ.parse(tests[i].input, pp);
2243        if(pp.getIndex() != tests[i].input.length()){
2244            errln("Test %i: setZoneString() did not succeed. Consumed: %i instead of %i",
2245                  i, pp.getIndex(), tests[i].input.length());
2246            return;
2247        }
2248        result.remove();
2249        univ.format(d, result);
2250        if(result != tests[i].expected_result) {
2251            errln("Expected " + tests[i].expected_result
2252                  + " got " + result);
2253            return;
2254        }
2255        logln("SUCCESS: Parsed " + tests[i].input
2256              + " got " + result
2257              + " expected " + tests[i].expected_result);
2258    }
2259}
2260
2261void DateFormatTest::TestHost(void)
2262{
2263#if U_PLATFORM_HAS_WIN32_API
2264    Win32DateTimeTest::testLocales(this);
2265#endif
2266}
2267
2268// Relative Date Tests
2269
2270void DateFormatTest::TestRelative(int daysdelta,
2271                                  const Locale& loc,
2272                                  const char *expectChars) {
2273    char banner[25];
2274    sprintf(banner, "%d", daysdelta);
2275    UnicodeString bannerStr(banner, "");
2276
2277    UErrorCode status = U_ZERO_ERROR;
2278
2279    FieldPosition pos(0);
2280    UnicodeString test;
2281    Locale en("en");
2282    DateFormat *fullrelative = DateFormat::createDateInstance(DateFormat::kFullRelative, loc);
2283
2284    if (fullrelative == NULL) {
2285        dataerrln("DateFormat::createDateInstance(DateFormat::kFullRelative, %s) returned NULL", loc.getName());
2286        return;
2287    }
2288
2289    DateFormat *full         = DateFormat::createDateInstance(DateFormat::kFull        , loc);
2290
2291    if (full == NULL) {
2292        errln("DateFormat::createDateInstance(DateFormat::kFull, %s) returned NULL", loc.getName());
2293        return;
2294    }
2295
2296    DateFormat *en_full =         DateFormat::createDateInstance(DateFormat::kFull,         en);
2297
2298    if (en_full == NULL) {
2299        errln("DateFormat::createDateInstance(DateFormat::kFull, en) returned NULL");
2300        return;
2301    }
2302
2303    DateFormat *en_fulltime =         DateFormat::createDateTimeInstance(DateFormat::kFull,DateFormat::kFull,en);
2304
2305    if (en_fulltime == NULL) {
2306        errln("DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, en) returned NULL");
2307        return;
2308    }
2309
2310    UnicodeString result;
2311    UnicodeString normalResult;
2312    UnicodeString expect;
2313    UnicodeString parseResult;
2314
2315    Calendar *c = Calendar::createInstance(status);
2316
2317    // Today = Today
2318    c->setTime(Calendar::getNow(), status);
2319    if(daysdelta != 0) {
2320        c->add(Calendar::DATE,daysdelta,status);
2321    }
2322    ASSERT_OK(status);
2323
2324    // calculate the expected string
2325    if(expectChars != NULL) {
2326        expect = expectChars;
2327    } else {
2328        full->format(*c, expect, pos); // expected = normal full
2329    }
2330
2331    fullrelative   ->format(*c, result, pos);
2332    en_full        ->format(*c, normalResult, pos);
2333
2334    if(result != expect) {
2335        errln("FAIL: Relative Format ["+bannerStr+"] of "+normalResult+" failed, expected "+expect+" but got " + result);
2336    } else {
2337        logln("PASS: Relative Format ["+bannerStr+"] of "+normalResult+" got " + result);
2338    }
2339
2340
2341    //verify
2342    UDate d = fullrelative->parse(result, status);
2343    ASSERT_OK(status);
2344
2345    UnicodeString parseFormat; // parse rel->format full
2346    en_full->format(d, parseFormat, status);
2347
2348    UnicodeString origFormat;
2349    en_full->format(*c, origFormat, pos);
2350
2351    if(parseFormat!=origFormat) {
2352        errln("FAIL: Relative Parse ["+bannerStr+"] of "+result+" failed, expected "+parseFormat+" but got "+origFormat);
2353    } else {
2354        logln("PASS: Relative Parse ["+bannerStr+"] of "+result+" passed, got "+parseFormat);
2355    }
2356
2357    delete full;
2358    delete fullrelative;
2359    delete en_fulltime;
2360    delete en_full;
2361    delete c;
2362}
2363
2364
2365void DateFormatTest::TestRelative(void)
2366{
2367    Locale en("en");
2368    TestRelative( 0, en, "Today");
2369    TestRelative(-1, en, "Yesterday");
2370    TestRelative( 1, en, "Tomorrow");
2371    TestRelative( 2, en, NULL);
2372    TestRelative( -2, en, NULL);
2373    TestRelative( 3, en, NULL);
2374    TestRelative( -3, en, NULL);
2375    TestRelative( 300, en, NULL);
2376    TestRelative( -300, en, NULL);
2377}
2378
2379void DateFormatTest::TestRelativeClone(void)
2380{
2381    /*
2382    Verify that a cloned formatter gives the same results
2383    and is useable after the original has been deleted.
2384    */
2385    UErrorCode status = U_ZERO_ERROR;
2386    Locale loc("en");
2387    UDate now = Calendar::getNow();
2388    DateFormat *full = DateFormat::createDateInstance(DateFormat::kFullRelative, loc);
2389    if (full == NULL) {
2390        dataerrln("FAIL: Can't create Relative date instance");
2391        return;
2392    }
2393    UnicodeString result1;
2394    full->format(now, result1, status);
2395    Format *fullClone = full->clone();
2396    delete full;
2397    full = NULL;
2398
2399    UnicodeString result2;
2400    fullClone->format(now, result2, status);
2401    ASSERT_OK(status);
2402    if (result1 != result2) {
2403        errln("FAIL: Clone returned different result from non-clone.");
2404    }
2405    delete fullClone;
2406}
2407
2408void DateFormatTest::TestHostClone(void)
2409{
2410    /*
2411    Verify that a cloned formatter gives the same results
2412    and is useable after the original has been deleted.
2413    */
2414    // This is mainly important on Windows.
2415    UErrorCode status = U_ZERO_ERROR;
2416    Locale loc("en_US@compat=host");
2417    UDate now = Calendar::getNow();
2418    DateFormat *full = DateFormat::createDateInstance(DateFormat::kFull, loc);
2419    if (full == NULL) {
2420        dataerrln("FAIL: Can't create Relative date instance");
2421        return;
2422    }
2423    UnicodeString result1;
2424    full->format(now, result1, status);
2425    Format *fullClone = full->clone();
2426    delete full;
2427    full = NULL;
2428
2429    UnicodeString result2;
2430    fullClone->format(now, result2, status);
2431    ASSERT_OK(status);
2432    if (result1 != result2) {
2433        errln("FAIL: Clone returned different result from non-clone.");
2434    }
2435    delete fullClone;
2436}
2437
2438void DateFormatTest::TestTimeZoneDisplayName()
2439{
2440    // This test data was ported from ICU4J.  Don't know why the 6th column in there because it's not being
2441    // used currently.
2442    const char *fallbackTests[][6]  = {
2443        { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
2444        { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
2445        { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZZ", "-08:00", "-8:00" },
2446        { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "PST", "America/Los_Angeles" },
2447        { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "Pacific Standard Time", "America/Los_Angeles" },
2448        { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
2449        { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
2450        { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "PDT", "America/Los_Angeles" },
2451        { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "Pacific Daylight Time", "America/Los_Angeles" },
2452        { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "PT", "America/Los_Angeles" },
2453        { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Pacific Time", "America/Los_Angeles" },
2454        { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "Los Angeles Time", "America/Los_Angeles" },
2455        { "en_GB", "America/Los_Angeles", "2004-01-15T12:00:00Z", "z", "GMT-8", "America/Los_Angeles" },
2456        { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "Z", "-0700", "-7:00" },
2457        { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
2458        { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "z", "MST", "America/Phoenix" },
2459        { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "zzzz", "Mountain Standard Time", "America/Phoenix" },
2460        { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
2461        { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
2462        { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "z", "MST", "America/Phoenix" },
2463        { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "zzzz", "Mountain Standard Time", "America/Phoenix" },
2464        { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "v", "MST", "America/Phoenix" },
2465        { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "vvvv", "Mountain Standard Time", "America/Phoenix" },
2466        { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "VVVV", "Phoenix Time", "America/Phoenix" },
2467
2468        { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2469        { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2470        { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2471        { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" },
2472        { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2473        { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2474        { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2475        { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" },
2476        { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Time", "America/Buenos_Aires" },
2477        { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentina Standard Time", "America/Buenos_Aires" },
2478        { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "VVVV", "Buenos Aires Time", "America/Buenos_Aires" },
2479
2480        { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2481        { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2482        { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2483        { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" },
2484        { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2485        { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2486        { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2487        { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" },
2488        { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Time", "America/Buenos_Aires" },
2489        { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentina Standard Time", "America/Buenos_Aires" },
2490        { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "VVVV", "Buenos Aires Time", "America/Buenos_Aires" },
2491
2492        { "en", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
2493        { "en", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
2494        { "en", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
2495        { "en", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "Cuba Standard Time", "-5:00" },
2496        { "en", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
2497        { "en", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
2498        { "en", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
2499        { "en", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "Cuba Daylight Time", "-4:00" },
2500        { "en", "America/Havana", "2004-07-15T00:00:00Z", "v", "Cuba Time", "America/Havana" },
2501        { "en", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Cuba Time", "America/Havana" },
2502        { "en", "America/Havana", "2004-07-15T00:00:00Z", "VVVV", "Cuba Time", "America/Havana" },
2503
2504        { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2505        { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
2506        { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2507        { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "Australian Eastern Daylight Time", "+11:00" },
2508        { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2509        { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
2510        { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2511        { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "Australian Eastern Standard Time", "+10:00" },
2512        { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Sydney Time", "Australia/Sydney" },
2513        { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Eastern Australia Time", "Australia/Sydney" },
2514        { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "VVVV", "Sydney Time", "Australia/Sydney" },
2515
2516        { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2517        { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
2518        { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2519        { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "Australian Eastern Daylight Time", "+11:00" },
2520        { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2521        { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
2522        { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2523        { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "Australian Eastern Standard Time", "+10:00" },
2524        { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Sydney Time", "Australia/Sydney" },
2525        { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Eastern Australia Time", "Australia/Sydney" },
2526        { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "VVVV", "Sydney Time", "Australia/Sydney" },
2527
2528        { "en", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
2529        { "en", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
2530        { "en", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
2531        { "en", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "Greenwich Mean Time", "+0:00" },
2532        { "en", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
2533        { "en", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
2534        { "en", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "Europe/London" },
2535        { "en", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "British Summer Time", "Europe/London" },
2536    // icu en.txt has exemplar city for this time zone
2537        { "en", "Europe/London", "2004-07-15T00:00:00Z", "v", "United Kingdom Time", "Europe/London" },
2538        { "en", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "United Kingdom Time", "Europe/London" },
2539        { "en", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "United Kingdom Time", "Europe/London" },
2540
2541        { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2542        { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2543        { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2544        { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
2545        { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2546        { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2547        { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2548        { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
2549        { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
2550        { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
2551
2552        // JB#5150
2553        { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
2554        { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
2555        { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
2556        { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "India Standard Time", "+5:30" },
2557        { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
2558        { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
2559        { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
2560        { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "India Standard Time", "+5:30" },
2561        { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "India Time", "Asia/Calcutta" },
2562        { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "India Standard Time", "Asia/Calcutta" },
2563
2564        // Proper CLDR primary zone support #9733
2565        { "en", "Asia/Shanghai", "2013-01-01T00:00:00Z", "VVVV", "China Time", "Asia/Shanghai" },
2566        { "en", "Asia/Harbin", "2013-01-01T00:00:00Z", "VVVV", "Harbin Time", "Asia/Harbin" },
2567
2568        // ==========
2569
2570        { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
2571        { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
2572        // BEGIN android-change
2573        { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "PST", "-8:00" },
2574        { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "Nordamerikanische Westk\\u00fcsten-Normalzeit", "-8:00" },
2575        { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
2576        { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
2577        { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "PDT", "-7:00" },
2578        { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "Nordamerikanische Westk\\u00fcsten-Sommerzeit", "-7:00" },
2579        { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "PT", "America/Los_Angeles" },
2580        { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Nordamerikanische Westk\\u00fcstenzeit", "America/Los_Angeles" },
2581        // END android-change
2582
2583        { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2584        { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2585        { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2586        { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" },
2587        { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2588        { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2589        { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2590        { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" },
2591        { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Zeit", "America/Buenos_Aires" },
2592        { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentinische Normalzeit", "America/Buenos_Aires" },
2593
2594        { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2595        { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2596        { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2597        { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" },
2598        { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2599        { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2600        { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2601        { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" },
2602        { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Zeit", "America/Buenos_Aires" },
2603        { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentinische Normalzeit", "America/Buenos_Aires" },
2604
2605        { "de", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
2606        { "de", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
2607        { "de", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
2608        { "de", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "Kubanische Normalzeit", "-5:00" },
2609        { "de", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
2610        { "de", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
2611        { "de", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
2612        { "de", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "Kubanische Sommerzeit", "-4:00" },
2613        { "de", "America/Havana", "2004-07-15T00:00:00Z", "v", "Kuba Zeit", "America/Havana" },
2614        { "de", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Kubanische Zeit", "America/Havana" },
2615        // added to test proper fallback of country name
2616        { "de_CH", "America/Havana", "2004-07-15T00:00:00Z", "v", "Kuba Zeit", "America/Havana" },
2617        { "de_CH", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Kubanische Zeit", "America/Havana" },
2618
2619        { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2620        { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
2621        { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2622        { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "Ostaustralische Sommerzeit", "+11:00" },
2623        { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2624        { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
2625        { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2626        { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "Ostaustralische Normalzeit", "+10:00" },
2627        { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Sydney Zeit", "Australia/Sydney" },
2628        { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Ostaustralische Zeit", "Australia/Sydney" },
2629
2630        { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2631        { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
2632        { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2633        { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "Ostaustralische Sommerzeit", "+11:00" },
2634        { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2635        { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
2636        { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2637        { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "Ostaustralische Normalzeit", "+10:00" },
2638        { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Sydney Zeit", "Australia/Sydney" },
2639        { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Ostaustralische Zeit", "Australia/Sydney" },
2640
2641        { "de", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
2642        { "de", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
2643        { "de", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
2644        { "de", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "Mittlere Greenwich-Zeit", "+0:00" },
2645        { "de", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
2646        { "de", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
2647        { "de", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
2648        { "de", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "Britische Sommerzeit", "+1:00" },
2649        { "de", "Europe/London", "2004-07-15T00:00:00Z", "v", "Vereinigtes K\\u00f6nigreich Zeit", "Europe/London" },
2650        { "de", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "Vereinigtes K\\u00f6nigreich Zeit", "Europe/London" },
2651
2652        { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2653        { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2654        { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2655        { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
2656        { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2657        { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2658        { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2659        { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
2660        { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
2661        { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
2662
2663        // JB#5150
2664        { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
2665        { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
2666        { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
2667        { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "Indische Zeit", "+5:30" },
2668        { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
2669        { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
2670        { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
2671        { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "Indische Zeit", "+5:30" },
2672        { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "Indien Zeit", "Asia/Calcutta" },
2673        { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "Indische Zeit", "Asia/Calcutta" },
2674
2675        // ==========
2676
2677        { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
2678        { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-0800", "-8:00" },
2679        // BEGIN android-change
2680        { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "PST", "America/Los_Angeles" },
2681        { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u6807\\u51c6\\u65f6\\u95f4", "America/Los_Angeles" },
2682        { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
2683        { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-0700", "-7:00" },
2684        { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "PDT", "America/Los_Angeles" },
2685        { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u590f\\u4ee4\\u65f6\\u95f4", "America/Los_Angeles" },
2686    // icu zh.txt has exemplar city for this time zone
2687        { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "PT", "America/Los_Angeles" },
2688        { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u65f6\\u95f4", "America/Los_Angeles" },
2689        // END android-change
2690
2691        { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2692        { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-0300", "-3:00" },
2693        { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2694        { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" },
2695        { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2696        { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-0300", "-3:00" },
2697        { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2698        { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" },
2699        { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u5E03\\u5B9C\\u8BFA\\u65AF\\u827E\\u5229\\u65AF\\u65F6\\u95F4", "America/Buenos_Aires" },
2700        { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "America/Buenos_Aires" },
2701
2702        { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2703        { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-0300", "-3:00" },
2704        { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2705        { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" },
2706        { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2707        { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-0300", "-3:00" },
2708        { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2709        { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" },
2710        { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u5E03\\u5B9C\\u8BFA\\u65AF\\u827E\\u5229\\u65AF\\u65F6\\u95F4", "America/Buenos_Aires" },
2711        { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "America/Buenos_Aires" },
2712
2713        { "zh", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
2714        { "zh", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-0500", "-5:00" },
2715        { "zh", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
2716        { "zh", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u53e4\\u5df4\\u6807\\u51c6\\u65f6\\u95f4", "-5:00" },
2717        { "zh", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
2718        { "zh", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-0400", "-4:00" },
2719        { "zh", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
2720        { "zh", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u53e4\\u5df4\\u590f\\u4ee4\\u65f6\\u95f4", "-4:00" },
2721        { "zh", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u53e4\\u5df4\\u65f6\\u95f4", "America/Havana" },
2722        { "zh", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u53e4\\u5df4\\u65f6\\u95f4", "America/Havana" },
2723
2724        { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2725        { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+1100", "+11:00" },
2726        { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2727        { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u590f\\u4ee4\\u65f6\\u95f4", "+11:00" },
2728        { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2729        { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+1000", "+10:00" },
2730        { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2731        { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u6807\\u51c6\\u65f6\\u95f4", "+10:00" },
2732    // icu zh.txt does not have info for this time zone
2733        { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u6089\\u5C3C\\u65F6\\u95F4", "Australia/Sydney" },
2734        { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u65f6\\u95f4", "Australia/Sydney" },
2735
2736        { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2737        { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+1100", "+11:00" },
2738        { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2739        { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u590f\\u4ee4\\u65f6\\u95f4", "+11:00" },
2740        { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2741        { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+1000", "+10:00" },
2742        { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2743        { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u6807\\u51c6\\u65f6\\u95f4", "+10:00" },
2744        { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u6089\\u5C3C\\u65F6\\u95F4", "Australia/Sydney" },
2745        { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u65f6\\u95f4", "Australia/Sydney" },
2746
2747        { "zh", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
2748        { "zh", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
2749        { "zh", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
2750        { "zh", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
2751        { "zh", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
2752        { "zh", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u683C\\u6797\\u5C3C\\u6CBB\\u6807\\u51C6\\u65F6\\u95F4", "+0:00" },
2753        { "zh", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
2754        { "zh", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+0100", "+1:00" },
2755        { "zh", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
2756        { "zh", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u82f1\\u56fd\\u590f\\u4ee4\\u65f6\\u95f4", "+1:00" },
2757        { "zh", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" },
2758        { "zh", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" },
2759        { "zh", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" },
2760
2761        { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2762        { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-0300", "-3:00" },
2763        { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2764        { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-0300", "-3:00" },
2765        { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2766        { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-0300", "-3:00" },
2767        { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2768        { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-0300", "-3:00" },
2769        { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
2770        { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-0300", "-3:00" },
2771
2772        // JB#5150
2773        { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
2774        { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+0530", "+5:30" },
2775        { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+530", "+5:30" },
2776        { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u5370\\u5ea6\\u65f6\\u95f4", "+5:30" },
2777        { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
2778        { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+0530", "+5:30" },
2779        { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+530", "+05:30" },
2780        { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u5370\\u5ea6\\u65f6\\u95f4", "+5:30" },
2781        { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u5370\\u5ea6\\u65f6\\u95f4", "Asia/Calcutta" },
2782        { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u5370\\u5ea6\\u65f6\\u95f4", "Asia/Calcutta" },
2783
2784        // Proper CLDR primary zone support #9733
2785        { "zh", "Asia/Shanghai", "2013-01-01T00:00:00Z", "VVVV", "\\u4e2d\\u56fd\\u65f6\\u95f4", "Asia/Shanghai" },
2786        { "zh", "Asia/Harbin", "2013-01-01T00:00:00Z", "VVVV", "\\u54c8\\u5c14\\u6ee8\\u65f6\\u95f4", "Asia/Harbin" },
2787
2788        // ==========
2789
2790        { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
2791        { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
2792        // BEGIN android-change
2793        { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "PST", "-8:00" },
2794        { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u092a\\u094d\\u0930\\u0936\\u093e\\u0902\\u0924\\u0020\\u092e\\u093e\\u0928\\u0915\\u0020\\u0938\\u092e\\u092f", "-8:00" },
2795        { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
2796        { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
2797        { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "PDT", "-7:00" },
2798        { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u092A\\u094D\\u0930\\u0936\\u093E\\u0902\\u0924 \\u0926\\u093F\\u0935\\u093E\\u0935\\u0932\\u094B\\u0915 \\u0938\\u092E\\u092F", "-7:00" },
2799        { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "PT", "America/Los_Angeles" },
2800        { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u092A\\u094D\\u0930\\u0936\\u093E\\u0902\\u0924 \\u0938\\u092E\\u092F", "America/Los_Angeles" },
2801        // END android-change
2802
2803        { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2804        { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2805        { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2806        { "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" },
2807        { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2808        { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2809        { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2810        { "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" },
2811        { "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" },
2812        { "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" },
2813
2814        { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2815        { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2816        { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2817        { "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" },
2818        { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2819        { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2820        { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2821        { "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" },
2822        { "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" },
2823        { "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" },
2824
2825        { "hi", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
2826        { "hi", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
2827        { "hi", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
2828        { "hi", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0915\\u093e \\u092e\\u093e\\u0928\\u0915 \\u0938\\u092e\\u092f", "-5:00" },
2829        { "hi", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
2830        { "hi", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
2831        { "hi", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
2832        { "hi", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0915\\u093e \\u0921\\u0947\\u0932\\u093e\\u0907\\u091f \\u091f\\u093e\\u0907\\u092e", "-4:00" },
2833        { "hi", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0938\\u092E\\u092F", "America/Havana" },
2834        { "hi", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0915\\u093e \\u0938\\u092E\\u092F", "America/Havana" },
2835
2836        { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2837        { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
2838        { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2839        { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094D\\u200D\\u091F\\u094D\\u0930\\u0947\\u0932\\u093F\\u092F\\u093E\\u0908 \\u092A\\u0942\\u0930\\u094D\\u0935\\u0940 \\u0926\\u093F\\u0935\\u093E\\u0935\\u0932\\u094B\\u0915 \\u0938\\u092E\\u092F", "+11:00" },
2840        { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2841        { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
2842        { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2843        { "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" },
2844        { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u0938\\u093F\\u0921\\u0928\\u0940 \\u0938\\u092E\\u092F", "Australia/Sydney" },
2845        { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u092A\\u0942\\u0930\\u094D\\u0935\\u0940 \\u0911\\u0938\\u094D\\u091F\\u094D\\u0930\\u0947\\u0932\\u093F\\u092F\\u093E\\u0908 \\u0938\\u092E\\u092F", "Australia/Sydney" },
2846
2847        { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2848        { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
2849        { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2850        { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094D\\u200D\\u091F\\u094D\\u0930\\u0947\\u0932\\u093F\\u092F\\u093E\\u0908 \\u092A\\u0942\\u0930\\u094D\\u0935\\u0940 \\u0926\\u093F\\u0935\\u093E\\u0935\\u0932\\u094B\\u0915 \\u0938\\u092E\\u092F", "+11:00" },
2851        { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2852        { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
2853        { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2854        { "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" },
2855        { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u0938\\u093F\\u0921\\u0928\\u0940 \\u0938\\u092E\\u092F", "Australia/Sydney" },
2856        { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u092A\\u0942\\u0930\\u094D\\u0935\\u0940 \\u0911\\u0938\\u094D\\u091F\\u094D\\u0930\\u0947\\u0932\\u093F\\u092F\\u093E\\u0908 \\u0938\\u092E\\u092F", "Australia/Sydney" },
2857
2858        { "hi", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
2859        { "hi", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
2860        { "hi", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
2861        { "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" },
2862        { "hi", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
2863        { "hi", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
2864        { "hi", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
2865        { "hi", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "GMT+01:00", "+1:00" },
2866        { "hi", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u092C\\u094D\\u0930\\u093F\\u091F\\u0947\\u0928 \\u0938\\u092E\\u092F", "Europe/London" },
2867        { "hi", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u092C\\u094D\\u0930\\u093F\\u091F\\u0947\\u0928 \\u0938\\u092E\\u092F", "Europe/London" },
2868
2869        { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2870        { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2871        { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2872        { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
2873        { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2874        { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2875        { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2876        { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
2877        { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
2878        { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
2879
2880        { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
2881        { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
2882        { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "IST", "+5:30" },
2883        { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u0938\\u092E\\u092F", "+5:30" },
2884        { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
2885        { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
2886        { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "IST", "+05:30" },
2887        { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u0938\\u092E\\u092F", "+5:30" },
2888        { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "IST", "Asia/Calcutta" },
2889        { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u0938\\u092E\\u092F", "Asia/Calcutta" },
2890
2891        // ==========
2892
2893        { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
2894        { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0800", "-8:00" },
2895        // BEGIN android-change
2896        { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "PST", "America/Los_Angeles" },
2897        { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "V", "uslax", "America/Los_Angeles" },
2898        { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u0422\\u0438\\u0445\\u043E\\u043E\\u043A\\u0435\\u0430\\u043D\\u0441\\u043A\\u0430 \\u0447\\u0430\\u0441\\u043E\\u0432\\u0430 \\u0437\\u043E\\u043D\\u0430", "America/Los_Angeles" },
2899        { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
2900        { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0700", "-7:00" },
2901        { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "PDT", "America/Los_Angeles" },
2902        { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "V", "uslax", "America/Los_Angeles" },
2903        { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u0422\\u0438\\u0445\\u043E\\u043E\\u043A\\u0435\\u0430\\u043D\\u0441\\u043A\\u0430 \\u043B\\u044F\\u0442\\u043D\\u0430 \\u0447\\u0430\\u0441\\u043E\\u0432\\u0430 \\u0437\\u043E\\u043D\\u0430", "America/Los_Angeles" },
2904    // icu bg.txt has exemplar city for this time zone
2905        { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "PT", "America/Los_Angeles" },
2906        { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u0422\\u0438\\u0445\\u043E\\u043E\\u043A\\u0435\\u0430\\u043D\\u0441\\u043A\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Los_Angeles" },
2907        { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "\\u041B\\u043E\\u0441 \\u0410\\u043D\\u0436\\u0435\\u043B\\u0438\\u0441 \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Los_Angeles" },
2908        // END android-change
2909
2910        { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2911        { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" },
2912        { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
2913        { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0430 \\u2013 \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" },
2914        { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2915        { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" },
2916        { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
2917        { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0430 \\u2013 \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" },
2918        { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u0411\\u0443\\u0435\\u043D\\u043E\\u0441 \\u0410\\u0439\\u0440\\u0435\\u0441 \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Buenos_Aires" },
2919        { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0430 \\u2013 \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Buenos_Aires" },
2920
2921        { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2922        { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" },
2923        { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
2924        { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0430 \\u2013 \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" },
2925        { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2926        { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" },
2927        { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
2928        { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0430 \\u2013 \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" },
2929    // icu bg.txt does not have info for this time zone
2930        { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u0411\\u0443\\u0435\\u043D\\u043E\\u0441 \\u0410\\u0439\\u0440\\u0435\\u0441 \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Buenos_Aires" },
2931        { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0430 \\u2013 \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Buenos_Aires" },
2932
2933        { "bg", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
2934        { "bg", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0500", "-5:00" },
2935        { "bg", "America/Havana", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-5", "-5:00" },
2936        { "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" },
2937        { "bg", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
2938        { "bg", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0400", "-4:00" },
2939        { "bg", "America/Havana", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-4", "-4:00" },
2940        { "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" },
2941        { "bg", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u041a\\u0443\\u0431\\u0430 \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Havana" },
2942        { "bg", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u041a\\u0443\\u0431\\u0438\\u043d\\u0441\\u043a\\u043e \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Havana" },
2943
2944        { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2945        { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+1100", "+11:00" },
2946        { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+11", "+11:00" },
2947        { "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" },
2948        { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2949        { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+1000", "+10:00" },
2950        { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+10", "+10:00" },
2951        { "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" },
2952        { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u0421\\u0438\\u0434\\u043D\\u0438 \\u0432\\u0440\\u0435\\u043C\\u0435", "Australia/Sydney" },
2953        { "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" },
2954
2955        { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2956        { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+1100", "+11:00" },
2957        { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+11", "+11:00" },
2958        { "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" },
2959        { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2960        { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+1000", "+10:00" },
2961        { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+10", "+10:00" },
2962        { "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" },
2963        { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u0421\\u0438\\u0434\\u043D\\u0438 \\u0432\\u0440\\u0435\\u043C\\u0435", "Australia/Sydney" },
2964        { "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" },
2965
2966        { "bg", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
2967        { "bg", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" },
2968        { "bg", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
2969        { "bg", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u0427\\u0430\\u0441\\u043E\\u0432\\u0430 \\u0437\\u043E\\u043D\\u0430 \\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" },
2970        { "bg", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
2971        { "bg", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+0100", "+1:00" },
2972        { "bg", "Europe/London", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+1", "+1:00" },
2973        { "bg", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+0100", "+1:00" },
2974        { "bg", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u041e\\u0431\\u0435\\u0434\\u0438\\u043d\\u0435\\u043d\\u043e \\u043a\\u0440\\u0430\\u043b\\u0441\\u0442\\u0432\\u043e \\u0432\\u0440\\u0435\\u043C\\u0435", "Europe/London" },
2975        { "bg", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u041e\\u0431\\u0435\\u0434\\u0438\\u043d\\u0435\\u043d\\u043e \\u043a\\u0440\\u0430\\u043b\\u0441\\u0442\\u0432\\u043e \\u0432\\u0440\\u0435\\u043C\\u0435", "Europe/London" },
2976
2977        { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2978        { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" },
2979        { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
2980        { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" },
2981        { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2982        { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" },
2983        { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
2984        { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" },
2985        { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
2986        { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447-0300", "-3:00" },
2987
2988        // JB#5150
2989        { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
2990        { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+0530", "+5:30" },
2991        { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+530", "+5:30" },
2992        { "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" },
2993        { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
2994        { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+0530", "+5:30" },
2995        { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u0438\\u043D\\u0443\\u0438\\u0447+530", "+05:30" },
2996        { "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" },
2997        { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u0418\\u043D\\u0434\\u0438\\u044F \\u0432\\u0440\\u0435\\u043C\\u0435", "Asia/Calcutta" },
2998        { "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" },
2999    // ==========
3000
3001        { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
3002        { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
3003        // BEGIN android-change
3004        { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "PST", "America/Los_Angeles" },
3005        { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u30a2\\u30e1\\u30ea\\u30ab\\u592a\\u5e73\\u6d0b\\u6a19\\u6e96\\u6642", "America/Los_Angeles" },
3006        { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-700" },
3007        { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
3008        { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "PDT", "America/Los_Angeles" },
3009        { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u30a2\\u30e1\\u30ea\\u30ab\\u592a\\u5e73\\u6d0b\\u590f\\u6642\\u9593", "America/Los_Angeles" },
3010    // icu ja.txt has exemplar city for this time zone
3011        { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "PT", "America/Los_Angeles" },
3012        { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u30A2\\u30E1\\u30EA\\u30AB\\u592A\\u5e73\\u6D0B\\u6642\\u9593", "America/Los_Angeles" },
3013        { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "\\u30ED\\u30B5\\u30F3\\u30BC\\u30EB\\u30B9\\u6642\\u9593", "America/Los_Angeles" },
3014        // END Android-change
3015
3016        { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3017        { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3018        { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3019        { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" },
3020        { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3021        { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3022        { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3023        { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" },
3024    // icu ja.txt does not have info for this time zone
3025        { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u30D6\\u30A8\\u30CE\\u30B9\\u30A2\\u30A4\\u30EC\\u30B9\\u6642\\u9593", "America/Buenos_Aires" },
3026        { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "America/Buenos_Aires" },
3027
3028        { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3029        { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3030        { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3031        { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" },
3032        { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3033        { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3034        { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3035        { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" },
3036        { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u30D6\\u30A8\\u30CE\\u30B9\\u30A2\\u30A4\\u30EC\\u30B9\\u6642\\u9593", "America/Buenos_Aires" },
3037        { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "America/Buenos_Aires" },
3038
3039        { "ja", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
3040        { "ja", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
3041        { "ja", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
3042        { "ja", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u30AD\\u30E5\\u30FC\\u30D0\\u6A19\\u6E96\\u6642", "-5:00" },
3043        { "ja", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
3044        { "ja", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
3045        { "ja", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
3046        { "ja", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u30AD\\u30E5\\u30FC\\u30D0\\u590F\\u6642\\u9593", "-4:00" },
3047        { "ja", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u30ad\\u30e5\\u30fc\\u30d0\\u6642\\u9593", "America/Havana" },
3048        { "ja", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u30ad\\u30e5\\u30fc\\u30d0\\u6642\\u9593", "America/Havana" },
3049
3050        { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
3051        { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
3052        { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
3053        { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u590F\\u6642\\u9593", "+11:00" },
3054        { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
3055        { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
3056        { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
3057        { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6A19\\u6E96\\u6642", "+10:00" },
3058    // icu ja.txt does not have info for this time zone
3059        { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u30B7\\u30C9\\u30CB\\u30FC\\u6642\\u9593", "Australia/Sydney" },
3060        { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6642\\u9593", "Australia/Sydney" },
3061
3062        { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
3063        { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
3064        { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
3065        { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u590F\\u6642\\u9593", "+11:00" },
3066        { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
3067        { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
3068        { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
3069        { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6A19\\u6E96\\u6642", "+10:00" },
3070        { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u30B7\\u30C9\\u30CB\\u30FC\\u6642\\u9593", "Australia/Sydney" },
3071        { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6642\\u9593", "Australia/Sydney" },
3072
3073        { "ja", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
3074        { "ja", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
3075        { "ja", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
3076        { "ja", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u30B0\\u30EA\\u30CB\\u30C3\\u30B8\\u6A19\\u6E96\\u6642", "+0:00" },
3077        { "ja", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
3078        { "ja", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
3079        { "ja", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
3080        { "ja", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u82f1\\u56fd\\u590f\\u6642\\u9593", "+1:00" },
3081        { "ja", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u30a4\\u30ae\\u30ea\\u30b9\\u6642\\u9593", "Europe/London" },
3082        { "ja", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u30a4\\u30ae\\u30ea\\u30b9\\u6642\\u9593", "Europe/London" },
3083        { "ja", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "\\u30a4\\u30ae\\u30ea\\u30b9\\u6642\\u9593", "Europe/London" },
3084
3085        { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3086        { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3087        { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3088        { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3089        { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3090        { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3091        { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3092        { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3093        { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
3094        { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
3095
3096        // JB#5150
3097        { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
3098        { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
3099        { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
3100        { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u30A4\\u30F3\\u30C9\\u6642\\u9593", "+5:30" },
3101        { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
3102        { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
3103        { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
3104        { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u30A4\\u30F3\\u30C9\\u6642\\u9593", "+5:30" },
3105        { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u30A4\\u30F3\\u30C9\\u6642\\u9593", "Asia/Calcutta" },
3106        { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u30A4\\u30F3\\u30C9\\u6642\\u9593", "Asia/Calcutta" },
3107
3108    // ==========
3109
3110        { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
3111        { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
3112        // BEGIN Android-change
3113        { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "PST", "-8:00" },
3114        { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "GMT-08:00", "-8:00" },
3115        { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
3116        { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
3117        { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "PDT", "-7:00" },
3118        { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "GMT-07:00", "-7:00" },
3119        { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "PT", "America/Los_Angeles" },
3120        { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Los Angeles", "America/Los_Angeles" },
3121        // END Android-change
3122
3123        { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3124        { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3125        { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3126        { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3127        { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3128        { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3129        { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3130        { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3131        { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires", "America/Buenos_Aires" },
3132        { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Buenos Aires", "America/Buenos_Aires" },
3133
3134        { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3135        { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3136        { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3137        { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3138        { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3139        { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3140        { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3141        { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3142        { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires", "America/Buenos_Aires" },
3143        { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Buenos Aires", "America/Buenos_Aires" },
3144
3145        { "ti", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
3146        { "ti", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
3147        { "ti", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
3148        { "ti", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "GMT-05:00", "-5:00" },
3149        { "ti", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
3150        { "ti", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
3151        { "ti", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
3152        { "ti", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "GMT-04:00", "-4:00" },
3153        { "ti", "America/Havana", "2004-07-15T00:00:00Z", "v", "CU", "America/Havana" },
3154        { "ti", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "CU", "America/Havana" },
3155
3156        { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
3157        { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
3158        { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
3159        { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" },
3160        { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
3161        { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
3162        { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
3163        { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" },
3164        { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Sydney", "Australia/Sydney" },
3165        { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Sydney", "Australia/Sydney" },
3166
3167        { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
3168        { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
3169        { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
3170        { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" },
3171        { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
3172        { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
3173        { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
3174        { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" },
3175        { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Sydney", "Australia/Sydney" },
3176        { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Sydney", "Australia/Sydney" },
3177
3178        { "ti", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
3179        { "ti", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
3180        { "ti", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
3181        { "ti", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "GMT", "+0:00" },
3182        { "ti", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
3183        { "ti", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
3184        { "ti", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
3185        { "ti", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "GMT+01:00", "+1:00" },
3186        { "ti", "Europe/London", "2004-07-15T00:00:00Z", "v", "GB", "Europe/London" },
3187        { "ti", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "GB", "Europe/London" },
3188
3189        { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3190        { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3191        { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3192        { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3193        { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3194        { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3195        { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3196        { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3197        { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
3198        { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
3199
3200        // JB#5150
3201        { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
3202        { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
3203        { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
3204        { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
3205        { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
3206        { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
3207        { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
3208        { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
3209        { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "IN", "Alna/Calcutta" },
3210        { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "IN", "Asia/Calcutta" },
3211
3212        // Ticket#8589 Partial location name to use country name if the zone is the golden
3213        // zone for the time zone's country.
3214        { "en_MX", "America/Chicago", "1995-07-15T00:00:00Z", "vvvv", "Central Time (United States)", "America/Chicago"},
3215
3216        // Tests proper handling of time zones that should have empty sets when inherited from the parent.
3217        // For example, en_GB understands CET as Central European Time, but en_HK, which inherits from en_GB
3218        // does not
3219        { "en_GB", "Europe/Paris", "2004-01-15T00:00:00Z", "zzzz", "Central European Standard Time", "+1:00"},
3220        { "en_GB", "Europe/Paris", "2004-07-15T00:00:00Z", "zzzz", "Central European Summer Time", "+2:00"},
3221        { "en_GB", "Europe/Paris", "2004-01-15T00:00:00Z", "z", "CET", "+1:00"},
3222        { "en_GB", "Europe/Paris", "2004-07-15T00:00:00Z", "z", "CEST", "+2:00"},
3223        { "en_HK", "Europe/Paris", "2004-01-15T00:00:00Z", "zzzz", "Central European Standard Time", "+1:00"},
3224        { "en_HK", "Europe/Paris", "2004-07-15T00:00:00Z", "zzzz", "Central European Summer Time", "+2:00"},
3225        { "en_HK", "Europe/Paris", "2004-01-15T00:00:00Z", "z", "GMT+1", "+1:00"},
3226        { "en_HK", "Europe/Paris", "2004-07-15T00:00:00Z", "z", "GMT+2", "+2:00"},
3227
3228        { NULL, NULL, NULL, NULL, NULL, NULL },
3229    };
3230
3231    UErrorCode status = U_ZERO_ERROR;
3232    Calendar *cal = GregorianCalendar::createInstance(status);
3233    if (failure(status, "GregorianCalendar::createInstance", TRUE)) return;
3234    SimpleDateFormat testfmt(UnicodeString("yyyy-MM-dd'T'HH:mm:ss'Z'"), status);
3235    if (failure(status, "SimpleDateFormat constructor", TRUE)) return;
3236    testfmt.setTimeZone(*TimeZone::getGMT());
3237
3238    for (int i = 0; fallbackTests[i][0]; i++) {
3239        const char **testLine = fallbackTests[i];
3240        UnicodeString info[5];
3241        for ( int j = 0 ; j < 5 ; j++ ) {
3242            info[j] = UnicodeString(testLine[j], -1, US_INV);
3243        }
3244        info[4] = info[4].unescape();
3245        logln("%s;%s;%s;%s", testLine[0], testLine[1], testLine[2], testLine[3]);
3246
3247        TimeZone *tz = TimeZone::createTimeZone(info[1]);
3248
3249        UDate d = testfmt.parse(testLine[2], status);
3250        cal->setTime(d, status);
3251        if (U_FAILURE(status)) {
3252            errln(UnicodeString("Failed to set date: ") + testLine[2]);
3253        }
3254
3255        SimpleDateFormat fmt(info[3], Locale(testLine[0]),status);
3256        ASSERT_OK(status);
3257        cal->adoptTimeZone(tz);
3258        UnicodeString result;
3259        FieldPosition pos(0);
3260        fmt.format(*cal,result,pos);
3261        if (result != info[4]) {
3262            errln(info[0] + ";" + info[1] + ";" + info[2] + ";" + info[3] + " expected: '" +
3263                  info[4] + "' but got: '" + result + "'");
3264        }
3265    }
3266    delete cal;
3267}
3268
3269void DateFormatTest::TestRoundtripWithCalendar(void) {
3270    UErrorCode status = U_ZERO_ERROR;
3271
3272    TimeZone *tz = TimeZone::createTimeZone("Europe/Paris");
3273    TimeZone *gmt = TimeZone::createTimeZone("Etc/GMT");
3274
3275    Calendar *calendars[] = {
3276        Calendar::createInstance(*tz, Locale("und@calendar=gregorian"), status),
3277        Calendar::createInstance(*tz, Locale("und@calendar=buddhist"), status),
3278//        Calendar::createInstance(*tz, Locale("und@calendar=hebrew"), status),
3279        Calendar::createInstance(*tz, Locale("und@calendar=islamic"), status),
3280        Calendar::createInstance(*tz, Locale("und@calendar=japanese"), status),
3281        NULL
3282    };
3283    if (U_FAILURE(status)) {
3284        dataerrln("Failed to initialize calendars: %s", u_errorName(status));
3285        for (int i = 0; calendars[i] != NULL; i++) {
3286            delete calendars[i];
3287        }
3288        return;
3289    }
3290
3291    //FIXME The formatters commented out below are currently failing because of
3292    // the calendar calculation problem reported by #6691
3293
3294    // The order of test formatters must match the order of calendars above.
3295    DateFormat *formatters[] = {
3296        DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("en_US")), //calendar=gregorian
3297        DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("th_TH")), //calendar=buddhist
3298//        DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("he_IL@calendar=hebrew")),
3299        DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("ar_EG@calendar=islamic")),
3300//        DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("ja_JP@calendar=japanese")),
3301        NULL
3302    };
3303
3304    UDate d = Calendar::getNow();
3305    UnicodeString buf;
3306    FieldPosition fpos;
3307    ParsePosition ppos;
3308
3309    for (int i = 0; formatters[i] != NULL; i++) {
3310        buf.remove();
3311        fpos.setBeginIndex(0);
3312        fpos.setEndIndex(0);
3313        calendars[i]->setTime(d, status);
3314
3315        // Normal case output - the given calendar matches the calendar
3316        // used by the formatter
3317        formatters[i]->format(*calendars[i], buf, fpos);
3318        UnicodeString refStr(buf);
3319
3320        for (int j = 0; calendars[j] != NULL; j++) {
3321            if (j == i) {
3322                continue;
3323            }
3324            buf.remove();
3325            fpos.setBeginIndex(0);
3326            fpos.setEndIndex(0);
3327            calendars[j]->setTime(d, status);
3328
3329            // Even the different calendar type is specified,
3330            // we should get the same result.
3331            formatters[i]->format(*calendars[j], buf, fpos);
3332            if (refStr != buf) {
3333                errln((UnicodeString)"FAIL: Different format result with a different calendar for the same time -"
3334                        + "\n Reference calendar type=" + calendars[i]->getType()
3335                        + "\n Another calendar type=" + calendars[j]->getType()
3336                        + "\n Expected result=" + refStr
3337                        + "\n Actual result=" + buf);
3338            }
3339        }
3340
3341        calendars[i]->setTimeZone(*gmt);
3342        calendars[i]->clear();
3343        ppos.setErrorIndex(-1);
3344        ppos.setIndex(0);
3345
3346        // Normal case parse result - the given calendar matches the calendar
3347        // used by the formatter
3348        formatters[i]->parse(refStr, *calendars[i], ppos);
3349
3350        for (int j = 0; calendars[j] != NULL; j++) {
3351            if (j == i) {
3352                continue;
3353            }
3354            calendars[j]->setTimeZone(*gmt);
3355            calendars[j]->clear();
3356            ppos.setErrorIndex(-1);
3357            ppos.setIndex(0);
3358
3359            // Even the different calendar type is specified,
3360            // we should get the same time and time zone.
3361            formatters[i]->parse(refStr, *calendars[j], ppos);
3362            if (calendars[i]->getTime(status) != calendars[j]->getTime(status)
3363                || calendars[i]->getTimeZone() != calendars[j]->getTimeZone()) {
3364                UnicodeString tzid;
3365                errln((UnicodeString)"FAIL: Different parse result with a different calendar for the same string -"
3366                        + "\n Reference calendar type=" + calendars[i]->getType()
3367                        + "\n Another calendar type=" + calendars[j]->getType()
3368                        + "\n Date string=" + refStr
3369                        + "\n Expected time=" + calendars[i]->getTime(status)
3370                        + "\n Expected time zone=" + calendars[i]->getTimeZone().getID(tzid)
3371                        + "\n Actual time=" + calendars[j]->getTime(status)
3372                        + "\n Actual time zone=" + calendars[j]->getTimeZone().getID(tzid));
3373            }
3374        }
3375        if (U_FAILURE(status)) {
3376            errln((UnicodeString)"FAIL: " + u_errorName(status));
3377            break;
3378        }
3379    }
3380
3381    delete tz;
3382    delete gmt;
3383    for (int i = 0; calendars[i] != NULL; i++) {
3384        delete calendars[i];
3385    }
3386    for (int i = 0; formatters[i] != NULL; i++) {
3387        delete formatters[i];
3388    }
3389}
3390
3391/*
3392void DateFormatTest::TestRelativeError(void)
3393{
3394    UErrorCode status;
3395    Locale en("en");
3396
3397    DateFormat *en_reltime_reldate =         DateFormat::createDateTimeInstance(DateFormat::kFullRelative,DateFormat::kFullRelative,en);
3398    if(en_reltime_reldate == NULL) {
3399        logln("PASS: rel date/rel time failed");
3400    } else {
3401        errln("FAIL: rel date/rel time created, should have failed.");
3402        delete en_reltime_reldate;
3403    }
3404}
3405
3406void DateFormatTest::TestRelativeOther(void)
3407{
3408    logln("Nothing in this test. When we get more data from CLDR, put in some tests of -2, +2, etc. ");
3409}
3410*/
3411
3412void DateFormatTest::Test6338(void)
3413{
3414    UErrorCode status = U_ZERO_ERROR;
3415
3416    SimpleDateFormat *fmt1 = new SimpleDateFormat(UnicodeString("y-M-d"), Locale("ar"), status);
3417    if (failure(status, "new SimpleDateFormat", TRUE)) return;
3418
3419    UDate dt1 = date(2008-1900, UCAL_JUNE, 10, 12, 00);
3420    UnicodeString str1;
3421    str1 = fmt1->format(dt1, str1);
3422    logln(str1);
3423
3424    UDate dt11 = fmt1->parse(str1, status);
3425    failure(status, "fmt->parse");
3426
3427    UnicodeString str11;
3428    str11 = fmt1->format(dt11, str11);
3429    logln(str11);
3430
3431    if (str1 != str11) {
3432        errln((UnicodeString)"FAIL: Different dates str1:" + str1
3433            + " str2:" + str11);
3434    }
3435    delete fmt1;
3436
3437    /////////////////
3438
3439    status = U_ZERO_ERROR;
3440    SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("y M d"), Locale("ar"), status);
3441    failure(status, "new SimpleDateFormat");
3442
3443    UDate dt2 = date(2008-1900, UCAL_JUNE, 10, 12, 00);
3444    UnicodeString str2;
3445    str2 = fmt2->format(dt2, str2);
3446    logln(str2);
3447
3448    UDate dt22 = fmt2->parse(str2, status);
3449    failure(status, "fmt->parse");
3450
3451    UnicodeString str22;
3452    str22 = fmt2->format(dt22, str22);
3453    logln(str22);
3454
3455    if (str2 != str22) {
3456        errln((UnicodeString)"FAIL: Different dates str1:" + str2
3457            + " str2:" + str22);
3458    }
3459    delete fmt2;
3460
3461    /////////////////
3462
3463    status = U_ZERO_ERROR;
3464    SimpleDateFormat *fmt3 = new SimpleDateFormat(UnicodeString("y-M-d"), Locale("en-us"), status);
3465    failure(status, "new SimpleDateFormat");
3466
3467    UDate dt3 = date(2008-1900, UCAL_JUNE, 10, 12, 00);
3468    UnicodeString str3;
3469    str3 = fmt3->format(dt3, str3);
3470    logln(str3);
3471
3472    UDate dt33 = fmt3->parse(str3, status);
3473    failure(status, "fmt->parse");
3474
3475    UnicodeString str33;
3476    str33 = fmt3->format(dt33, str33);
3477    logln(str33);
3478
3479    if (str3 != str33) {
3480        errln((UnicodeString)"FAIL: Different dates str1:" + str3
3481            + " str2:" + str33);
3482    }
3483    delete fmt3;
3484
3485    /////////////////
3486
3487    status = U_ZERO_ERROR;
3488    SimpleDateFormat *fmt4 = new SimpleDateFormat(UnicodeString("y M  d"), Locale("en-us"), status);
3489    failure(status, "new SimpleDateFormat");
3490
3491    UDate dt4 = date(2008-1900, UCAL_JUNE, 10, 12, 00);
3492    UnicodeString str4;
3493    str4 = fmt4->format(dt4, str4);
3494    logln(str4);
3495
3496    UDate dt44 = fmt4->parse(str4, status);
3497    failure(status, "fmt->parse");
3498
3499    UnicodeString str44;
3500    str44 = fmt4->format(dt44, str44);
3501    logln(str44);
3502
3503    if (str4 != str44) {
3504        errln((UnicodeString)"FAIL: Different dates str1:" + str4
3505            + " str2:" + str44);
3506    }
3507    delete fmt4;
3508
3509}
3510
3511void DateFormatTest::Test6726(void)
3512{
3513    // status
3514//    UErrorCode status = U_ZERO_ERROR;
3515
3516    // fmtf, fmtl, fmtm, fmts;
3517    UnicodeString strf, strl, strm, strs;
3518    UDate dt = date(2008-1900, UCAL_JUNE, 10, 12, 00);
3519
3520    Locale loc("ja");
3521    DateFormat* fmtf = DateFormat::createDateTimeInstance(DateFormat::FULL, DateFormat::FULL, loc);
3522    DateFormat* fmtl = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::FULL, loc);
3523    DateFormat* fmtm = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL, loc);
3524    DateFormat* fmts = DateFormat::createDateTimeInstance(DateFormat::SHORT, DateFormat::FULL, loc);
3525    if (fmtf == NULL || fmtl == NULL || fmtm == NULL || fmts == NULL) {
3526        dataerrln("Unable to create DateFormat. got NULL.");
3527        /* It may not be true that if one is NULL all is NULL.  Just to be safe. */
3528        delete fmtf;
3529        delete fmtl;
3530        delete fmtm;
3531        delete fmts;
3532
3533        return;
3534    }
3535    strf = fmtf->format(dt, strf);
3536    strl = fmtl->format(dt, strl);
3537    strm = fmtm->format(dt, strm);
3538    strs = fmts->format(dt, strs);
3539
3540
3541    logln("strm.charAt(10)=%04X wanted 0x20\n", strm.charAt(10));
3542    if (strm.charAt(10) != UChar(0x0020)) {
3543      errln((UnicodeString)"FAIL: Improper formatted date: " + strm );
3544    }
3545    logln("strs.charAt(10)=%04X wanted 0x20\n", strs.charAt(8));
3546    if (strs.charAt(10)  != UChar(0x0020)) {
3547        errln((UnicodeString)"FAIL: Improper formatted date: " + strs);
3548    }
3549
3550    delete fmtf;
3551    delete fmtl;
3552    delete fmtm;
3553    delete fmts;
3554
3555    return;
3556}
3557
3558/**
3559 * Test DateFormat's parsing of default GMT variants.  See ticket#6135
3560 */
3561void DateFormatTest::TestGMTParsing() {
3562    const char* DATA[] = {
3563        "HH:mm:ss Z",
3564
3565        // pattern, input, expected output (in quotes)
3566        "HH:mm:ss Z",       "10:20:30 GMT+03:00",   "10:20:30 +0300",
3567        "HH:mm:ss Z",       "10:20:30 UT-02:00",    "10:20:30 -0200",
3568        "HH:mm:ss Z",       "10:20:30 GMT",         "10:20:30 +0000",
3569        "HH:mm:ss vvvv",    "10:20:30 UT+10:00",    "10:20:30 +1000",
3570        "HH:mm:ss zzzz",    "10:20:30 UTC",         "10:20:30 +0000",   // standalone "UTC"
3571        "ZZZZ HH:mm:ss",    "UT 10:20:30",          "10:20:30 +0000",
3572        "z HH:mm:ss",       "UT+0130 10:20:30",     "10:20:30 +0130",
3573        "z HH:mm:ss",       "UTC+0130 10:20:30",    "10:20:30 +0130",
3574        // Note: GMT-1100 no longer works because of the introduction of the short
3575        // localized GMT support. Previous implementation support this level of
3576        // leniency (no separator char in localized GMT format), but the new
3577        // implementation handles GMT-11 as the legitimate short localized GMT format
3578        // and stop at there. Otherwise, roundtrip would be broken.
3579        //"HH mm Z ss",       "10 20 GMT-1100 30",    "10:20:30 -1100",
3580        "HH mm Z ss",       "10 20 GMT-11 30",    "10:20:30 -1100",
3581        "HH:mm:ssZZZZZ",    "14:25:45Z",            "14:25:45 +0000",
3582        "HH:mm:ssZZZZZ",    "15:00:00-08:00",       "15:00:00 -0800",
3583    };
3584    const int32_t DATA_len = sizeof(DATA)/sizeof(DATA[0]);
3585    expectParse(DATA, DATA_len, Locale("en"));
3586}
3587
3588// Test case for localized GMT format parsing
3589// with no delimitters in offset format (Chinese locale)
3590void DateFormatTest::Test6880() {
3591    UErrorCode status = U_ZERO_ERROR;
3592    UDate d1, d2, dp1, dp2, dexp1, dexp2;
3593    UnicodeString s1, s2;
3594
3595    TimeZone *tz = TimeZone::createTimeZone("Asia/Shanghai");
3596    GregorianCalendar gcal(*tz, status);
3597    if (failure(status, "construct GregorianCalendar", TRUE)) return;
3598
3599    gcal.clear();
3600    gcal.set(1910, UCAL_JULY, 1, 12, 00);   // offset 8:05:57
3601    d1 = gcal.getTime(status);
3602
3603    gcal.clear();
3604    gcal.set(1950, UCAL_JULY, 1, 12, 00);   // offset 8:00
3605    d2 = gcal.getTime(status);
3606
3607    gcal.clear();
3608    gcal.set(1970, UCAL_JANUARY, 1, 12, 00);
3609    dexp2 = gcal.getTime(status);
3610    dexp1 = dexp2 - (5*60 + 57)*1000;   // subtract 5m57s
3611
3612    if (U_FAILURE(status)) {
3613        errln("FAIL: Gregorian calendar error");
3614    }
3615
3616    DateFormat *fmt = DateFormat::createTimeInstance(DateFormat::kFull, Locale("zh"));
3617    if (fmt == NULL) {
3618        dataerrln("Unable to create DateFormat. Got NULL.");
3619        return;
3620    }
3621    fmt->adoptTimeZone(tz);
3622
3623    fmt->format(d1, s1);
3624    fmt->format(d2, s2);
3625
3626    dp1 = fmt->parse(s1, status);
3627    dp2 = fmt->parse(s2, status);
3628
3629    if (U_FAILURE(status)) {
3630        errln("FAIL: Parse failure");
3631    }
3632
3633    if (dp1 != dexp1) {
3634        errln("FAIL: Failed to parse " + s1 + " parsed: " + dp1 + " expected: " + dexp1);
3635    }
3636    if (dp2 != dexp2) {
3637        errln("FAIL: Failed to parse " + s2 + " parsed: " + dp2 + " expected: " + dexp2);
3638    }
3639
3640    delete fmt;
3641}
3642
3643typedef struct {
3644    const char * localeStr;
3645    UBool        lenient;
3646    UBool        expectFail;
3647    UnicodeString datePattern;
3648    UnicodeString dateString;
3649} NumAsStringItem;
3650
3651void DateFormatTest::TestNumberAsStringParsing()
3652{
3653    const NumAsStringItem items[] = {
3654        // loc lenient fail?  datePattern                                         dateString
3655        { "",   FALSE, FALSE,  UnicodeString("y MMMM d HH:mm:ss"),                UnicodeString("2009 7 14 08:43:57") },  // Google Patch. CLDR Ticket 5932.
3656        { "",   TRUE,  FALSE, UnicodeString("y MMMM d HH:mm:ss"),                 UnicodeString("2009 7 14 08:43:57") },
3657        { "en", FALSE, FALSE, UnicodeString("MMM d, y"),                          UnicodeString("Jul 14, 2009") },
3658        { "en", TRUE,  FALSE, UnicodeString("MMM d, y"),                          UnicodeString("Jul 14, 2009") },
3659        { "en", FALSE, TRUE,  UnicodeString("MMM d, y"),                          UnicodeString("7 14, 2009") },
3660        { "en", TRUE,  FALSE, UnicodeString("MMM d, y"),                          UnicodeString("7 14, 2009") },
3661        { "ja", FALSE, FALSE, UnicodeString("yyyy/MM/dd"),                        UnicodeString("2009/07/14")         },
3662        { "ja", TRUE,  FALSE, UnicodeString("yyyy/MM/dd"),                        UnicodeString("2009/07/14")         },
3663      //{ "ja", FALSE, FALSE, UnicodeString("yyyy/MMMMM/d"),                      UnicodeString("2009/7/14")          }, // #8860 covers test failure
3664        { "ja", TRUE,  FALSE, UnicodeString("yyyy/MMMMM/d"),                      UnicodeString("2009/7/14")          },
3665        { "ja", FALSE, FALSE, CharsToUnicodeString("y\\u5E74M\\u6708d\\u65E5"),   CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5")   },
3666        { "ja", TRUE,  FALSE, CharsToUnicodeString("y\\u5E74M\\u6708d\\u65E5"),   CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5")   },
3667        { "ja", FALSE, FALSE, CharsToUnicodeString("y\\u5E74MMMd\\u65E5"),        CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5")   },
3668        { "ja", TRUE,  FALSE, CharsToUnicodeString("y\\u5E74MMMd\\u65E5"),        CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5")   }, // #8820 fixes test failure
3669        { "ko", FALSE, FALSE, UnicodeString("yyyy. M. d."),                       UnicodeString("2009. 7. 14.")       },
3670        { "ko", TRUE,  FALSE, UnicodeString("yyyy. M. d."),                       UnicodeString("2009. 7. 14.")       },
3671        { "ko", FALSE, FALSE, UnicodeString("yyyy. MMMMM d."),                    CharsToUnicodeString("2009. 7\\uC6D4 14.")             },
3672        { "ko", TRUE,  FALSE, UnicodeString("yyyy. MMMMM d."),                    CharsToUnicodeString("2009. 7\\uC6D4 14.")             }, // #8820 fixes test failure
3673        { "ko", FALSE, FALSE, CharsToUnicodeString("y\\uB144 M\\uC6D4 d\\uC77C"), CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") },
3674        { "ko", TRUE,  FALSE, CharsToUnicodeString("y\\uB144 M\\uC6D4 d\\uC77C"), CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") },
3675        { "ko", FALSE, FALSE, CharsToUnicodeString("y\\uB144 MMM d\\uC77C"),      CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") },
3676        { "ko", TRUE,  FALSE, CharsToUnicodeString("y\\uB144 MMM d\\uC77C"),      CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") }, // #8820 fixes test failure
3677        { NULL, FALSE, FALSE, UnicodeString(""),                                  UnicodeString("")                   }
3678    };
3679    const NumAsStringItem * itemPtr;
3680    for (itemPtr = items; itemPtr->localeStr != NULL; itemPtr++ ) {
3681        Locale locale = Locale::createFromName(itemPtr->localeStr);
3682        UErrorCode status = U_ZERO_ERROR;
3683        SimpleDateFormat *formatter = new SimpleDateFormat(itemPtr->datePattern, locale, status);
3684        if (formatter == NULL || U_FAILURE(status)) {
3685            dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
3686            return;
3687        }
3688
3689        formatter->setLenient(itemPtr->lenient);
3690        UDate date1 = formatter->parse(itemPtr->dateString, status);
3691        if (U_FAILURE(status)) {
3692            if (!itemPtr->expectFail) {
3693                errln("FAIL, err when expected success: Locale \"" + UnicodeString(itemPtr->localeStr) + "\", lenient " + itemPtr->lenient +
3694                        ": using pattern \"" + itemPtr->datePattern + "\", could not parse \"" + itemPtr->dateString + "\"; err: " + u_errorName(status) );
3695            }
3696        } else if (itemPtr->expectFail) {
3697                errln("FAIL, expected err but got none: Locale \"" + UnicodeString(itemPtr->localeStr) + "\", lenient " + itemPtr->lenient +
3698                        ": using pattern \"" + itemPtr->datePattern + "\", did parse \"" + itemPtr->dateString + "\"." );
3699        } else if (!itemPtr->lenient) {
3700            UnicodeString formatted;
3701            formatter->format(date1, formatted);
3702            if (formatted != itemPtr->dateString) {
3703                errln("FAIL, mismatch formatting parsed date: Locale \"" + UnicodeString(itemPtr->localeStr) + "\", lenient " + itemPtr->lenient +
3704                        ": using pattern \"" + itemPtr->datePattern + "\", did parse \"" + itemPtr->dateString + "\", formatted result \"" + formatted + "\".");
3705            }
3706        }
3707
3708        delete formatter;
3709    }
3710}
3711
3712void DateFormatTest::TestISOEra() {
3713
3714    const char* data[] = {
3715    // input, output
3716    "BC 4004-10-23T07:00:00Z", "BC 4004-10-23T07:00:00Z",
3717    "AD 4004-10-23T07:00:00Z", "AD 4004-10-23T07:00:00Z",
3718    "-4004-10-23T07:00:00Z"  , "BC 4005-10-23T07:00:00Z",
3719    "4004-10-23T07:00:00Z"   , "AD 4004-10-23T07:00:00Z",
3720    };
3721
3722    int32_t numData = 8;
3723
3724    UErrorCode status = U_ZERO_ERROR;
3725
3726    // create formatter
3727    SimpleDateFormat *fmt1 = new SimpleDateFormat(UnicodeString("GGG yyyy-MM-dd'T'HH:mm:ss'Z"), status);
3728    failure(status, "new SimpleDateFormat", TRUE);
3729    if (status == U_MISSING_RESOURCE_ERROR) {
3730        if (fmt1 != NULL) {
3731            delete fmt1;
3732        }
3733        return;
3734    }
3735    for(int i=0; i < numData; i+=2) {
3736        // create input string
3737        UnicodeString in = data[i];
3738
3739        // parse string to date
3740        UDate dt1 = fmt1->parse(in, status);
3741        failure(status, "fmt->parse", TRUE);
3742
3743        // format date back to string
3744        UnicodeString out;
3745        out = fmt1->format(dt1, out);
3746        logln(out);
3747
3748        // check that roundtrip worked as expected
3749        UnicodeString expected = data[i+1];
3750        if (out != expected) {
3751            dataerrln((UnicodeString)"FAIL: " + in + " -> " + out + " expected -> " + expected);
3752        }
3753    }
3754
3755    delete fmt1;
3756}
3757void DateFormatTest::TestFormalChineseDate() {
3758
3759    UErrorCode status = U_ZERO_ERROR;
3760    UnicodeString pattern ("y\\u5e74M\\u6708d\\u65e5", -1, US_INV );
3761    pattern = pattern.unescape();
3762    UnicodeString override ("y=hanidec;M=hans;d=hans", -1, US_INV );
3763
3764    // create formatter
3765    SimpleDateFormat *sdf = new SimpleDateFormat(pattern,override,Locale::getChina(),status);
3766    failure(status, "new SimpleDateFormat with override", TRUE);
3767
3768    UDate thedate = date(2009-1900, UCAL_JULY, 28);
3769    FieldPosition pos(0);
3770    UnicodeString result;
3771    sdf->format(thedate,result,pos);
3772
3773    UnicodeString expected = "\\u4e8c\\u3007\\u3007\\u4e5d\\u5e74\\u4e03\\u6708\\u4e8c\\u5341\\u516b\\u65e5";
3774    expected = expected.unescape();
3775    if (result != expected) {
3776        dataerrln((UnicodeString)"FAIL: -> " + result + " expected -> " + expected);
3777    }
3778
3779    UDate parsedate = sdf->parse(expected,status);
3780    if ( parsedate != thedate ) {
3781        UnicodeString pat1 ("yyyy-MM-dd'T'HH:mm:ss'Z'", -1, US_INV );
3782        SimpleDateFormat *usf = new SimpleDateFormat(pat1,Locale::getEnglish(),status);
3783        UnicodeString parsedres,expres;
3784        usf->format(parsedate,parsedres,pos);
3785        usf->format(thedate,expres,pos);
3786        dataerrln((UnicodeString)"FAIL: parsed -> " + parsedres + " expected -> " + expres);
3787        delete usf;
3788    }
3789    delete sdf;
3790}
3791
3792// Test case for #8675
3793// Incorrect parse offset with stand alone GMT string on 2nd or later iteration.
3794void DateFormatTest::TestStandAloneGMTParse() {
3795    UErrorCode status = U_ZERO_ERROR;
3796    SimpleDateFormat *sdf = new SimpleDateFormat("ZZZZ", Locale(""), status);
3797
3798    if (U_SUCCESS(status)) {
3799
3800        UnicodeString inText("GMT$$$");
3801        for (int32_t i = 0; i < 10; i++) {
3802            ParsePosition pos(0);
3803            sdf->parse(inText, pos);
3804            if (pos.getIndex() != 3) {
3805                errln((UnicodeString)"FAIL: Incorrect output parse position: actual=" + pos.getIndex() + " expected=3");
3806            }
3807        }
3808
3809        delete sdf;
3810    } else {
3811        dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
3812    }
3813}
3814
3815void DateFormatTest::TestParsePosition() {
3816    const char* TestData[][4] = {
3817        // {<pattern>, <lead>, <date string>, <trail>}
3818        {"yyyy-MM-dd HH:mm:ssZ", "", "2010-01-10 12:30:00+0500", ""},
3819        {"yyyy-MM-dd HH:mm:ss ZZZZ", "", "2010-01-10 12:30:00 GMT+05:00", ""},
3820        {"Z HH:mm:ss", "", "-0100 13:20:30", ""},
3821        {"y-M-d Z", "", "2011-8-25 -0400", " Foo"},
3822        {"y/M/d H:mm:ss z", "", "2011/7/1 12:34:00 PDT", ""},
3823        {"y/M/d H:mm:ss z", "+123", "2011/7/1 12:34:00 PDT", " PST"},
3824        {"vvvv a h:mm:ss", "", "Pacific Time AM 10:21:45", ""},
3825        {"HH:mm v M/d", "111", "14:15 PT 8/10", " 12345"},
3826        {"'time zone:' VVVV 'date:' yyyy-MM-dd", "xxxx", "time zone: Los Angeles Time date: 2010-02-25", "xxxx"},
3827        {"yG", "", "2012AD", ""},
3828        {"yG", "", "2012", "x"},
3829        {0, 0, 0, 0},
3830    };
3831
3832    for (int32_t i = 0; TestData[i][0]; i++) {
3833        UErrorCode status = U_ZERO_ERROR;
3834        SimpleDateFormat *sdf = new SimpleDateFormat(UnicodeString(TestData[i][0]), status);
3835        if (failure(status, "new SimpleDateFormat", TRUE)) return;
3836
3837        int32_t startPos, resPos;
3838
3839        // lead text
3840        UnicodeString input(TestData[i][1]);
3841        startPos = input.length();
3842
3843        // date string
3844        input += TestData[i][2];
3845        resPos = input.length();
3846
3847        // trail text
3848        input += TestData[i][3];
3849
3850        ParsePosition pos(startPos);
3851        //UDate d = sdf->parse(input, pos);
3852        (void)sdf->parse(input, pos);
3853
3854        if (pos.getIndex() != resPos) {
3855            errln(UnicodeString("FAIL: Parsing [") + input + "] with pattern [" + TestData[i][0] + "] returns position - "
3856                + pos.getIndex() + ", expected - " + resPos);
3857        }
3858
3859        delete sdf;
3860    }
3861}
3862
3863
3864typedef struct {
3865    int32_t era;
3866    int32_t year;
3867    int32_t month; // 1-based
3868    int32_t isLeapMonth;
3869    int32_t day;
3870} ChineseCalTestDate;
3871
3872#define NUM_TEST_DATES 3
3873
3874typedef struct {
3875    const char *   locale;
3876    int32_t        style; // <0 => custom
3877    UnicodeString  dateString[NUM_TEST_DATES];
3878} MonthPatternItem;
3879
3880void DateFormatTest::TestMonthPatterns()
3881{
3882    const ChineseCalTestDate dates[NUM_TEST_DATES] = {
3883        // era yr mo lp da
3884        {  78, 29, 4, 0, 2 }, // (in chinese era 78) gregorian 2012-4-22
3885        {  78, 29, 4, 1, 2 }, // (in chinese era 78) gregorian 2012-5-22
3886        {  78, 29, 5, 0, 2 }, // (in chinese era 78) gregorian 2012-6-20
3887    };
3888
3889    const MonthPatternItem items[] = {
3890        // locale                     date style;           expected formats for the 3 dates above
3891        { "root@calendar=chinese",    DateFormat::kLong,  { UnicodeString("ren-chen 4 2"),  UnicodeString("ren-chen 4bis 2"),       UnicodeString("ren-chen 5 2") } },  // Google Patch. CLDR Ticket 5932.
3892        { "root@calendar=chinese",    DateFormat::kShort, { UnicodeString("29-04-02"),        UnicodeString("29-04bis-02"),             UnicodeString("29-05-02") } },
3893        { "root@calendar=chinese",    -1,                 { UnicodeString("29-4-2"),        UnicodeString("29-4bis-2"),             UnicodeString("29-5-2") } },
3894        { "root@calendar=chinese",    -2,                 { UnicodeString("78x29-4-2"),     UnicodeString("78x29-4bis-2"),          UnicodeString("78x29-5-2") } },
3895        { "root@calendar=chinese",    -3,                 { UnicodeString("ren-chen-4-2"),  UnicodeString("ren-chen-4bis-2"),       UnicodeString("ren-chen-5-2") } },
3896        { "root@calendar=chinese",    -4,                 { UnicodeString("ren-chen 4 2"),  UnicodeString("ren-chen 4bis 2"),       UnicodeString("ren-chen 5 2") } },  // Google Patch. CLDR Ticket 5932.
3897        { "en@calendar=gregorian",    -3,                 { UnicodeString("2012-4-22"),     UnicodeString("2012-5-22"),             UnicodeString("2012-6-20") } },
3898        { "en@calendar=chinese",      DateFormat::kLong,  { UnicodeString("4 2, ren-chen"), UnicodeString("4bis 2, ren-chen"),      UnicodeString("5 2, ren-chen") } },  // Google Patch. CLDR Ticket 5932.
3899        { "en@calendar=chinese",      DateFormat::kShort, { UnicodeString("4/2/29"),        UnicodeString("4bis/2/29"),             UnicodeString("5/2/29") } },
3900        { "zh@calendar=chinese",      DateFormat::kLong,  { CharsToUnicodeString("\\u58EC\\u8FB0\\u5E74\\u56DB\\u6708\\u4E8C\\u65E5"),
3901                                                            CharsToUnicodeString("\\u58EC\\u8FB0\\u5E74\\u95F0\\u56DB\\u6708\\u4E8C\\u65E5"),
3902                                                            CharsToUnicodeString("\\u58EC\\u8FB0\\u5E74\\u4E94\\u6708\\u4E8C\\u65E5") } },
3903        { "zh@calendar=chinese",      DateFormat::kShort, { CharsToUnicodeString("\\u58EC\\u8FB0-4-2"),
3904                                                            CharsToUnicodeString("\\u58EC\\u8FB0-\\u95F04-2"),
3905                                                            CharsToUnicodeString("\\u58EC\\u8FB0-5-2") } },
3906        { "zh@calendar=chinese",      -3,                 { CharsToUnicodeString("\\u58EC\\u8FB0-4-2"),
3907                                                            CharsToUnicodeString("\\u58EC\\u8FB0-\\u95F04-2"),
3908                                                            CharsToUnicodeString("\\u58EC\\u8FB0-5-2") } },
3909        { "zh@calendar=chinese",      -4,                 { CharsToUnicodeString("\\u58EC\\u8FB0 \\u56DB\\u6708 2"),
3910                                                            CharsToUnicodeString("\\u58EC\\u8FB0 \\u95F0\\u56DB\\u6708 2"),
3911                                                            CharsToUnicodeString("\\u58EC\\u8FB0 \\u4E94\\u6708 2") } },
3912        { "zh_Hant@calendar=chinese", DateFormat::kLong,  { CharsToUnicodeString("\\u58EC\\u8FB0\\u5E74\\u56DB\\u6708\\u4E8C\\u65E5"),
3913                                                            CharsToUnicodeString("\\u58EC\\u8FB0\\u5E74\\u958F\\u56DB\\u6708\\u4E8C\\u65E5"),
3914                                                            CharsToUnicodeString("\\u58EC\\u8FB0\\u5E74\\u4E94\\u6708\\u4E8C\\u65E5") } },
3915        { "zh_Hant@calendar=chinese", DateFormat::kShort, { CharsToUnicodeString("\\u58EC\\u8FB0/4/2"),
3916                                                            CharsToUnicodeString("\\u58EC\\u8FB0/\\u958F4/2"),
3917                                                            CharsToUnicodeString("\\u58EC\\u8FB0/5/2") } },
3918        { "fr@calendar=chinese",      DateFormat::kLong,  { CharsToUnicodeString("2 s\\u00ECyu\\u00E8 ren-chen"),
3919                                                            CharsToUnicodeString("2 s\\u00ECyu\\u00E8bis ren-chen"),
3920                                                            CharsToUnicodeString("2 w\\u01D4yu\\u00E8 ren-chen") } },
3921        { "fr@calendar=chinese",      DateFormat::kShort, { UnicodeString("2/4/29"),        UnicodeString("2/4bis/29"),             UnicodeString("2/5/29") } },
3922        { "en@calendar=dangi",        DateFormat::kLong,  { UnicodeString("3bis 2, 29"), UnicodeString("4 2, 29"),      UnicodeString("5 1, 29") } }, // Google Patch. CLDR ticket #5932
3923        { "en@calendar=dangi",        DateFormat::kShort, { UnicodeString("3bis/2/29"),        UnicodeString("4/2/29"),             UnicodeString("5/1/29") } },
3924        { "ko@calendar=dangi",        DateFormat::kLong,  { CharsToUnicodeString("\\uC784\\uC9C4\\uB144 3bis\\uC6D4 2\\uC77C"),
3925                                                            CharsToUnicodeString("\\uC784\\uC9C4\\uB144 4\\uC6D4 2\\uC77C"),
3926                                                            CharsToUnicodeString("\\uC784\\uC9C4\\uB144 5\\uC6D4 1\\uC77C") } },
3927        { "ko@calendar=dangi",        DateFormat::kShort, { CharsToUnicodeString("29. 3bis. 2."),
3928                                                            CharsToUnicodeString("29. 4. 2."),
3929                                                            CharsToUnicodeString("29. 5. 1.") } },
3930        // terminator
3931        { NULL,                       0,                  { UnicodeString(""), UnicodeString(""), UnicodeString("") } }
3932    };
3933
3934    //.                               style: -1        -2            -3       -4
3935    const UnicodeString customPatterns[] = { "y-Ml-d", "G'x'y-Ml-d", "U-M-d", "U MMM d" }; // like old root pattern, using 'l'
3936
3937    UErrorCode status = U_ZERO_ERROR;
3938    Locale rootChineseCalLocale = Locale::createFromName("root@calendar=chinese");
3939    Calendar * rootChineseCalendar = Calendar::createInstance(rootChineseCalLocale, status);
3940    if (U_SUCCESS(status)) {
3941        const MonthPatternItem * itemPtr;
3942        for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
3943            Locale locale = Locale::createFromName(itemPtr->locale);
3944            DateFormat * dmft = (itemPtr->style >= 0)?
3945                    DateFormat::createDateInstance((DateFormat::EStyle)itemPtr->style, locale):
3946                    new SimpleDateFormat(customPatterns[-itemPtr->style - 1], locale, status);
3947            if ( dmft != NULL ) {
3948                if (U_SUCCESS(status)) {
3949                    const ChineseCalTestDate * datePtr = dates;
3950                    int32_t idate;
3951                    for (idate = 0; idate < NUM_TEST_DATES; idate++, datePtr++) {
3952                        rootChineseCalendar->clear();
3953                        rootChineseCalendar->set(UCAL_ERA, datePtr->era);
3954                        rootChineseCalendar->set(datePtr->year, datePtr->month-1, datePtr->day);
3955                        rootChineseCalendar->set(UCAL_IS_LEAP_MONTH, datePtr->isLeapMonth);
3956                        UnicodeString result;
3957                        FieldPosition fpos(0);
3958                        dmft->format(*rootChineseCalendar, result, fpos);
3959                        if ( result.compare(itemPtr->dateString[idate]) != 0 ) {
3960                            errln( UnicodeString("FAIL: Chinese calendar format for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
3961                                    ", expected \"" + itemPtr->dateString[idate] + "\", got \"" + result + "\"");
3962                        } else {
3963                            // formatted OK, try parse
3964                            ParsePosition ppos(0);
3965                            // ensure we are really parsing the fields we should be
3966                            rootChineseCalendar->set(UCAL_YEAR, 1);
3967                            rootChineseCalendar->set(UCAL_MONTH, 0);
3968                            rootChineseCalendar->set(UCAL_IS_LEAP_MONTH, 0);
3969                            rootChineseCalendar->set(UCAL_DATE, 1);
3970                            //
3971                            dmft->parse(result, *rootChineseCalendar, ppos);
3972                            int32_t year = rootChineseCalendar->get(UCAL_YEAR, status);
3973                            int32_t month = rootChineseCalendar->get(UCAL_MONTH, status) + 1;
3974                            int32_t isLeapMonth = rootChineseCalendar->get(UCAL_IS_LEAP_MONTH, status);
3975                            int32_t day = rootChineseCalendar->get(UCAL_DATE, status);
3976                            if ( ppos.getIndex() < result.length() || year != datePtr->year || month != datePtr->month || isLeapMonth != datePtr->isLeapMonth || day != datePtr->day ) {
3977                                errln( UnicodeString("FAIL: Chinese calendar parse for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
3978                                    ", string \"" + result + "\", expected " + datePtr->year +"-"+datePtr->month+"("+datePtr->isLeapMonth+")-"+datePtr->day + ", got pos " +
3979                                    ppos.getIndex() + " " + year +"-"+month+"("+isLeapMonth+")-"+day);
3980                            }
3981                        }
3982                    }
3983                } else {
3984                    dataerrln("Error creating SimpleDateFormat for Chinese calendar- %s", u_errorName(status));
3985                }
3986                delete dmft;
3987            } else {
3988                dataerrln("FAIL: Unable to create DateFormat for Chinese calendar- %s", u_errorName(status));
3989            }
3990        }
3991        delete rootChineseCalendar;
3992    } else {
3993        errln(UnicodeString("FAIL: Unable to create Calendar for root@calendar=chinese"));
3994    }
3995}
3996
3997typedef struct {
3998    const char * locale;
3999    UnicodeString pattern;
4000    UDisplayContext capitalizationContext;
4001    UnicodeString expectedFormat;
4002} TestContextItem;
4003
4004void DateFormatTest::TestContext()
4005{
4006    const UDate july022008 = 1215000001979.0;
4007    const TestContextItem items[] = {
4008        //locale              pattern    capitalizationContext                              expected formatted date
4009        { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_NONE,                      UnicodeString("juillet 2008") },
4010#if !UCONFIG_NO_BREAK_ITERATION
4011        { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE,    UnicodeString("juillet 2008") },
4012        { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UnicodeString("Juillet 2008") },
4013        { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU,       UnicodeString("juillet 2008") },
4014        { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_STANDALONE,            UnicodeString("Juillet 2008") },
4015#endif
4016        { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_NONE,                      CharsToUnicodeString("\\u010Dervenec 2008") },
4017#if !UCONFIG_NO_BREAK_ITERATION
4018        { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE,    CharsToUnicodeString("\\u010Dervenec 2008") },
4019        { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, CharsToUnicodeString("\\u010Cervenec 2008") },
4020        { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU,       CharsToUnicodeString("\\u010Cervenec 2008") },
4021        { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_STANDALONE,            CharsToUnicodeString("\\u010Dervenec 2008") },
4022#endif
4023        // terminator
4024        { NULL, UnicodeString(""),       (UDisplayContext)0, UnicodeString("") }
4025    };
4026    UErrorCode status = U_ZERO_ERROR;
4027    Calendar* cal = Calendar::createInstance(status);
4028    if (U_FAILURE(status)) {
4029        dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale."));
4030    } else {
4031        cal->setTime(july022008, status);
4032        const TestContextItem * itemPtr;
4033        for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
4034           Locale locale = Locale::createFromName(itemPtr->locale);
4035           status = U_ZERO_ERROR;
4036           SimpleDateFormat * sdmft = new SimpleDateFormat(itemPtr->pattern, locale, status);
4037           if (U_FAILURE(status)) {
4038                dataerrln(UnicodeString("FAIL: Unable to create SimpleDateFormat for specified pattern with locale ") + UnicodeString(itemPtr->locale));
4039           } else {
4040               sdmft->setContext(itemPtr->capitalizationContext, status);
4041               UnicodeString result;
4042               FieldPosition pos(0);
4043               sdmft->format(*cal, result, pos);
4044               if (result.compare(itemPtr->expectedFormat) != 0) {
4045                   errln(UnicodeString("FAIL: format for locale ") + UnicodeString(itemPtr->locale) +
4046                           ", status " + (int)status +
4047                           ", capitalizationContext " + (int)itemPtr->capitalizationContext +
4048                           ", expected " + itemPtr->expectedFormat + ", got " + result);
4049               }
4050           }
4051           if (sdmft) {
4052               delete sdmft;
4053           }
4054        }
4055    }
4056    if (cal) {
4057        delete cal;
4058    }
4059}
4060
4061// test item for a particular locale + calendar and date format
4062typedef struct {
4063    int32_t year;
4064    int32_t month;
4065    int32_t day;
4066    int32_t hour;
4067    int32_t minute;
4068    UnicodeString formattedDate;
4069} CalAndFmtTestItem;
4070
4071// test item giving locale + calendar, date format, and CalAndFmtTestItems
4072typedef struct {
4073    const char * locale; // with calendar
4074    DateFormat::EStyle style;
4075    const CalAndFmtTestItem *caftItems;
4076} TestNonGregoItem;
4077
4078void DateFormatTest::TestNonGregoFmtParse()
4079{
4080    // test items for he@calendar=hebrew, long date format
4081    const CalAndFmtTestItem cafti_he_hebrew_long[] = {
4082        { 4999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05D3\\u05F3\\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") },
4083        { 5100,  0,  1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05E7\\u05F3") },
4084        { 5774,  5,  1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05D0\\u05D3\\u05E8 \\u05D0\\u05F3 \\u05EA\\u05E9\\u05E2\\u05F4\\u05D3") },
4085        { 5999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") },
4086        { 6100,  0,  1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05D5\\u05F3\\u05E7\\u05F3") },
4087        {    0,  0,  0,  0, 0, UnicodeString("") } // terminator
4088    };
4089    // overal test items
4090    const TestNonGregoItem items[] = {
4091        { "he@calendar=hebrew", DateFormat::kLong, cafti_he_hebrew_long },
4092        { NULL, DateFormat::kNone, NULL } // terminator
4093    };
4094    const TestNonGregoItem * itemPtr;
4095    for (itemPtr = items; itemPtr->locale != NULL; itemPtr++) {
4096        Locale locale = Locale::createFromName(itemPtr->locale);
4097        DateFormat * dfmt = DateFormat::createDateInstance(itemPtr->style, locale);
4098        if (dfmt == NULL) {
4099            dataerrln("DateFormat::createDateInstance fails for locale %s", itemPtr->locale);
4100        } else {
4101            Calendar * cal = (dfmt->getCalendar())->clone();
4102            if (cal == NULL) {
4103                dataerrln("(DateFormat::getCalendar)->clone() fails for locale %s", itemPtr->locale);
4104            } else {
4105                const CalAndFmtTestItem * caftItemPtr;
4106                for (caftItemPtr = itemPtr->caftItems; caftItemPtr->year != 0; caftItemPtr++) {
4107                    cal->clear();
4108                    cal->set(UCAL_YEAR,   caftItemPtr->year);
4109                    cal->set(UCAL_MONTH,  caftItemPtr->month);
4110                    cal->set(UCAL_DATE,   caftItemPtr->day);
4111                    cal->set(UCAL_HOUR_OF_DAY, caftItemPtr->hour);
4112                    cal->set(UCAL_MINUTE, caftItemPtr->minute);
4113                    UnicodeString result;
4114                    FieldPosition fpos(0);
4115                    dfmt->format(*cal, result, fpos);
4116                    if ( result.compare(caftItemPtr->formattedDate) != 0 ) {
4117                        errln( UnicodeString("FAIL: date format for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
4118                                ", expected \"" + caftItemPtr->formattedDate + "\", got \"" + result + "\"");
4119                    } else {
4120                        // formatted OK, try parse
4121                        ParsePosition ppos(0);
4122                        dfmt->parse(result, *cal, ppos);
4123                        UErrorCode status = U_ZERO_ERROR;
4124                        int32_t year = cal->get(UCAL_YEAR, status);
4125                        int32_t month = cal->get(UCAL_MONTH, status);
4126                        int32_t day = cal->get(UCAL_DATE, status);
4127                        if ( U_FAILURE(status) || ppos.getIndex() < result.length() || year != caftItemPtr->year || month != caftItemPtr->month || day != caftItemPtr->day ) {
4128                            errln( UnicodeString("FAIL: date parse for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
4129                                ", string \"" + result + "\", expected " + caftItemPtr->year +"-"+caftItemPtr->month+"-"+caftItemPtr->day + ", got pos " +
4130                                ppos.getIndex() + " " + year +"-"+month+"-"+day + " status " + UnicodeString(u_errorName(status)) );
4131                        }
4132                    }
4133                }
4134                delete cal;
4135            }
4136            delete dfmt;
4137        }
4138    }
4139}
4140
4141static const UDate TEST_DATE = 1326585600000.;  // 2012-jan-15
4142
4143void DateFormatTest::TestDotAndAtLeniency() {
4144    // Test for date/time parsing regression with CLDR 22.1/ICU 50 pattern strings.
4145    // For details see http://bugs.icu-project.org/trac/ticket/9789
4146    static const char *locales[] = { "en", "fr" };
4147    for (int32_t i = 0; i < LENGTHOF(locales); ++i) {
4148        Locale locale(locales[i]);
4149
4150        for (DateFormat::EStyle dateStyle = DateFormat::FULL; dateStyle <= DateFormat::SHORT;
4151                  dateStyle = static_cast<DateFormat::EStyle>(dateStyle + 1)) {
4152            LocalPointer<DateFormat> dateFormat(DateFormat::createDateInstance(dateStyle, locale));
4153
4154            for (DateFormat::EStyle timeStyle = DateFormat::FULL; timeStyle <= DateFormat::SHORT;
4155                      timeStyle = static_cast<DateFormat::EStyle>(timeStyle + 1)) {
4156                LocalPointer<DateFormat> format(DateFormat::createDateTimeInstance(dateStyle, timeStyle, locale));
4157                LocalPointer<DateFormat> timeFormat(DateFormat::createTimeInstance(timeStyle, locale));
4158                UnicodeString formattedString;
4159                if (format.isNull()) {
4160                    dataerrln("Unable to create DateFormat");
4161                    continue;
4162                }
4163                format->format(TEST_DATE, formattedString);
4164
4165                if (!showParse(*format, formattedString)) {
4166                    errln(UnicodeString("    with date-time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle);
4167                }
4168
4169                UnicodeString ds, ts;
4170                formattedString = dateFormat->format(TEST_DATE, ds) + "  " + timeFormat->format(TEST_DATE, ts);
4171                if (!showParse(*format, formattedString)) {
4172                    errln(UnicodeString("    with date sp sp time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle);
4173                }
4174                if (formattedString.indexOf("n ") >= 0) { // will add "." after the end of text ending in 'n', like Jan.
4175                    UnicodeString plusDot(formattedString);
4176                    plusDot.findAndReplace("n ", "n. ").append(".");
4177                    if (!showParse(*format, plusDot)) {
4178                        errln(UnicodeString("    with date plus-dot time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle);
4179                    }
4180                }
4181                if (formattedString.indexOf(". ") >= 0) { // will subtract "." at the end of strings.
4182                    UnicodeString minusDot(formattedString);
4183                    minusDot.findAndReplace(". ", " ");
4184                    if (!showParse(*format, minusDot)) {
4185                        errln(UnicodeString("    with date minus-dot time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle);
4186                    }
4187                }
4188            }
4189        }
4190    }
4191}
4192
4193UBool DateFormatTest::showParse(DateFormat &format, const UnicodeString &formattedString) {
4194    ParsePosition parsePosition;
4195    UDate parsed = format.parse(formattedString, parsePosition);
4196    UBool ok = TEST_DATE == parsed && parsePosition.getIndex() == formattedString.length();
4197    UnicodeString pattern;
4198    static_cast<SimpleDateFormat &>(format).toPattern(pattern);
4199    if (ok) {
4200        logln(pattern + "  parsed: " + formattedString);
4201    } else {
4202        errln(pattern + "  fails to parse: " + formattedString);
4203    }
4204    return ok;
4205}
4206
4207#endif /* #if !UCONFIG_NO_FORMATTING */
4208
4209//eof
4210