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