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