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