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