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