1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2016, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 ********************************************************************/
9 #include "unicode/utypes.h"
11 #if !UCONFIG_NO_FORMATTING
14 #include "unicode/localpointer.h"
15 #include "unicode/timezone.h"
16 #include "unicode/gregocal.h"
17 #include "unicode/smpdtfmt.h"
18 #include "unicode/datefmt.h"
19 #include "unicode/dtptngen.h"
20 #include "unicode/simpletz.h"
21 #include "unicode/strenum.h"
22 #include "unicode/dtfmtsym.h"
25 #include "caltest.h" // for fieldName
26 #include <stdio.h> // for sprintf
28 #if U_PLATFORM_HAS_WIN32_API
32 #define ASSERT_OK(status) if(U_FAILURE(status)) {errcheckln(status, #status " = %s @ %s:%d", u_errorName(status), __FILE__, __LINE__); return; }
34 // *****************************************************************************
35 // class DateFormatTest
36 // *****************************************************************************
38 void DateFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
41 logln("TestSuite DateFormatTest: ");
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 TESTCASE_AUTO(TestFormatsWithNumberSystems);
101 TESTCASE_AUTO(TestRelativeError);
102 TESTCASE_AUTO(TestRelativeOther);
104 TESTCASE_AUTO(TestDotAndAtLeniency);
105 TESTCASE_AUTO(TestDateFormatLeniency);
106 TESTCASE_AUTO(TestParseMultiPatternMatch);
108 TESTCASE_AUTO(TestParseLeniencyAPIs);
109 TESTCASE_AUTO(TestNumberFormatOverride);
110 TESTCASE_AUTO(TestCreateInstanceForSkeleton);
111 TESTCASE_AUTO(TestCreateInstanceForSkeletonDefault);
112 TESTCASE_AUTO(TestCreateInstanceForSkeletonWithCalendar);
113 TESTCASE_AUTO(TestDFSCreateForLocaleNonGregorianLocale);
114 TESTCASE_AUTO(TestDFSCreateForLocaleWithCalendarInLocale);
115 TESTCASE_AUTO(TestChangeCalendar);
117 TESTCASE_AUTO(TestPatternFromSkeleton);
119 TESTCASE_AUTO(TestAmPmMidnightNoon);
120 TESTCASE_AUTO(TestFlexibleDayPeriod);
121 TESTCASE_AUTO(TestDayPeriodWithLocales);
122 TESTCASE_AUTO(TestMinuteSecondFieldsInOddPlaces);
123 TESTCASE_AUTO(TestDayPeriodParsing);
128 void DateFormatTest::TestPatterns() {
129 static const struct {
130 const char *actualPattern;
131 const char *expectedPattern;
132 const char *localeID;
133 const char *expectedLocalPattern;
135 {UDAT_YEAR, "y","en","y"},
137 {UDAT_QUARTER, "QQQQ", "en", "QQQQ"},
138 {UDAT_ABBR_QUARTER, "QQQ", "en", "QQQ"},
139 {UDAT_YEAR_QUARTER, "yQQQQ", "en", "QQQQ y"},
140 {UDAT_YEAR_ABBR_QUARTER, "yQQQ", "en", "QQQ y"},
142 {UDAT_NUM_MONTH, "M", "en", "L"},
143 {UDAT_ABBR_MONTH, "MMM", "en", "LLL"},
144 {UDAT_MONTH, "MMMM", "en", "LLLL"},
145 {UDAT_YEAR_NUM_MONTH, "yM","en","M/y"},
146 {UDAT_YEAR_ABBR_MONTH, "yMMM","en","MMM y"},
147 {UDAT_YEAR_MONTH, "yMMMM","en","MMMM y"},
149 {UDAT_DAY, "d","en","d"},
150 {UDAT_YEAR_NUM_MONTH_DAY, "yMd", "en", "M/d/y"},
151 {UDAT_YEAR_ABBR_MONTH_DAY, "yMMMd", "en", "MMM d, y"},
152 {UDAT_YEAR_MONTH_DAY, "yMMMMd", "en", "MMMM d, y"},
153 {UDAT_YEAR_NUM_MONTH_WEEKDAY_DAY, "yMEd", "en", "EEE, M/d/y"},
154 {UDAT_YEAR_ABBR_MONTH_WEEKDAY_DAY, "yMMMEd", "en", "EEE, MMM d, y"},
155 {UDAT_YEAR_MONTH_WEEKDAY_DAY, "yMMMMEEEEd", "en", "EEEE, MMMM d, y"},
157 {UDAT_NUM_MONTH_DAY, "Md","en","M/d"},
158 {UDAT_ABBR_MONTH_DAY, "MMMd","en","MMM d"},
159 {UDAT_MONTH_DAY, "MMMMd","en","MMMM d"},
160 {UDAT_NUM_MONTH_WEEKDAY_DAY, "MEd","en","EEE, M/d"},
161 {UDAT_ABBR_MONTH_WEEKDAY_DAY, "MMMEd","en","EEE, MMM d"},
162 {UDAT_MONTH_WEEKDAY_DAY, "MMMMEEEEd","en","EEEE, MMMM d"},
164 {UDAT_HOUR, "j", "en", "h a"}, // (fixed expected result per ticket 6872<-6626)
165 {UDAT_HOUR24, "H", "en", "HH"}, // (fixed expected result per ticket 6872<-6626
167 {UDAT_MINUTE, "m", "en", "m"},
168 {UDAT_HOUR_MINUTE, "jm","en","h:mm a"}, // (fixed expected result per ticket 6872<-7180)
169 {UDAT_HOUR24_MINUTE, "Hm", "en", "HH:mm"}, // (fixed expected result per ticket 6872<-6626)
171 {UDAT_SECOND, "s", "en", "s"},
172 {UDAT_HOUR_MINUTE_SECOND, "jms","en","h:mm:ss a"}, // (fixed expected result per ticket 6872<-7180)
173 {UDAT_HOUR24_MINUTE_SECOND, "Hms","en","HH:mm:ss"}, // (fixed expected result per ticket 6872<-6626)
174 {UDAT_MINUTE_SECOND, "ms", "en", "mm:ss"}, // (fixed expected result per ticket 6872<-6626)
176 {UDAT_LOCATION_TZ, "VVVV", "en", "VVVV"},
177 {UDAT_GENERIC_TZ, "vvvv", "en", "vvvv"},
178 {UDAT_ABBR_GENERIC_TZ, "v", "en", "v"},
179 {UDAT_SPECIFIC_TZ, "zzzz", "en", "zzzz"},
180 {UDAT_ABBR_SPECIFIC_TZ, "z", "en", "z"},
181 {UDAT_ABBR_UTC_TZ, "ZZZZ", "en", "ZZZZ"},
183 {UDAT_YEAR_NUM_MONTH_DAY UDAT_ABBR_UTC_TZ, "yMdZZZZ", "en", "M/d/y, ZZZZ"},
184 {UDAT_MONTH_DAY UDAT_LOCATION_TZ, "MMMMdVVVV", "en", "MMMM d, VVVV"}
187 IcuTestErrorCode errorCode(*this, "TestPatterns()");
188 for (int32_t i = 0; i < UPRV_LENGTHOF(EXPECTED); i++) {
189 // Verify that patterns have the correct values
190 UnicodeString actualPattern(EXPECTED[i].actualPattern, -1, US_INV);
191 UnicodeString expectedPattern(EXPECTED[i].expectedPattern, -1, US_INV);
192 Locale locale(EXPECTED[i].localeID);
193 if (actualPattern != expectedPattern) {
194 errln("FAILURE! Expected pattern: " + expectedPattern +
195 " but was: " + actualPattern);
198 // Verify that DataFormat instances produced contain the correct
199 // localized patterns
200 // TODO: use DateFormat::getInstanceForSkeleton(), ticket #9029
202 // DateFormat date1 = DateFormat.getPatternInstance(actualPattern,
204 // DateFormat date2 = DateFormat.getPatternInstance(Calendar.getInstance(locale),
205 // actualPattern, locale);
206 LocalPointer<DateTimePatternGenerator> generator(
207 DateTimePatternGenerator::createInstance(locale, errorCode));
208 if(errorCode.logDataIfFailureAndReset("DateTimePatternGenerator::createInstance() failed for locale ID \"%s\"", EXPECTED[i].localeID)) {
211 UnicodeString pattern = generator->getBestPattern(actualPattern, errorCode);
212 SimpleDateFormat date1(pattern, locale, errorCode);
213 SimpleDateFormat date2(pattern, locale, errorCode);
214 date2.adoptCalendar(Calendar::createInstance(locale, errorCode));
215 if(errorCode.logIfFailureAndReset("DateFormat::getInstanceForSkeleton() failed")) {
216 errln(" for actualPattern \"%s\" & locale ID \"%s\"",
217 EXPECTED[i].actualPattern, EXPECTED[i].localeID);
221 UnicodeString expectedLocalPattern(EXPECTED[i].expectedLocalPattern, -1, US_INV);
222 UnicodeString actualLocalPattern1;
223 UnicodeString actualLocalPattern2;
224 date1.toLocalizedPattern(actualLocalPattern1, errorCode);
225 date2.toLocalizedPattern(actualLocalPattern2, errorCode);
226 if (actualLocalPattern1 != expectedLocalPattern) {
227 errln("FAILURE! Expected local pattern: " + expectedLocalPattern
228 + " but was: " + actualLocalPattern1);
230 if (actualLocalPattern2 != expectedLocalPattern) {
231 errln("FAILURE! Expected local pattern: " + expectedLocalPattern
232 + " but was: " + actualLocalPattern2);
237 // Test written by Wally Wedel and emailed to me.
238 void DateFormatTest::TestWallyWedel()
240 UErrorCode status = U_ZERO_ERROR;
242 * Instantiate a TimeZone so we can get the ids.
244 TimeZone *tz = new SimpleTimeZone(7,"");
246 * Computational variables.
248 int32_t offset, hours, minutes, seconds;
250 * Instantiate a SimpleDateFormat set up to produce a full time
253 SimpleDateFormat *sdf = new SimpleDateFormat((UnicodeString)"zzzz", status);
255 * A String array for the time zone ids.
258 StringEnumeration* ids = TimeZone::createEnumeration();
260 dataerrln("Unable to create TimeZone enumeration.");
266 ids_length = ids->count(status);
268 * How many ids do we have?
270 logln("Time Zone IDs size: %d", ids_length);
272 * Column headings (sort of)
274 logln("Ordinal ID offset(h:m) name");
276 * Loop through the tzs.
278 UDate today = Calendar::getNow();
279 Calendar *cal = Calendar::createInstance(status);
280 for (int32_t i = 0; i < ids_length; i++) {
281 // logln(i + " " + ids[i]);
282 const UnicodeString* id = ids->snext(status);
283 TimeZone *ttz = TimeZone::createTimeZone(*id);
284 // offset = ttz.getRawOffset();
285 cal->setTimeZone(*ttz);
286 cal->setTime(today, status);
287 offset = cal->get(UCAL_ZONE_OFFSET, status) + cal->get(UCAL_DST_OFFSET, status);
288 // logln(i + " " + ids[i] + " offset " + offset);
289 const char* sign = "+";
294 hours = offset/3600000;
295 minutes = (offset%3600000)/60000;
296 seconds = (offset%60000)/1000;
297 UnicodeString dstOffset = (UnicodeString)"" + sign + (hours < 10 ? "0" : "") +
298 (int32_t)hours + ":" + (minutes < 10 ? "0" : "") + (int32_t)minutes;
300 dstOffset = dstOffset + ":" + (seconds < 10 ? "0" : "") + seconds;
303 * Instantiate a date so we can display the time zone name.
305 sdf->setTimeZone(*ttz);
309 UnicodeString fmtOffset;
310 FieldPosition pos(FieldPosition::DONT_CARE);
311 sdf->format(today,fmtOffset, pos);
312 // UnicodeString fmtOffset = tzS.toString();
313 UnicodeString *fmtDstOffset = 0;
314 if (fmtOffset.startsWith("GMT") && fmtOffset.length() != 3)
316 //fmtDstOffset = fmtOffset->substring(3);
317 fmtDstOffset = new UnicodeString();
318 fmtOffset.extract(3, fmtOffset.length(), *fmtDstOffset);
323 UBool ok = fmtDstOffset == 0 || *fmtDstOffset == dstOffset;
326 logln(UnicodeString() + i + " " + *id + " " + dstOffset +
328 (fmtDstOffset != 0 ? " ok" : " ?"));
332 errln(UnicodeString() + i + " " + *id + " " + dstOffset +
333 " " + fmtOffset + " *** FAIL ***");
339 // delete ids; // TODO: BAD API
345 // -------------------------------------
351 DateFormatTest::TestEquals()
353 DateFormat* fmtA = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL);
354 DateFormat* fmtB = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL);
355 if ( fmtA == NULL || fmtB == NULL){
356 dataerrln("Error calling DateFormat::createDateTimeInstance");
362 if (!(*fmtA == *fmtB)) errln((UnicodeString)"FAIL");
366 TimeZone* test = TimeZone::createTimeZone("PDT");
370 // -------------------------------------
373 * Test the parsing of 2-digit years.
376 DateFormatTest::TestTwoDigitYearDSTParse(void)
378 UErrorCode status = U_ZERO_ERROR;
379 SimpleDateFormat* fullFmt = new SimpleDateFormat((UnicodeString)"EEE MMM dd HH:mm:ss.SSS zzz yyyy G", status);
380 SimpleDateFormat *fmt = new SimpleDateFormat((UnicodeString)"dd-MMM-yy h:mm:ss 'o''clock' a z", Locale::getEnglish(), status);
381 //DateFormat* fmt = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL, Locale::ENGLISH);
382 UnicodeString* s = new UnicodeString("03-Apr-04 2:20:47 o'clock AM PST", "");
383 TimeZone* defaultTZ = TimeZone::createDefault();
384 TimeZone* PST = TimeZone::createTimeZone("PST");
385 int32_t defaultOffset = defaultTZ->getRawOffset();
386 int32_t PSTOffset = PST->getRawOffset();
387 int32_t hour = 2 + (defaultOffset - PSTOffset) / (60*60*1000);
388 // hour is the expected hour of day, in units of seconds
389 hour = ((hour < 0) ? hour + 24 : hour) * 60*60;
393 if(U_FAILURE(status)) {
394 dataerrln("Could not set up test. exitting - %s", u_errorName(status));
398 UDate d = fmt->parse(*s, status);
399 logln(*s + " P> " + ((DateFormat*)fullFmt)->format(d, str));
400 int32_t y, m, day, hr, min, sec;
401 dateToFields(d, y, m, day, hr, min, sec);
402 hour += defaultTZ->inDaylightTime(d, status) ? 1 : 0;
405 errln((UnicodeString)"FAIL: Should parse to hour " + hour + " but got " + hr);
407 if (U_FAILURE(status))
408 errln((UnicodeString)"FAIL: " + (int32_t)status);
417 // -------------------------------------
419 UChar toHexString(int32_t i) { return (UChar)(i + (i < 10 ? 0x30 : (0x41 - 10))); }
422 DateFormatTest::escape(UnicodeString& s)
425 for (int32_t i=0; i<s.length(); ++i)
427 UChar c = s[(int32_t)i];
428 if (c <= (UChar)0x7F) buf += c;
430 buf += (UChar)0x5c; buf += (UChar)0x55;
431 buf += toHexString((c & 0xF000) >> 12);
432 buf += toHexString((c & 0x0F00) >> 8);
433 buf += toHexString((c & 0x00F0) >> 4);
434 buf += toHexString(c & 0x000F);
440 // -------------------------------------
443 * This MUST be kept in sync with DateFormatSymbols.gPatternChars.
445 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
446 static const char* PATTERN_CHARS = "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB:";
448 static const char* PATTERN_CHARS = "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB";
452 * A list of the names of all the fields in DateFormat.
453 * This MUST be kept in sync with DateFormat.
455 static const char* DATEFORMAT_FIELD_NAMES[] = {
460 "HOUR_OF_DAY1_FIELD",
461 "HOUR_OF_DAY0_FIELD",
467 "DAY_OF_WEEK_IN_MONTH_FIELD",
468 "WEEK_OF_YEAR_FIELD",
469 "WEEK_OF_MONTH_FIELD",
476 "EXTENDED_YEAR_FIELD",
478 "MILLISECONDS_IN_DAY_FIELD",
479 "TIMEZONE_RFC_FIELD",
480 "GENERIC_TIMEZONE_FIELD",
481 "STAND_ALONE_DAY_FIELD",
482 "STAND_ALONE_MONTH_FIELD",
484 "STAND_ALONE_QUARTER_FIELD",
485 "TIMEZONE_SPECIAL_FIELD",
487 "TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD",
488 "TIMEZONE_ISO_FIELD",
489 "TIMEZONE_ISO_LOCAL_FIELD",
490 "RELATED_YEAR_FIELD",
491 "AM_PM_MIDNIGHT_NOON_FIELD",
492 "FLEXIBLE_DAY_PERIOD_FIELD",
493 "UDAT_TIME_SEPARATOR_FIELD",
496 static const int32_t DATEFORMAT_FIELD_NAMES_LENGTH =
497 UPRV_LENGTHOF(DATEFORMAT_FIELD_NAMES);
500 * Verify that returned field position indices are correct.
502 void DateFormatTest::TestFieldPosition() {
503 UErrorCode ec = U_ZERO_ERROR;
508 DateFormatSymbols rootSyms(Locale(""), ec);
510 dataerrln("Unable to create DateFormatSymbols - %s", u_errorName(ec));
514 // local pattern chars data is not longer loaded
515 // from icu locale bundle
516 assertEquals("patternChars", PATTERN_CHARS, rootSyms.getLocalPatternChars(buf));
517 assertEquals("patternChars", PATTERN_CHARS, DateFormatSymbols::getPatternUChars());
518 assertTrue("DATEFORMAT_FIELD_NAMES", DATEFORMAT_FIELD_NAMES_LENGTH == UDAT_FIELD_COUNT);
519 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
520 assertTrue("Data", UDAT_FIELD_COUNT == uprv_strlen(PATTERN_CHARS));
522 assertTrue("Data", UDAT_FIELD_COUNT == uprv_strlen(PATTERN_CHARS) + 1); // +1 for missing TIME_SEPARATOR pattern char
525 // Create test formatters
526 const int32_t COUNT = 4;
527 DateFormat* dateFormats[COUNT];
528 dateFormats[0] = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale::getUS());
529 dateFormats[1] = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale::getFrance());
530 // Make the pattern "G y M d..."
531 buf.remove().append(PATTERN_CHARS);
532 for (j=buf.length()-1; j>=0; --j) buf.insert(j, (UChar)32/*' '*/);
533 dateFormats[2] = new SimpleDateFormat(buf, Locale::getUS(), ec);
534 // Make the pattern "GGGG yyyy MMMM dddd..."
535 for (j=buf.length()-1; j>=0; j-=2) {
536 for (i=0; i<3; ++i) {
537 buf.insert(j, buf.charAt(j));
540 dateFormats[3] = new SimpleDateFormat(buf, Locale::getUS(), ec);
542 errln(UnicodeString("Could not create SimpleDateFormat object for locale en_US. Error: " )+ UnicodeString(u_errorName(ec)));
545 UDate aug13 = 871508052513.0;
547 // Expected output field values for above DateFormats on aug13
548 // Fields are given in order of DateFormat field number
549 const char* EXPECTED[] = {
550 "", "1997", "August", "13", "", "", "34", "12", "", "Wednesday",
551 "", "", "", "", "PM", "2", "", "Pacific Daylight Time", "", "",
552 "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
553 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
559 "", "1997", "ao\\u00FBt", "13", "", "14", "34", "12", "", "mercredi",
560 "", "", "", "", "", "", "", "heure d\\u2019\\u00E9t\\u00E9 du Pacifique", "", "",
561 "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
562 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
568 "AD", "1997", "8", "13", "14", "14", "34", "12", "5", "Wed",
569 "225", "2", "33", "3", "PM", "2", "2", "PDT", "1997", "4",
570 "1997", "2450674", "52452513", "-0700", "PT", "4", "8", "3", "3", "uslax",
571 "1997", "GMT-7", "-07", "-07", "1997", "PM", "in the afternoon",
572 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
578 "Anno Domini", "1997", "August", "0013", "0014", "0014", "0034", "0012", "5130", "Wednesday",
579 "0225", "0002", "0033", "0003", "PM", "0002", "0002", "Pacific Daylight Time", "1997", "Wednesday",
580 "1997", "2450674", "52452513", "GMT-07:00", "Pacific Time", "Wednesday", "August", "3rd quarter", "3rd quarter", "Los Angeles Time",
581 "1997", "GMT-07:00", "-0700", "-0700", "1997", "PM", "in the afternoon",
582 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
589 const int32_t EXPECTED_LENGTH = UPRV_LENGTHOF(EXPECTED);
591 assertTrue("data size", EXPECTED_LENGTH == COUNT * UDAT_FIELD_COUNT);
593 TimeZone* PT = TimeZone::createTimeZone("America/Los_Angeles");
594 for (j = 0, exp = 0; j < COUNT; ++j) {
596 DateFormat* df = dateFormats[j];
597 df->setTimeZone(*PT);
598 SimpleDateFormat* sdtfmt = dynamic_cast<SimpleDateFormat*>(df);
599 if (sdtfmt != NULL) {
600 logln(" Pattern = " + sdtfmt->toPattern(buf.remove()));
602 logln(" Pattern = ? (not a SimpleDateFormat)");
604 logln((UnicodeString)" Result = " + df->format(aug13, buf.remove()));
606 int32_t expBase = exp; // save for later
607 for (i = 0; i < UDAT_FIELD_COUNT; ++i, ++exp) {
608 FieldPosition pos(i);
610 df->format(aug13, buf, pos);
612 buf.extractBetween(pos.getBeginIndex(), pos.getEndIndex(), field);
613 assertEquals((UnicodeString)"field #" + i + " " + DATEFORMAT_FIELD_NAMES[i],
614 ctou(EXPECTED[exp]), field);
617 // test FieldPositionIterator API
618 logln("FieldPositionIterator");
620 UErrorCode status = U_ZERO_ERROR;
621 FieldPositionIterator posIter;
625 df->format(aug13, buf, &posIter, status);
626 while (posIter.next(fp)) {
627 int32_t i = fp.getField();
629 buf.extractBetween(fp.getBeginIndex(), fp.getEndIndex(), field);
630 assertEquals((UnicodeString)"field #" + i + " " + DATEFORMAT_FIELD_NAMES[i],
631 ctou(EXPECTED[expBase + i]), field);
640 UErrorCode status = U_ZERO_ERROR;
641 dateFormats[0]->format(aug13, buf, NULL, status);
642 // if we didn't crash, we succeeded.
644 for (i=0; i<COUNT; ++i) {
645 delete dateFormats[i];
650 // -------------------------------------
653 * General parse/format tests. Add test cases as needed.
655 void DateFormatTest::TestGeneral() {
656 const char* DATA[] = {
657 "yyyy MM dd HH:mm:ss.SSS",
659 // Milliseconds are left-justified, since they format as fractions of a second
660 "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",
661 "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",
662 "y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567",
663 "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",
665 expect(DATA, UPRV_LENGTHOF(DATA), Locale("en", "", ""));
668 // -------------------------------------
671 * Verify that strings which contain incomplete specifications are parsed
672 * correctly. In some instances, this means not being parsed at all, and
673 * returning an appropriate error.
676 DateFormatTest::TestPartialParse994()
678 UErrorCode status = U_ZERO_ERROR;
679 SimpleDateFormat* f = new SimpleDateFormat(status);
680 if (U_FAILURE(status)) {
681 dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
686 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:11:42", date(97, 1 - 1, 17, 10, 11, 42));
687 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:", null);
688 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10", null);
689 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 ", null);
690 tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17", null);
691 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
695 // -------------------------------------
698 DateFormatTest::tryPat994(SimpleDateFormat* format, const char* pat, const char* str, UDate expected)
700 UErrorCode status = U_ZERO_ERROR;
702 logln(UnicodeString("Pattern \"") + pat + "\" String \"" + str + "\"");
704 format->applyPattern(pat);
705 UDate date = format->parse(str, status);
706 if (U_FAILURE(status) || date == null)
708 logln((UnicodeString)"ParseException: " + (int32_t)status);
709 if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
714 ((DateFormat*)format)->format(date, f);
715 logln(UnicodeString(" parse(") + str + ") -> " + dateToString(date));
716 logln((UnicodeString)" format -> " + f);
717 if (expected == null ||
718 !(date == expected)) errln((UnicodeString)"FAIL: Expected null");//" + expected);
719 if (!(f == str)) errln(UnicodeString("FAIL: Expected ") + str);
722 //catch(ParseException e) {
723 // logln((UnicodeString)"ParseException: " + e.getMessage());
724 // if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
726 //catch(Exception e) {
727 // errln((UnicodeString)"*** Exception:");
728 // e.printStackTrace();
732 // -------------------------------------
735 * Verify the behavior of patterns in which digits for different fields run together
736 * without intervening separators.
739 DateFormatTest::TestRunTogetherPattern985()
741 UErrorCode status = U_ZERO_ERROR;
742 UnicodeString format("yyyyMMddHHmmssSSS");
743 UnicodeString now, then;
745 SimpleDateFormat *formatter = new SimpleDateFormat(format, status);
746 if (U_FAILURE(status)) {
747 dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
751 UDate date1 = Calendar::getNow();
752 ((DateFormat*)formatter)->format(date1, now);
754 ParsePosition pos(0);
755 UDate date2 = formatter->parse(now, pos);
756 if (date2 == 0) then = UnicodeString("Parse stopped at ") + pos.getIndex();
757 else ((DateFormat*)formatter)->format(date2, then);
759 if (!(date2 == date1)) errln((UnicodeString)"FAIL");
761 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
764 // -------------------------------------
767 * Verify the behavior of patterns in which digits for different fields run together
768 * without intervening separators.
771 DateFormatTest::TestRunTogetherPattern917()
773 UErrorCode status = U_ZERO_ERROR;
774 SimpleDateFormat* fmt;
775 UnicodeString myDate;
776 fmt = new SimpleDateFormat((UnicodeString)"yyyy/MM/dd", status);
777 if (U_FAILURE(status)) {
778 dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
782 myDate = "1997/02/03";
783 testIt917(fmt, myDate, date(97, 2 - 1, 3));
785 fmt = new SimpleDateFormat((UnicodeString)"yyyyMMdd", status);
787 testIt917(fmt, myDate, date(97, 3 - 1, 4));
789 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
792 // -------------------------------------
795 DateFormatTest::testIt917(SimpleDateFormat* fmt, UnicodeString& str, UDate expected)
797 UErrorCode status = U_ZERO_ERROR;
798 UnicodeString pattern;
799 logln((UnicodeString)"pattern=" + fmt->toPattern(pattern) + " string=" + str);
802 ((Format*)fmt)->parseObject(str, o, status);
804 if (U_FAILURE(status)) return;
805 //catch(ParseException e) {
806 // e.printStackTrace();
809 logln((UnicodeString)"Parsed object: " + dateToString(o.getDate()));
810 if (!(o.getDate() == expected)) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
811 UnicodeString formatted; ((Format*)fmt)->format(o, formatted, status);
812 logln((UnicodeString)"Formatted string: " + formatted);
813 if (!(formatted == str)) errln((UnicodeString)"FAIL: Expected " + str);
814 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
817 // -------------------------------------
820 * Verify the handling of Czech June and July, which have the unique attribute that
821 * one is a proper prefix substring of the other.
824 DateFormatTest::TestCzechMonths459()
826 UErrorCode status = U_ZERO_ERROR;
827 DateFormat* fmt = DateFormat::createDateInstance(DateFormat::FULL, Locale("cs", "", ""));
829 dataerrln("Error calling DateFormat::createDateInstance()");
833 UnicodeString pattern;
834 logln((UnicodeString)"Pattern " + ((SimpleDateFormat*) fmt)->toPattern(pattern));
835 UDate june = date(97, UCAL_JUNE, 15);
836 UDate july = date(97, UCAL_JULY, 15);
837 UnicodeString juneStr; fmt->format(june, juneStr);
838 UnicodeString julyStr; fmt->format(july, julyStr);
840 logln((UnicodeString)"format(June 15 1997) = " + juneStr);
841 UDate d = fmt->parse(juneStr, status);
842 UnicodeString s; fmt->format(d, s);
843 int32_t month,yr,day,hr,min,sec; dateToFields(d,yr,month,day,hr,min,sec);
844 logln((UnicodeString)" -> parse -> " + s + " (month = " + month + ")");
845 if (month != UCAL_JUNE) errln((UnicodeString)"FAIL: Month should be June");
846 logln((UnicodeString)"format(July 15 1997) = " + julyStr);
847 d = fmt->parse(julyStr, status);
849 dateToFields(d,yr,month,day,hr,min,sec);
850 logln((UnicodeString)" -> parse -> " + s + " (month = " + month + ")");
851 if (month != UCAL_JULY) errln((UnicodeString)"FAIL: Month should be July");
853 //catch(ParseException e) {
854 if (U_FAILURE(status))
855 errln((UnicodeString)"Exception: " + (int32_t)status);
860 // -------------------------------------
863 * Test the handling of 'D' in patterns.
866 DateFormatTest::TestLetterDPattern212()
868 UErrorCode status = U_ZERO_ERROR;
869 UnicodeString dateString("1995-040.05:01:29");
870 UnicodeString bigD("yyyy-DDD.hh:mm:ss");
871 UnicodeString littleD("yyyy-ddd.hh:mm:ss");
872 UDate expLittleD = date(95, 0, 1, 5, 1, 29);
873 UDate expBigD = expLittleD + 39 * 24 * 3600000.0;
874 expLittleD = expBigD; // Expect the same, with default lenient parsing
875 logln((UnicodeString)"dateString= " + dateString);
876 SimpleDateFormat *formatter = new SimpleDateFormat(bigD, status);
877 if (U_FAILURE(status)) {
878 dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
882 ParsePosition pos(0);
883 UDate myDate = formatter->parse(dateString, pos);
884 logln((UnicodeString)"Using " + bigD + " -> " + myDate);
885 if (myDate != expBigD) errln((UnicodeString)"FAIL: bigD - Expected " + dateToString(expBigD));
887 formatter = new SimpleDateFormat(littleD, status);
889 pos = ParsePosition(0);
890 myDate = formatter->parse(dateString, pos);
891 logln((UnicodeString)"Using " + littleD + " -> " + dateToString(myDate));
892 if (myDate != expLittleD) errln((UnicodeString)"FAIL: littleD - Expected " + dateToString(expLittleD));
894 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
897 // -------------------------------------
900 * Test the day of year pattern.
903 DateFormatTest::TestDayOfYearPattern195()
905 UErrorCode status = U_ZERO_ERROR;
906 UDate today = Calendar::getNow();
907 int32_t year,month,day,hour,min,sec; dateToFields(today,year,month,day,hour,min,sec);
908 UDate expected = date(year, month, day);
909 logln((UnicodeString)"Test Date: " + dateToString(today));
910 SimpleDateFormat* sdf = (SimpleDateFormat*)DateFormat::createDateInstance();
912 dataerrln("Error calling DateFormat::createDateInstance()");
915 tryPattern(*sdf, today, 0, expected);
916 tryPattern(*sdf, today, "G yyyy DDD", expected);
918 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
921 // -------------------------------------
924 DateFormatTest::tryPattern(SimpleDateFormat& sdf, UDate d, const char* pattern, UDate expected)
926 UErrorCode status = U_ZERO_ERROR;
927 if (pattern != 0) sdf.applyPattern(pattern);
928 UnicodeString thePat;
929 logln((UnicodeString)"pattern: " + sdf.toPattern(thePat));
930 UnicodeString formatResult; (*(DateFormat*)&sdf).format(d, formatResult);
931 logln((UnicodeString)" format -> " + formatResult);
933 UDate d2 = sdf.parse(formatResult, status);
934 logln((UnicodeString)" parse(" + formatResult + ") -> " + dateToString(d2));
935 if (d2 != expected) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
936 UnicodeString format2; (*(DateFormat*)&sdf).format(d2, format2);
937 logln((UnicodeString)" format -> " + format2);
938 if (!(formatResult == format2)) errln((UnicodeString)"FAIL: Round trip drift");
940 //catch(Exception e) {
941 if (U_FAILURE(status))
942 errln((UnicodeString)"Error: " + (int32_t)status);
946 // -------------------------------------
949 * Test the handling of single quotes in patterns.
952 DateFormatTest::TestQuotePattern161()
954 UErrorCode status = U_ZERO_ERROR;
955 SimpleDateFormat* formatter = new SimpleDateFormat((UnicodeString)"MM/dd/yyyy 'at' hh:mm:ss a zzz", status);
956 if (U_FAILURE(status)) {
957 dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status));
961 UDate currentTime_1 = date(97, UCAL_AUGUST, 13, 10, 42, 28);
962 UnicodeString dateString; ((DateFormat*)formatter)->format(currentTime_1, dateString);
963 UnicodeString exp("08/13/1997 at 10:42:28 AM ");
964 logln((UnicodeString)"format(" + dateToString(currentTime_1) + ") = " + dateString);
965 if (0 != dateString.compareBetween(0, exp.length(), exp, 0, exp.length())) errln((UnicodeString)"FAIL: Expected " + exp);
967 if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
970 // -------------------------------------
973 * Verify the correct behavior when handling invalid input strings.
976 DateFormatTest::TestBadInput135()
978 UErrorCode status = U_ZERO_ERROR;
979 DateFormat::EStyle looks[] = {
980 DateFormat::SHORT, DateFormat::MEDIUM, DateFormat::LONG, DateFormat::FULL
982 int32_t looks_length = UPRV_LENGTHOF(looks);
983 const char* strings[] = {
984 "Mar 15", "Mar 15 1997", "asdf", "3/1/97 1:23:", "3/1/00 1:23:45 AM"
986 int32_t strings_length = UPRV_LENGTHOF(strings);
987 DateFormat *full = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::LONG);
989 dataerrln("could not create date time instance");
992 UnicodeString expected("March 1, 2000 at 1:23:45 AM ");
993 for (int32_t i = 0; i < strings_length;++i) {
994 const char* text = strings[i];
995 for (int32_t j = 0; j < looks_length;++j) {
996 DateFormat::EStyle dateLook = looks[j];
997 for (int32_t k = 0; k < looks_length;++k) {
998 DateFormat::EStyle timeLook = looks[k];
999 DateFormat *df = DateFormat::createDateTimeInstance(dateLook, timeLook);
1001 dataerrln("Error calling DateFormat::createDateTimeInstance()");
1004 UnicodeString prefix = UnicodeString(text) + ", " + dateLook + "/" + timeLook + ": ";
1006 UDate when = df->parse(text, status);
1007 if (when == 0 && U_SUCCESS(status)) {
1008 errln(prefix + "SHOULD NOT HAPPEN: parse returned 0.");
1011 if (U_SUCCESS(status))
1013 UnicodeString format;
1014 UnicodeString pattern;
1015 SimpleDateFormat* sdtfmt = dynamic_cast<SimpleDateFormat*>(df);
1016 if (sdtfmt != NULL) {
1017 sdtfmt->toPattern(pattern);
1019 full->format(when, format);
1020 logln(prefix + "OK: " + format);
1021 if (0!=format.compareBetween(0, expected.length(), expected, 0, expected.length()))
1022 errln((UnicodeString)"FAIL: Parse \"" + text + "\", pattern \"" + pattern + "\", expected " + expected + " got " + format);
1025 //catch(ParseException e) {
1027 status = U_ZERO_ERROR;
1029 //catch(StringIndexOutOfBoundsException e) {
1030 // errln(prefix + "SHOULD NOT HAPPEN: " + (int)status);
1037 if (U_FAILURE(status))
1038 errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
1041 static const char* const parseFormats[] = {
1050 "h:mm a MMMM d, yyyy"
1054 // strict inputStrings
1055 static const char* const inputStrings[] = {
1056 "bogus string", 0, 0, 0, 0, 0, 0, 0, 0, 0,
1057 "April 1, 1997", "April 1, 1997", 0, 0, 0, 0, 0, "April 1", 0, 0,
1058 "Jan 1, 1970", "January 1, 1970", 0, 0, 0, 0, 0, "January 1", 0, 0,
1059 "Jan 1 2037", 0, "January 1 2037", 0, 0, 0, 0, "January 1", 0, 0,
1060 "1/1/70", 0, 0, "1/1/70", 0, 0, 0, 0, "0001", 0,
1061 "5 May 1997", 0, 0, 0, 0, "5 May 1997", "5 May", 0, "0005", 0,
1062 "16 May", 0, 0, 0, 0, 0, "16 May", 0, "0016", 0,
1063 "April 30", 0, 0, 0, 0, 0, 0, "April 30", 0, 0,
1064 "1998", 0, 0, 0, 0, 0, 0, 0, "1998", 0,
1065 "1", 0, 0, 0, 0, 0, 0, 0, "0001", 0,
1066 "3:00 pm Jan 1, 1997", 0, 0, 0, 0, 0, 0, 0, "0003", "3:00 PM January 1, 1997",
1069 // lenient inputStrings
1070 static const char* const inputStrings[] = {
1071 "bogus string", 0, 0, 0, 0, 0, 0, 0, 0, 0,
1072 "April 1, 1997", "April 1, 1997", "April 1 1997", "4/1/97", 0, 0, 0, "April 1", 0, 0,
1073 "Jan 1, 1970", "January 1, 1970", "January 1 1970", "1/1/70", 0, 0, 0, "January 1", 0, 0,
1074 "Jan 1 2037", "January 1, 2037", "January 1 2037", "1/1/37", 0, 0, 0, "January 1", 0, 0,
1075 "1/1/70", "January 1, 0070", "January 1 0070", "1/1/70", "1 January, 0070", "1 January 0070", "1 January", "January 1", "0001", 0,
1076 "5 May 1997", 0, 0, 0, "5 May, 1997", "5 May 1997", "5 May", 0, "0005", 0,
1077 "16 May", 0, 0, 0, 0, 0, "16 May", 0, "0016", 0,
1078 "April 30", 0, 0, 0, 0, 0, 0, "April 30", 0, 0,
1079 "1998", 0, 0, 0, 0, 0, 0, 0, "1998", 0,
1080 "1", 0, 0, 0, 0, 0, 0, 0, "0001", 0,
1081 "3:00 pm Jan 1, 1997", 0, 0, 0, 0, 0, 0, 0, "0003", "3:00 PM January 1, 1997",
1085 // -------------------------------------
1088 * Verify the correct behavior when parsing an array of inputs against an
1089 * array of patterns, with known results. The results are encoded after
1090 * the input strings in each row.
1093 DateFormatTest::TestBadInput135a()
1095 UErrorCode status = U_ZERO_ERROR;
1096 SimpleDateFormat* dateParse = new SimpleDateFormat(status);
1097 if(U_FAILURE(status)) {
1098 dataerrln("Failed creating SimpleDateFormat with %s. Quitting test", u_errorName(status));
1104 const uint32_t PF_LENGTH = UPRV_LENGTHOF(parseFormats);
1105 const uint32_t INPUT_LENGTH = UPRV_LENGTHOF(inputStrings);
1107 dateParse->applyPattern("d MMMM, yyyy");
1108 dateParse->adoptTimeZone(TimeZone::createDefault());
1109 s = "not parseable";
1110 UnicodeString thePat;
1111 logln(UnicodeString("Trying to parse \"") + s + "\" with " + dateParse->toPattern(thePat));
1113 date = dateParse->parse(s, status);
1114 if (U_SUCCESS(status))
1115 errln((UnicodeString)"FAIL: Expected exception during parse");
1117 //catch(Exception ex) {
1119 logln((UnicodeString)"Exception during parse: " + (int32_t)status);
1120 status = U_ZERO_ERROR;
1122 for (uint32_t i = 0; i < INPUT_LENGTH; i += (PF_LENGTH + 1)) {
1123 ParsePosition parsePosition(0);
1124 UnicodeString s( inputStrings[i]);
1125 for (uint32_t index = 0; index < PF_LENGTH;++index) {
1126 const char* expected = inputStrings[i + 1 + index];
1127 dateParse->applyPattern(parseFormats[index]);
1128 dateParse->adoptTimeZone(TimeZone::createDefault());
1130 parsePosition.setIndex(0);
1131 date = dateParse->parse(s, parsePosition);
1132 if (parsePosition.getIndex() != 0) {
1133 UnicodeString s1, s2;
1134 s.extract(0, parsePosition.getIndex(), s1);
1135 s.extract(parsePosition.getIndex(), s.length(), s2);
1137 errln((UnicodeString)"ERROR: null result fmt=\"" +
1138 parseFormats[index] +
1139 "\" pos=" + parsePosition.getIndex() + " " +
1143 UnicodeString result;
1144 ((DateFormat*)dateParse)->format(date, result);
1145 logln((UnicodeString)"Parsed \"" + s + "\" using \"" + dateParse->toPattern(thePat) + "\" to: " + result);
1147 errln((UnicodeString)"FAIL: Expected parse failure, got " + result);
1148 else if (!(result == expected))
1149 errln(UnicodeString("FAIL: Parse \"") + s + UnicodeString("\", expected ") + expected + UnicodeString(", got ") + result);
1152 else if (expected != 0) {
1153 errln(UnicodeString("FAIL: Expected ") + expected + " from \"" +
1154 s + "\" with \"" + dateParse->toPattern(thePat) + "\"");
1157 //catch(Exception ex) {
1158 if (U_FAILURE(status))
1159 errln((UnicodeString)"An exception was thrown during parse: " + (int32_t)status);
1164 if (U_FAILURE(status))
1165 errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
1168 // -------------------------------------
1171 * Test the parsing of two-digit years.
1174 DateFormatTest::TestTwoDigitYear()
1176 UErrorCode ec = U_ZERO_ERROR;
1177 SimpleDateFormat fmt("dd/MM/yy", Locale::getUK(), ec);
1178 if (U_FAILURE(ec)) {
1179 dataerrln("FAIL: SimpleDateFormat constructor - %s", u_errorName(ec));
1182 parse2DigitYear(fmt, "5/6/30", date(130, UCAL_JUNE, 5));
1183 parse2DigitYear(fmt, "4/6/50", date(50, UCAL_JUNE, 4));
1186 // -------------------------------------
1189 DateFormatTest::parse2DigitYear(DateFormat& fmt, const char* str, UDate expected)
1191 UErrorCode status = U_ZERO_ERROR;
1193 UDate d = fmt.parse(str, status);
1194 UnicodeString thePat;
1195 logln(UnicodeString("Parsing \"") + str + "\" with " + ((SimpleDateFormat*)&fmt)->toPattern(thePat) +
1196 " => " + dateToString(d));
1197 if (d != expected) errln((UnicodeString)"FAIL: Expected " + expected);
1199 //catch(ParseException e) {
1200 if (U_FAILURE(status))
1201 errln((UnicodeString)"FAIL: Got exception");
1205 // -------------------------------------
1208 * Test the formatting of time zones.
1211 DateFormatTest::TestDateFormatZone061()
1213 UErrorCode status = U_ZERO_ERROR;
1215 DateFormat *formatter;
1216 date= 859248000000.0;
1217 logln((UnicodeString)"Date 1997/3/25 00:00 GMT: " + date);
1218 formatter = new SimpleDateFormat((UnicodeString)"dd-MMM-yyyyy HH:mm", Locale::getUK(), status);
1219 if(U_FAILURE(status)) {
1220 dataerrln("Failed creating SimpleDateFormat with %s. Quitting test", u_errorName(status));
1224 formatter->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1225 UnicodeString temp; formatter->format(date, temp);
1226 logln((UnicodeString)"Formatted in GMT to: " + temp);
1228 UDate tempDate = formatter->parse(temp, status);
1229 logln((UnicodeString)"Parsed to: " + dateToString(tempDate));
1230 if (tempDate != date) errln((UnicodeString)"FAIL: Expected " + dateToString(date));
1232 //catch(Throwable t) {
1233 if (U_FAILURE(status))
1234 errln((UnicodeString)"Date Formatter throws: " + (int32_t)status);
1239 // -------------------------------------
1242 * Test the formatting of time zones.
1245 DateFormatTest::TestDateFormatZone146()
1247 TimeZone *saveDefault = TimeZone::createDefault();
1250 TimeZone *thedefault = TimeZone::createTimeZone("GMT");
1251 TimeZone::setDefault(*thedefault);
1252 // java.util.Locale.setDefault(new java.util.Locale("ar", "", ""));
1254 // check to be sure... its GMT all right
1255 TimeZone *testdefault = TimeZone::createDefault();
1256 UnicodeString testtimezone;
1257 testdefault->getID(testtimezone);
1258 if (testtimezone == "GMT")
1259 logln("Test timezone = " + testtimezone);
1261 dataerrln("Test timezone should be GMT, not " + testtimezone);
1263 UErrorCode status = U_ZERO_ERROR;
1264 // now try to use the default GMT time zone
1265 GregorianCalendar *greenwichcalendar =
1266 new GregorianCalendar(1997, 3, 4, 23, 0, status);
1267 if (U_FAILURE(status)) {
1268 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status));
1270 //*****************************greenwichcalendar.setTimeZone(TimeZone.getDefault());
1271 //greenwichcalendar.set(1997, 3, 4, 23, 0);
1272 // try anything to set hour to 23:00 !!!
1273 greenwichcalendar->set(UCAL_HOUR_OF_DAY, 23);
1275 UDate greenwichdate = greenwichcalendar->getTime(status);
1277 UnicodeString DATA [] = {
1278 UnicodeString("simple format: "), UnicodeString("04/04/97 23:00 GMT"),
1279 UnicodeString("MM/dd/yy HH:mm z"),
1280 UnicodeString("full format: "), UnicodeString("Friday, April 4, 1997 11:00:00 o'clock PM GMT"),
1281 UnicodeString("EEEE, MMMM d, yyyy h:mm:ss 'o''clock' a z"),
1282 UnicodeString("long format: "), UnicodeString("April 4, 1997 11:00:00 PM GMT"),
1283 UnicodeString("MMMM d, yyyy h:mm:ss a z"),
1284 UnicodeString("default format: "), UnicodeString("04-Apr-97 11:00:00 PM"),
1285 UnicodeString("dd-MMM-yy h:mm:ss a"),
1286 UnicodeString("short format: "), UnicodeString("4/4/97 11:00 PM"),
1287 UnicodeString("M/d/yy h:mm a")
1289 int32_t DATA_length = UPRV_LENGTHOF(DATA);
1291 for (int32_t i=0; i<DATA_length; i+=3) {
1292 DateFormat *fmt = new SimpleDateFormat(DATA[i+2], Locale::getEnglish(), status);
1293 if (U_FAILURE(status)) {
1294 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
1297 fmt->setCalendar(*greenwichcalendar);
1298 UnicodeString result;
1299 result = fmt->format(greenwichdate, result);
1300 logln(DATA[i] + result);
1301 if (result != DATA[i+1])
1302 errln("FAIL: Expected " + DATA[i+1] + ", got " + result);
1308 TimeZone::adoptDefault(saveDefault);
1311 delete greenwichcalendar;
1317 // -------------------------------------
1320 * Test the formatting of dates in different locales.
1323 DateFormatTest::TestLocaleDateFormat() // Bug 495
1325 UDate testDate = date(97, UCAL_SEPTEMBER, 15);
1326 DateFormat *dfFrench = DateFormat::createDateTimeInstance(DateFormat::FULL,
1327 DateFormat::FULL, Locale::getFrench());
1328 DateFormat *dfUS = DateFormat::createDateTimeInstance(DateFormat::FULL,
1329 DateFormat::FULL, Locale::getUS());
1330 UnicodeString expectedFRENCH ( "lundi 15 septembre 1997 \\u00E0 00:00:00 heure d\\u2019\\u00E9t\\u00E9 du Pacifique", -1, US_INV );
1331 expectedFRENCH = expectedFRENCH.unescape();
1332 UnicodeString expectedUS ( "Monday, September 15, 1997 at 12:00:00 AM Pacific Daylight Time" );
1333 logln((UnicodeString)"Date set to : " + dateToString(testDate));
1335 if (dfUS == NULL || dfFrench == NULL){
1336 dataerrln("Error calling DateFormat::createDateTimeInstance)");
1342 dfFrench->format(testDate, out);
1343 logln((UnicodeString)"Date Formated with French Locale " + out);
1344 if (!(out == expectedFRENCH))
1345 errln((UnicodeString)"FAIL: Expected " + expectedFRENCH);
1347 dfUS->format(testDate, out);
1348 logln((UnicodeString)"Date Formated with US Locale " + out);
1349 if (!(out == expectedUS))
1350 errln((UnicodeString)"FAIL: Expected " + expectedUS);
1356 DateFormatTest::TestFormattingLocaleTimeSeparator()
1358 // This test not as useful is it once was, since timeSeparator
1359 // in the Arabic is changed back to ":" in CLDR 28.
1360 const UDate testDate = 874266720000.; // Sun Sep 14 21:52:00 CET 1997
1361 logln((UnicodeString)"Date set to : " + dateToString(testDate));
1363 const LocalPointer<const TimeZone> tz(TimeZone::createTimeZone("CET"));
1365 const LocalPointer<DateFormat> dfArab(DateFormat::createTimeInstance(
1366 DateFormat::SHORT, Locale("ar")));
1368 const LocalPointer<DateFormat> dfLatn(DateFormat::createTimeInstance(
1369 DateFormat::SHORT, Locale("ar", NULL, NULL, "numbers=latn")));
1371 if (dfLatn.isNull() || dfArab.isNull()) {
1372 dataerrln("Error calling DateFormat::createTimeInstance()");
1376 dfArab->setTimeZone(*tz);
1377 dfLatn->setTimeZone(*tz);
1379 const UnicodeString expectedArab = UnicodeString(
1380 "\\u0669:\\u0665\\u0662 \\u0645", -1, US_INV).unescape();
1382 const UnicodeString expectedLatn = UnicodeString(
1383 "9:52 \\u0645", -1, US_INV).unescape();
1385 UnicodeString actualArab;
1386 UnicodeString actualLatn;
1388 dfArab->format(testDate, actualArab);
1389 dfLatn->format(testDate, actualLatn);
1391 assertEquals("Arab", expectedArab, actualArab);
1392 assertEquals("Latn", expectedLatn, actualLatn);
1396 * Test DateFormat(Calendar) API
1398 void DateFormatTest::TestDateFormatCalendar() {
1399 DateFormat *date=0, *time=0, *full=0;
1404 UErrorCode ec = U_ZERO_ERROR;
1406 /* Create a formatter for date fields. */
1407 date = DateFormat::createDateInstance(DateFormat::kShort, Locale::getUS());
1409 dataerrln("FAIL: createDateInstance failed");
1413 /* Create a formatter for time fields. */
1414 time = DateFormat::createTimeInstance(DateFormat::kShort, Locale::getUS());
1416 errln("FAIL: createTimeInstance failed");
1420 /* Create a full format for output */
1421 full = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull,
1424 errln("FAIL: createInstance failed");
1428 /* Create a calendar */
1429 cal = Calendar::createInstance(Locale::getUS(), ec);
1430 if (cal == NULL || U_FAILURE(ec)) {
1431 errln((UnicodeString)"FAIL: Calendar::createInstance failed with " +
1436 /* Parse the date */
1438 str = UnicodeString("4/5/2001", "");
1440 date->parse(str, *cal, pos);
1441 if (pos.getIndex() != str.length()) {
1442 errln((UnicodeString)"FAIL: DateFormat::parse(4/5/2001) failed at " +
1447 /* Parse the time */
1448 str = UnicodeString("5:45 PM", "");
1450 time->parse(str, *cal, pos);
1451 if (pos.getIndex() != str.length()) {
1452 errln((UnicodeString)"FAIL: DateFormat::parse(17:45) failed at " +
1458 when = cal->getTime(ec);
1459 if (U_FAILURE(ec)) {
1460 errln((UnicodeString)"FAIL: cal->getTime() failed with " + u_errorName(ec));
1464 full->format(when, str);
1465 // Thursday, April 5, 2001 5:45:00 PM PDT 986517900000
1466 if (when == 986517900000.0) {
1467 logln("Ok: Parsed result: " + str);
1469 errln("FAIL: Parsed result: " + str + ", exp 4/5/2001 5:45 PM");
1480 * Test DateFormat's parsing of space characters. See jitterbug 1916.
1482 void DateFormatTest::TestSpaceParsing() {
1483 const char* DATA[] = {
1484 "yyyy MM dd HH:mm:ss",
1486 // pattern, input, expected parse or NULL if expect parse failure
1487 "MMMM d yy", " 04 05 06", "2006 04 05 00:00:00",
1488 NULL, "04 05 06", "2006 04 05 00:00:00",
1490 "MM d yy", " 04 05 06", "2006 04 05 00:00:00",
1491 NULL, "04 05 06", "2006 04 05 00:00:00",
1492 NULL, "04/05/06", "2006 04 05 00:00:00",
1493 NULL, "04-05-06", "2006 04 05 00:00:00",
1494 NULL, "04.05.06", "2006 04 05 00:00:00",
1495 NULL, "04 / 05 / 06", "2006 04 05 00:00:00",
1496 NULL, "Apr / 05/ 06", "2006 04 05 00:00:00",
1497 NULL, "Apr-05-06", "2006 04 05 00:00:00",
1498 NULL, "Apr 05, 2006", "2006 04 05 00:00:00",
1500 "MMMM d yy", " Apr 05 06", "2006 04 05 00:00:00",
1501 NULL, "Apr 05 06", "2006 04 05 00:00:00",
1502 NULL, "Apr05 06", "2006 04 05 00:00:00",
1504 "hh:mm:ss a", "12:34:56 PM", "1970 01 01 12:34:56",
1505 NULL, "12:34:56PM", "1970 01 01 12:34:56",
1506 NULL, "12.34.56PM", "1970 01 01 12:34:56",
1507 NULL, "12 : 34 : 56 PM", "1970 01 01 12:34:56",
1509 "MM d yy 'at' hh:mm:ss a", "04/05/06 12:34:56 PM", "2006 04 05 12:34:56",
1511 "MMMM dd yyyy hh:mm a", "September 27, 1964 21:56 PM", "1964 09 28 09:56:00",
1512 NULL, "November 4, 2008 0:13 AM", "2008 11 04 00:13:00",
1514 "HH'h'mm'min'ss's'", "12h34min56s", "1970 01 01 12:34:56",
1515 NULL, "12h34mi56s", "1970 01 01 12:34:56",
1516 NULL, "12h34m56s", "1970 01 01 12:34:56",
1517 NULL, "12:34:56", "1970 01 01 12:34:56"
1519 const int32_t DATA_len = UPRV_LENGTHOF(DATA);
1521 expectParse(DATA, DATA_len, Locale("en"));
1525 * Test handling of "HHmmss" pattern.
1527 void DateFormatTest::TestExactCountFormat() {
1528 const char* DATA[] = {
1529 "yyyy MM dd HH:mm:ss",
1531 // pattern, input, expected parse or NULL if expect parse failure
1532 "HHmmss", "123456", "1970 01 01 12:34:56",
1533 NULL, "12345", "1970 01 01 01:23:45",
1535 NULL, "00-05", NULL,
1536 NULL, "12-34", NULL,
1537 NULL, "00+05", NULL,
1538 "ahhmm", "PM730", "1970 01 01 19:30:00",
1540 const int32_t DATA_len = UPRV_LENGTHOF(DATA);
1542 expectParse(DATA, DATA_len, Locale("en"));
1546 * Test handling of white space.
1548 void DateFormatTest::TestWhiteSpaceParsing() {
1549 const char* DATA[] = {
1552 // pattern, input, expected parse or null if expect parse failure
1554 // Pattern space run should parse input text space run
1555 "MM d yy", " 04 01 03", "2003 04 01",
1556 NULL, " 04 01 03 ", "2003 04 01",
1558 const int32_t DATA_len = UPRV_LENGTHOF(DATA);
1560 expectParse(DATA, DATA_len, Locale("en"));
1564 void DateFormatTest::TestInvalidPattern() {
1565 UErrorCode ec = U_ZERO_ERROR;
1566 SimpleDateFormat f(UnicodeString("Yesterday"), ec);
1567 if (U_FAILURE(ec)) {
1568 dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(ec));
1573 f.format((UDate)0, out, pos);
1575 // The bug is that the call to format() will crash. By not
1576 // crashing, the test passes.
1579 void DateFormatTest::TestGreekMay() {
1580 UErrorCode ec = U_ZERO_ERROR;
1581 UDate date = -9896080848000.0;
1582 SimpleDateFormat fmt("EEEE, dd MMMM yyyy h:mm:ss a", Locale("el", "", ""), ec);
1583 if (U_FAILURE(ec)) {
1584 dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(ec));
1588 fmt.format(date, str);
1589 ParsePosition pos(0);
1590 UDate d2 = fmt.parse(str, pos);
1592 errln("FAIL: unable to parse strings where case-folding changes length");
1596 void DateFormatTest::TestStandAloneMonths()
1598 const char *EN_DATA[] = {
1599 "yyyy MM dd HH:mm:ss",
1601 "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",
1602 "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",
1603 "yyyy LLLL dd H:mm:ss", "F", "2004 03 10 16:36:31", "2004 March 10 16:36:31",
1604 "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",
1606 "LLLL", "fp", "1970 01 01 0:00:00", "January", "1970 01 01 0:00:00",
1607 "LLLL", "fp", "1970 02 01 0:00:00", "February", "1970 02 01 0:00:00",
1608 "LLLL", "fp", "1970 03 01 0:00:00", "March", "1970 03 01 0:00:00",
1609 "LLLL", "fp", "1970 04 01 0:00:00", "April", "1970 04 01 0:00:00",
1610 "LLLL", "fp", "1970 05 01 0:00:00", "May", "1970 05 01 0:00:00",
1611 "LLLL", "fp", "1970 06 01 0:00:00", "June", "1970 06 01 0:00:00",
1612 "LLLL", "fp", "1970 07 01 0:00:00", "July", "1970 07 01 0:00:00",
1613 "LLLL", "fp", "1970 08 01 0:00:00", "August", "1970 08 01 0:00:00",
1614 "LLLL", "fp", "1970 09 01 0:00:00", "September", "1970 09 01 0:00:00",
1615 "LLLL", "fp", "1970 10 01 0:00:00", "October", "1970 10 01 0:00:00",
1616 "LLLL", "fp", "1970 11 01 0:00:00", "November", "1970 11 01 0:00:00",
1617 "LLLL", "fp", "1970 12 01 0:00:00", "December", "1970 12 01 0:00:00",
1619 "LLL", "fp", "1970 01 01 0:00:00", "Jan", "1970 01 01 0:00:00",
1620 "LLL", "fp", "1970 02 01 0:00:00", "Feb", "1970 02 01 0:00:00",
1621 "LLL", "fp", "1970 03 01 0:00:00", "Mar", "1970 03 01 0:00:00",
1622 "LLL", "fp", "1970 04 01 0:00:00", "Apr", "1970 04 01 0:00:00",
1623 "LLL", "fp", "1970 05 01 0:00:00", "May", "1970 05 01 0:00:00",
1624 "LLL", "fp", "1970 06 01 0:00:00", "Jun", "1970 06 01 0:00:00",
1625 "LLL", "fp", "1970 07 01 0:00:00", "Jul", "1970 07 01 0:00:00",
1626 "LLL", "fp", "1970 08 01 0:00:00", "Aug", "1970 08 01 0:00:00",
1627 "LLL", "fp", "1970 09 01 0:00:00", "Sep", "1970 09 01 0:00:00",
1628 "LLL", "fp", "1970 10 01 0:00:00", "Oct", "1970 10 01 0:00:00",
1629 "LLL", "fp", "1970 11 01 0:00:00", "Nov", "1970 11 01 0:00:00",
1630 "LLL", "fp", "1970 12 01 0:00:00", "Dec", "1970 12 01 0:00:00",
1633 const char *CS_DATA[] = {
1634 "yyyy MM dd HH:mm:ss",
1636 "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",
1637 "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",
1638 "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",
1639 "yyyy LLLL dd H:mm:ss", "F", "2004 04 10 16:36:31", "2004 duben 10 16:36:31",
1640 "yyyy MMMM dd H:mm:ss", "F", "2004 04 10 16:36:31", "2004 dubna 10 16:36:31",
1641 "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",
1642 "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",
1644 "LLLL", "fp", "1970 01 01 0:00:00", "leden", "1970 01 01 0:00:00",
1645 "LLLL", "fp", "1970 02 01 0:00:00", "\\u00FAnor", "1970 02 01 0:00:00",
1646 "LLLL", "fp", "1970 03 01 0:00:00", "b\\u0159ezen", "1970 03 01 0:00:00",
1647 "LLLL", "fp", "1970 04 01 0:00:00", "duben", "1970 04 01 0:00:00",
1648 "LLLL", "fp", "1970 05 01 0:00:00", "kv\\u011Bten", "1970 05 01 0:00:00",
1649 "LLLL", "fp", "1970 06 01 0:00:00", "\\u010Derven", "1970 06 01 0:00:00",
1650 "LLLL", "fp", "1970 07 01 0:00:00", "\\u010Dervenec", "1970 07 01 0:00:00",
1651 "LLLL", "fp", "1970 08 01 0:00:00", "srpen", "1970 08 01 0:00:00",
1652 "LLLL", "fp", "1970 09 01 0:00:00", "z\\u00E1\\u0159\\u00ED", "1970 09 01 0:00:00",
1653 "LLLL", "fp", "1970 10 01 0:00:00", "\\u0159\\u00EDjen", "1970 10 01 0:00:00",
1654 "LLLL", "fp", "1970 11 01 0:00:00", "listopad", "1970 11 01 0:00:00",
1655 "LLLL", "fp", "1970 12 01 0:00:00", "prosinec", "1970 12 01 0:00:00",
1657 "LLL", "fp", "1970 01 01 0:00:00", "led", "1970 01 01 0:00:00",
1658 "LLL", "fp", "1970 02 01 0:00:00", "\\u00FAno", "1970 02 01 0:00:00",
1659 "LLL", "fp", "1970 03 01 0:00:00", "b\\u0159e", "1970 03 01 0:00:00",
1660 "LLL", "fp", "1970 04 01 0:00:00", "dub", "1970 04 01 0:00:00",
1661 "LLL", "fp", "1970 05 01 0:00:00", "kv\\u011B", "1970 05 01 0:00:00",
1662 "LLL", "fp", "1970 06 01 0:00:00", "\\u010Dvn", "1970 06 01 0:00:00",
1663 "LLL", "fp", "1970 07 01 0:00:00", "\\u010Dvc", "1970 07 01 0:00:00",
1664 "LLL", "fp", "1970 08 01 0:00:00", "srp", "1970 08 01 0:00:00",
1665 "LLL", "fp", "1970 09 01 0:00:00", "z\\u00E1\\u0159", "1970 09 01 0:00:00",
1666 "LLL", "fp", "1970 10 01 0:00:00", "\\u0159\\u00EDj", "1970 10 01 0:00:00",
1667 "LLL", "fp", "1970 11 01 0:00:00", "lis", "1970 11 01 0:00:00",
1668 "LLL", "fp", "1970 12 01 0:00:00", "pro", "1970 12 01 0:00:00",
1671 expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
1672 expect(CS_DATA, UPRV_LENGTHOF(CS_DATA), Locale("cs", "", ""));
1675 void DateFormatTest::TestStandAloneDays()
1677 const char *EN_DATA[] = {
1678 "yyyy MM dd HH:mm:ss",
1680 "cccc", "fp", "1970 01 04 0:00:00", "Sunday", "1970 01 04 0:00:00",
1681 "cccc", "fp", "1970 01 05 0:00:00", "Monday", "1970 01 05 0:00:00",
1682 "cccc", "fp", "1970 01 06 0:00:00", "Tuesday", "1970 01 06 0:00:00",
1683 "cccc", "fp", "1970 01 07 0:00:00", "Wednesday", "1970 01 07 0:00:00",
1684 "cccc", "fp", "1970 01 01 0:00:00", "Thursday", "1970 01 01 0:00:00",
1685 "cccc", "fp", "1970 01 02 0:00:00", "Friday", "1970 01 02 0:00:00",
1686 "cccc", "fp", "1970 01 03 0:00:00", "Saturday", "1970 01 03 0:00:00",
1688 "ccc", "fp", "1970 01 04 0:00:00", "Sun", "1970 01 04 0:00:00",
1689 "ccc", "fp", "1970 01 05 0:00:00", "Mon", "1970 01 05 0:00:00",
1690 "ccc", "fp", "1970 01 06 0:00:00", "Tue", "1970 01 06 0:00:00",
1691 "ccc", "fp", "1970 01 07 0:00:00", "Wed", "1970 01 07 0:00:00",
1692 "ccc", "fp", "1970 01 01 0:00:00", "Thu", "1970 01 01 0:00:00",
1693 "ccc", "fp", "1970 01 02 0:00:00", "Fri", "1970 01 02 0:00:00",
1694 "ccc", "fp", "1970 01 03 0:00:00", "Sat", "1970 01 03 0:00:00",
1697 const char *CS_DATA[] = {
1698 "yyyy MM dd HH:mm:ss",
1700 "cccc", "fp", "1970 01 04 0:00:00", "ned\\u011Ble", "1970 01 04 0:00:00",
1701 "cccc", "fp", "1970 01 05 0:00:00", "pond\\u011Bl\\u00ED", "1970 01 05 0:00:00",
1702 "cccc", "fp", "1970 01 06 0:00:00", "\\u00FAter\\u00FD", "1970 01 06 0:00:00",
1703 "cccc", "fp", "1970 01 07 0:00:00", "st\\u0159eda", "1970 01 07 0:00:00",
1704 "cccc", "fp", "1970 01 01 0:00:00", "\\u010Dtvrtek", "1970 01 01 0:00:00",
1705 "cccc", "fp", "1970 01 02 0:00:00", "p\\u00E1tek", "1970 01 02 0:00:00",
1706 "cccc", "fp", "1970 01 03 0:00:00", "sobota", "1970 01 03 0:00:00",
1708 "ccc", "fp", "1970 01 04 0:00:00", "ne", "1970 01 04 0:00:00",
1709 "ccc", "fp", "1970 01 05 0:00:00", "po", "1970 01 05 0:00:00",
1710 "ccc", "fp", "1970 01 06 0:00:00", "\\u00FAt", "1970 01 06 0:00:00",
1711 "ccc", "fp", "1970 01 07 0:00:00", "st", "1970 01 07 0:00:00",
1712 "ccc", "fp", "1970 01 01 0:00:00", "\\u010Dt", "1970 01 01 0:00:00",
1713 "ccc", "fp", "1970 01 02 0:00:00", "p\\u00E1", "1970 01 02 0:00:00",
1714 "ccc", "fp", "1970 01 03 0:00:00", "so", "1970 01 03 0:00:00",
1717 expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
1718 expect(CS_DATA, UPRV_LENGTHOF(CS_DATA), Locale("cs", "", ""));
1721 void DateFormatTest::TestShortDays()
1723 const char *EN_DATA[] = {
1724 "yyyy MM dd HH:mm:ss",
1726 "EEEEEE, MMM d y", "fp", "2013 01 13 0:00:00", "Su, Jan 13 2013", "2013 01 13 0:00:00",
1727 "EEEEEE, MMM d y", "fp", "2013 01 16 0:00:00", "We, Jan 16 2013", "2013 01 16 0:00:00",
1728 "EEEEEE d", "fp", "1970 01 17 0:00:00", "Sa 17", "1970 01 17 0:00:00",
1729 "cccccc d", "fp", "1970 01 17 0:00:00", "Sa 17", "1970 01 17 0:00:00",
1730 "cccccc", "fp", "1970 01 03 0:00:00", "Sa", "1970 01 03 0:00:00",
1732 const char *SV_DATA[] = {
1733 "yyyy MM dd HH:mm:ss",
1735 "EEEEEE d MMM y", "fp", "2013 01 13 0:00:00", "s\\u00F6 13 jan. 2013", "2013 01 13 0:00:00",
1736 "EEEEEE d MMM y", "fp", "2013 01 16 0:00:00", "on 16 jan. 2013", "2013 01 16 0:00:00",
1737 "EEEEEE d", "fp", "1970 01 17 0:00:00", "l\\u00F6 17", "1970 01 17 0:00:00",
1738 "cccccc d", "fp", "1970 01 17 0:00:00", "l\\u00F6 17", "1970 01 17 0:00:00",
1739 "cccccc", "fp", "1970 01 03 0:00:00", "l\\u00F6", "1970 01 03 0:00:00",
1741 expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
1742 expect(SV_DATA, UPRV_LENGTHOF(SV_DATA), Locale("sv", "", ""));
1745 void DateFormatTest::TestNarrowNames()
1747 const char *EN_DATA[] = {
1748 "yyyy MM dd HH:mm:ss",
1750 "yyyy MMMMM dd H:mm:ss", "2004 03 10 16:36:31", "2004 M 10 16:36:31",
1751 "yyyy LLLLL dd H:mm:ss", "2004 03 10 16:36:31", "2004 M 10 16:36:31",
1753 "MMMMM", "1970 01 01 0:00:00", "J",
1754 "MMMMM", "1970 02 01 0:00:00", "F",
1755 "MMMMM", "1970 03 01 0:00:00", "M",
1756 "MMMMM", "1970 04 01 0:00:00", "A",
1757 "MMMMM", "1970 05 01 0:00:00", "M",
1758 "MMMMM", "1970 06 01 0:00:00", "J",
1759 "MMMMM", "1970 07 01 0:00:00", "J",
1760 "MMMMM", "1970 08 01 0:00:00", "A",
1761 "MMMMM", "1970 09 01 0:00:00", "S",
1762 "MMMMM", "1970 10 01 0:00:00", "O",
1763 "MMMMM", "1970 11 01 0:00:00", "N",
1764 "MMMMM", "1970 12 01 0:00:00", "D",
1766 "LLLLL", "1970 01 01 0:00:00", "J",
1767 "LLLLL", "1970 02 01 0:00:00", "F",
1768 "LLLLL", "1970 03 01 0:00:00", "M",
1769 "LLLLL", "1970 04 01 0:00:00", "A",
1770 "LLLLL", "1970 05 01 0:00:00", "M",
1771 "LLLLL", "1970 06 01 0:00:00", "J",
1772 "LLLLL", "1970 07 01 0:00:00", "J",
1773 "LLLLL", "1970 08 01 0:00:00", "A",
1774 "LLLLL", "1970 09 01 0:00:00", "S",
1775 "LLLLL", "1970 10 01 0:00:00", "O",
1776 "LLLLL", "1970 11 01 0:00:00", "N",
1777 "LLLLL", "1970 12 01 0:00:00", "D",
1779 "EEEEE", "1970 01 04 0:00:00", "S",
1780 "EEEEE", "1970 01 05 0:00:00", "M",
1781 "EEEEE", "1970 01 06 0:00:00", "T",
1782 "EEEEE", "1970 01 07 0:00:00", "W",
1783 "EEEEE", "1970 01 01 0:00:00", "T",
1784 "EEEEE", "1970 01 02 0:00:00", "F",
1785 "EEEEE", "1970 01 03 0:00:00", "S",
1787 "ccccc", "1970 01 04 0:00:00", "S",
1788 "ccccc", "1970 01 05 0:00:00", "M",
1789 "ccccc", "1970 01 06 0:00:00", "T",
1790 "ccccc", "1970 01 07 0:00:00", "W",
1791 "ccccc", "1970 01 01 0:00:00", "T",
1792 "ccccc", "1970 01 02 0:00:00", "F",
1793 "ccccc", "1970 01 03 0:00:00", "S",
1795 "h:mm a", "2015 01 01 10:00:00", "10:00 AM",
1796 "h:mm a", "2015 01 01 22:00:00", "10:00 PM",
1797 "h:mm aaaaa", "2015 01 01 10:00:00", "10:00 a",
1798 "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 p",
1801 const char *CS_DATA[] = {
1802 "yyyy MM dd HH:mm:ss",
1804 "yyyy LLLLL dd H:mm:ss", "2004 04 10 16:36:31", "2004 4 10 16:36:31",
1805 "yyyy MMMMM dd H:mm:ss", "2004 04 10 16:36:31", "2004 4 10 16:36:31",
1807 "MMMMM", "1970 01 01 0:00:00", "1",
1808 "MMMMM", "1970 02 01 0:00:00", "2",
1809 "MMMMM", "1970 03 01 0:00:00", "3",
1810 "MMMMM", "1970 04 01 0:00:00", "4",
1811 "MMMMM", "1970 05 01 0:00:00", "5",
1812 "MMMMM", "1970 06 01 0:00:00", "6",
1813 "MMMMM", "1970 07 01 0:00:00", "7",
1814 "MMMMM", "1970 08 01 0:00:00", "8",
1815 "MMMMM", "1970 09 01 0:00:00", "9",
1816 "MMMMM", "1970 10 01 0:00:00", "10",
1817 "MMMMM", "1970 11 01 0:00:00", "11",
1818 "MMMMM", "1970 12 01 0:00:00", "12",
1820 "LLLLL", "1970 01 01 0:00:00", "1",
1821 "LLLLL", "1970 02 01 0:00:00", "2",
1822 "LLLLL", "1970 03 01 0:00:00", "3",
1823 "LLLLL", "1970 04 01 0:00:00", "4",
1824 "LLLLL", "1970 05 01 0:00:00", "5",
1825 "LLLLL", "1970 06 01 0:00:00", "6",
1826 "LLLLL", "1970 07 01 0:00:00", "7",
1827 "LLLLL", "1970 08 01 0:00:00", "8",
1828 "LLLLL", "1970 09 01 0:00:00", "9",
1829 "LLLLL", "1970 10 01 0:00:00", "10",
1830 "LLLLL", "1970 11 01 0:00:00", "11",
1831 "LLLLL", "1970 12 01 0:00:00", "12",
1833 "EEEEE", "1970 01 04 0:00:00", "N",
1834 "EEEEE", "1970 01 05 0:00:00", "P",
1835 "EEEEE", "1970 01 06 0:00:00", "\\u00DA",
1836 "EEEEE", "1970 01 07 0:00:00", "S",
1837 "EEEEE", "1970 01 01 0:00:00", "\\u010C",
1838 "EEEEE", "1970 01 02 0:00:00", "P",
1839 "EEEEE", "1970 01 03 0:00:00", "S",
1841 "ccccc", "1970 01 04 0:00:00", "N",
1842 "ccccc", "1970 01 05 0:00:00", "P",
1843 "ccccc", "1970 01 06 0:00:00", "\\u00DA",
1844 "ccccc", "1970 01 07 0:00:00", "S",
1845 "ccccc", "1970 01 01 0:00:00", "\\u010C",
1846 "ccccc", "1970 01 02 0:00:00", "P",
1847 "ccccc", "1970 01 03 0:00:00", "S",
1849 "h:mm a", "2015 01 01 10:00:00", "10:00 dop.",
1850 "h:mm a", "2015 01 01 22:00:00", "10:00 odp.",
1851 "h:mm aaaaa", "2015 01 01 10:00:00", "10:00 dop.",
1852 "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 odp.",
1855 const char *CA_DATA[] = {
1856 "yyyy MM dd HH:mm:ss",
1858 "h:mm a", "2015 01 01 10:00:00", "10:00 a. m.",
1859 "h:mm a", "2015 01 01 22:00:00", "10:00 p. m.",
1860 "h:mm aaaaa", "2015 01 01 10:00:00", "10:00 a. m.",
1861 "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 p. m.",
1864 expectFormat(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
1865 expectFormat(CS_DATA, UPRV_LENGTHOF(CS_DATA), Locale("cs", "", ""));
1866 expectFormat(CA_DATA, UPRV_LENGTHOF(CA_DATA), Locale("ca", "", ""));
1869 void DateFormatTest::TestEras()
1871 const char *EN_DATA[] = {
1874 "MMMM dd yyyy G", "fp", "1951 07 17", "July 17 1951 AD", "1951 07 17",
1875 "MMMM dd yyyy GG", "fp", "1951 07 17", "July 17 1951 AD", "1951 07 17",
1876 "MMMM dd yyyy GGG", "fp", "1951 07 17", "July 17 1951 AD", "1951 07 17",
1877 "MMMM dd yyyy GGGG", "fp", "1951 07 17", "July 17 1951 Anno Domini", "1951 07 17",
1879 "MMMM dd yyyy G", "fp", "-438 07 17", "July 17 0439 BC", "-438 07 17",
1880 "MMMM dd yyyy GG", "fp", "-438 07 17", "July 17 0439 BC", "-438 07 17",
1881 "MMMM dd yyyy GGG", "fp", "-438 07 17", "July 17 0439 BC", "-438 07 17",
1882 "MMMM dd yyyy GGGG", "fp", "-438 07 17", "July 17 0439 Before Christ", "-438 07 17",
1885 expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
1888 void DateFormatTest::TestQuarters()
1890 const char *EN_DATA[] = {
1893 "Q", "fp", "1970 01 01", "1", "1970 01 01",
1894 "QQ", "fp", "1970 04 01", "02", "1970 04 01",
1895 "QQQ", "fp", "1970 07 01", "Q3", "1970 07 01",
1896 "QQQQ", "fp", "1970 10 01", "4th quarter", "1970 10 01",
1898 "q", "fp", "1970 01 01", "1", "1970 01 01",
1899 "qq", "fp", "1970 04 01", "02", "1970 04 01",
1900 "qqq", "fp", "1970 07 01", "Q3", "1970 07 01",
1901 "qqqq", "fp", "1970 10 01", "4th quarter", "1970 10 01",
1903 "Qyy", "fp", "2015 04 01", "215", "2015 04 01",
1904 "QQyy", "fp", "2015 07 01", "0315", "2015 07 01",
1907 expect(EN_DATA, UPRV_LENGTHOF(EN_DATA), Locale("en", "", ""));
1911 * Test parsing. Input is an array that starts with the following
1914 * [0] = pattern string to parse [i+2] with
1916 * followed by test cases, each of which is 3 array elements:
1918 * [i] = pattern, or NULL to reuse prior pattern
1919 * [i+1] = input string
1920 * [i+2] = expected parse result (parsed with pattern [0])
1922 * If expect parse failure, then [i+2] should be NULL.
1924 void DateFormatTest::expectParse(const char** data, int32_t data_length,
1925 const Locale& loc) {
1926 const UDate FAIL = (UDate) -1;
1927 const UnicodeString FAIL_STR("parse failure");
1930 UErrorCode ec = U_ZERO_ERROR;
1931 SimpleDateFormat fmt("", loc, ec);
1932 SimpleDateFormat ref(data[i++], loc, ec);
1933 SimpleDateFormat gotfmt("G yyyy MM dd HH:mm:ss z", loc, ec);
1934 if (U_FAILURE(ec)) {
1935 dataerrln("FAIL: SimpleDateFormat constructor - %s", u_errorName(ec));
1939 const char* currentPat = NULL;
1940 while (i<data_length) {
1941 const char* pattern = data[i++];
1942 const char* input = data[i++];
1943 const char* expected = data[i++];
1946 if (pattern != NULL) {
1947 fmt.applyPattern(pattern);
1948 currentPat = pattern;
1950 UDate got = fmt.parse(input, ec);
1951 UnicodeString gotstr(FAIL_STR);
1952 if (U_FAILURE(ec)) {
1956 gotfmt.format(got, gotstr);
1959 UErrorCode ec2 = U_ZERO_ERROR;
1961 UnicodeString expstr(FAIL_STR);
1962 if (expected != NULL) {
1964 exp = ref.parse(expstr, ec2);
1965 if (U_FAILURE(ec2)) {
1966 // This only happens if expected is in wrong format --
1967 // should never happen once test is debugged.
1968 errln("FAIL: Internal test error");
1974 logln((UnicodeString)"Ok: " + input + " x " +
1975 currentPat + " => " + gotstr);
1977 errln((UnicodeString)"FAIL: " + input + " x " +
1978 currentPat + " => " + gotstr + ", expected " +
1985 * Test formatting and parsing. Input is an array that starts
1986 * with the following header:
1988 * [0] = pattern string to parse [i+2] with
1990 * followed by test cases, each of which is 3 array elements:
1992 * [i] = pattern, or null to reuse prior pattern
1993 * [i+1] = control string, either "fp", "pf", or "F".
1994 * [i+2..] = data strings
1996 * The number of data strings depends on the control string.
1998 * 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",
1999 * 'f': Format date [i+2] (as parsed using pattern [0]) and expect string [i+3].
2000 * 'p': Parse string [i+3] and expect date [i+4].
2002 * 2. "y/M/d H:mm:ss.SSS", "F", "2004 03 10 16:36:31.567", "2004/3/10 16:36:31.567"
2003 * 'F': Format date [i+2] and expect string [i+3],
2004 * then parse string [i+3] and expect date [i+2].
2006 * 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",
2007 * 'p': Parse string [i+2] and expect date [i+3].
2008 * 'f': Format date [i+3] and expect string [i+4].
2010 void DateFormatTest::expect(const char** data, int32_t data_length,
2011 const Locale& loc) {
2013 UErrorCode ec = U_ZERO_ERROR;
2014 UnicodeString str, str2;
2015 SimpleDateFormat fmt("", loc, ec);
2016 SimpleDateFormat ref(data[i++], loc, ec);
2017 SimpleDateFormat univ("EE G yyyy MM dd HH:mm:ss.SSS z", loc, ec);
2018 if (U_FAILURE(ec)) {
2019 dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(ec));
2023 UnicodeString currentPat;
2024 while (i<data_length) {
2025 const char* pattern = data[i++];
2026 if (pattern != NULL) {
2027 fmt.applyPattern(pattern);
2028 currentPat = pattern;
2031 const char* control = data[i++];
2033 if (uprv_strcmp(control, "fp") == 0) {
2035 const char* datestr = data[i++];
2036 const char* string = data[i++];
2037 UDate date = ref.parse(ctou(datestr), ec);
2038 if (!assertSuccess("parse", ec)) return;
2039 assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
2041 fmt.format(date, str.remove()));
2043 datestr = data[i++];
2044 date = ref.parse(ctou(datestr), ec);
2045 if (!assertSuccess("parse", ec)) return;
2046 UDate parsedate = fmt.parse(ctou(string), ec);
2047 if (assertSuccess((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")", ec)) {
2048 assertEquals((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")",
2049 univ.format(date, str.remove()),
2050 univ.format(parsedate, str2.remove()));
2054 else if (uprv_strcmp(control, "pf") == 0) {
2056 const char* string = data[i++];
2057 const char* datestr = data[i++];
2058 UDate date = ref.parse(ctou(datestr), ec);
2059 if (!assertSuccess("parse", ec)) return;
2060 UDate parsedate = fmt.parse(ctou(string), ec);
2061 if (assertSuccess((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")", ec)) {
2062 assertEquals((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")",
2063 univ.format(date, str.remove()),
2064 univ.format(parsedate, str2.remove()));
2068 assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
2070 fmt.format(date, str.remove()));
2073 else if (uprv_strcmp(control, "F") == 0) {
2074 const char* datestr = data[i++];
2075 const char* string = data[i++];
2076 UDate date = ref.parse(ctou(datestr), ec);
2077 if (!assertSuccess("parse", ec)) return;
2078 assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
2080 fmt.format(date, str.remove()));
2082 UDate parsedate = fmt.parse(string, ec);
2083 if (assertSuccess((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")", ec)) {
2084 assertEquals((UnicodeString)"\"" + currentPat + "\".parse(" + string + ")",
2085 univ.format(date, str.remove()),
2086 univ.format(parsedate, str2.remove()));
2091 errln((UnicodeString)"FAIL: Invalid control string " + control);
2098 * Test formatting. Input is an array that starts
2099 * with the following header:
2101 * [0] = pattern string to parse [i+2] with
2103 * followed by test cases, each of which is 3 array elements:
2105 * [i] = pattern, or null to reuse prior pattern
2106 * [i+1] = data string a
2107 * [i+2] = data string b
2110 * Format date [i+1] and expect string [i+2].
2112 * "y/M/d H:mm:ss.SSSS", "2004/3/10 16:36:31.5679", "2004 03 10 16:36:31.567"
2114 void DateFormatTest::expectFormat(const char** data, int32_t data_length,
2115 const Locale& loc) {
2117 UErrorCode ec = U_ZERO_ERROR;
2118 UnicodeString str, str2;
2119 SimpleDateFormat fmt("", loc, ec);
2120 SimpleDateFormat ref(data[i++], loc, ec);
2121 SimpleDateFormat univ("EE G yyyy MM dd HH:mm:ss.SSS z", loc, ec);
2122 if (U_FAILURE(ec)) {
2123 dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(ec));
2127 UnicodeString currentPat;
2129 while (i<data_length) {
2130 const char* pattern = data[i++];
2131 if (pattern != NULL) {
2132 fmt.applyPattern(pattern);
2133 currentPat = pattern;
2136 const char* datestr = data[i++];
2137 const char* string = data[i++];
2138 UDate date = ref.parse(ctou(datestr), ec);
2139 if (!assertSuccess("parse", ec)) return;
2140 assertEquals((UnicodeString)"\"" + currentPat + "\".format(" + datestr + ")",
2142 fmt.format(date, str.remove()));
2146 void DateFormatTest::TestGenericTime() {
2147 const Locale en("en");
2148 // Note: We no longer parse strings in different styles.
2150 const char* ZDATA[] = {
2151 "yyyy MM dd HH:mm zzz",
2153 "y/M/d H:mm zzzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Standard Time",
2154 "y/M/d H:mm zzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
2155 "y/M/d H:mm vvvv", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
2156 "y/M/d H:mm v", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PT",
2157 // non-generic timezone string influences dst offset even if wrong for date/time
2158 "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",
2159 "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",
2160 "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",
2161 "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",
2162 // generic timezone generates dst offset appropriate for local time
2163 "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",
2164 "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",
2165 "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",
2166 "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",
2167 // daylight savings time transition edge cases.
2168 // time to parse does not really exist, PT interpreted as earlier time
2169 "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",
2170 "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",
2171 "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",
2172 "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",
2173 "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",
2174 "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",
2175 "y/M/d H:mm", "pf", "2005/4/3 2:30", "2005 04 03 03:30 PDT", "2005/4/3 3:30",
2176 // time to parse is ambiguous, PT interpreted as later time
2177 "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",
2178 "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",
2179 "y/M/d H:mm", "pf", "2005/10/30 1:30 PT", "2005 10 30 01:30 PST", "2005/10/30 1:30",
2181 "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",
2182 "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",
2183 "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",
2184 "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",
2185 "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",
2186 "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",
2187 "y/M/d H:mm", "pf", "2004/10/31 1:30", "2004 10 31 01:30 PST", "2004/10/31 1:30",
2190 const char* ZDATA[] = {
2191 "yyyy MM dd HH:mm zzz",
2193 "y/M/d H:mm zzzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Standard Time",
2194 "y/M/d H:mm zzz", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PST",
2195 "y/M/d H:mm vvvv", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 Pacific Time",
2196 "y/M/d H:mm v", "F", "2004 01 01 01:00 PST", "2004/1/1 1:00 PT",
2197 // non-generic timezone string influences dst offset even if wrong for date/time
2198 "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",
2199 "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",
2200 // generic timezone generates dst offset appropriate for local time
2201 "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",
2202 "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",
2203 "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",
2204 "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",
2205 // daylight savings time transition edge cases.
2206 // time to parse does not really exist, PT interpreted as earlier time
2207 "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",
2208 "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",
2209 "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",
2210 "y/M/d H:mm", "pf", "2005/4/3 2:30", "2005 04 03 03:30 PDT", "2005/4/3 3:30",
2211 // time to parse is ambiguous, PT interpreted as later time
2212 "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",
2213 "y/M/d H:mm", "pf", "2005/10/30 1:30 PT", "2005 10 30 01:30 PST", "2005/10/30 1:30",
2215 "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",
2216 "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",
2217 "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",
2218 "y/M/d H:mm", "pf", "2004/10/31 1:30", "2004 10 31 01:30 PST", "2004/10/31 1:30",
2221 const int32_t ZDATA_length = UPRV_LENGTHOF(ZDATA);
2222 expect(ZDATA, ZDATA_length, en);
2224 UErrorCode status = U_ZERO_ERROR;
2226 logln("cross format/parse tests"); // Note: We no longer support cross format/parse
2227 UnicodeString basepat("yy/MM/dd H:mm ");
2228 SimpleDateFormat formats[] = {
2229 SimpleDateFormat(basepat + "vvv", en, status),
2230 SimpleDateFormat(basepat + "vvvv", en, status),
2231 SimpleDateFormat(basepat + "zzz", en, status),
2232 SimpleDateFormat(basepat + "zzzz", en, status)
2234 if (U_FAILURE(status)) {
2235 dataerrln("Fail construct SimpleDateFormat: %s", u_errorName(status));
2238 const int32_t formats_length = UPRV_LENGTHOF(formats);
2241 SimpleDateFormat univ("yyyy MM dd HH:mm zzz", en, status);
2243 const UnicodeString times[] = {
2244 "2004 01 02 03:04 PST",
2245 "2004 07 08 09:10 PDT"
2247 int32_t times_length = UPRV_LENGTHOF(times);
2248 for (int i = 0; i < times_length; ++i) {
2249 UDate d = univ.parse(times[i], status);
2250 logln(UnicodeString("\ntime: ") + d);
2251 for (int j = 0; j < formats_length; ++j) {
2253 formats[j].format(d, test);
2254 logln("\ntest: '" + test + "'");
2255 for (int k = 0; k < formats_length; ++k) {
2256 UDate t = formats[k].parse(test, status);
2257 if (U_SUCCESS(status)) {
2259 errln((UnicodeString)"FAIL: format " + k +
2260 " incorrectly parsed output of format " + j +
2261 " (" + test + "), returned " +
2262 dateToString(t) + " instead of " + dateToString(d));
2264 logln((UnicodeString)"OK: format " + k + " parsed ok");
2266 } else if (status == U_PARSE_ERROR) {
2267 errln((UnicodeString)"FAIL: format " + k +
2268 " could not parse output of format " + j +
2276 void DateFormatTest::TestGenericTimeZoneOrder() {
2277 // generic times should parse the same no matter what the placement of the time zone string
2279 // Note: We no longer support cross style format/parse
2281 //const char* XDATA[] = {
2282 // "yyyy MM dd HH:mm zzz",
2283 // // standard time, explicit daylight/standard
2284 // "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",
2285 // "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",
2286 // "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",
2288 // // standard time, generic
2289 // "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",
2290 // "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",
2291 // "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",
2293 // // dahylight time, explicit daylight/standard
2294 // "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",
2295 // "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",
2296 // "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",
2298 // // daylight time, generic
2299 // "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",
2300 // "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",
2301 // "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",
2303 const char* XDATA[] = {
2304 "yyyy MM dd HH:mm zzz",
2305 // standard time, explicit daylight/standard
2306 "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",
2307 "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",
2308 "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",
2310 // standard time, generic
2311 "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",
2312 "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",
2313 "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",
2315 // dahylight time, explicit daylight/standard
2316 "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",
2317 "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",
2318 "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",
2320 // daylight time, generic
2321 "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",
2322 "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",
2323 "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",
2325 const int32_t XDATA_length = UPRV_LENGTHOF(XDATA);
2327 expect(XDATA, XDATA_length, en);
2330 void DateFormatTest::TestZTimeZoneParsing(void) {
2331 UErrorCode status = U_ZERO_ERROR;
2332 const Locale en("en");
2334 //SimpleDateFormat univ("yyyy-MM-dd'T'HH:mm Z", en, status);
2335 SimpleDateFormat univ("HH:mm Z", en, status);
2336 if (failure(status, "construct SimpleDateFormat", TRUE)) return;
2337 const TimeZone *t = TimeZone::getGMT();
2338 univ.setTimeZone(*t);
2340 univ.setLenient(false);
2341 ParsePosition pp(0);
2343 UnicodeString input;
2344 UnicodeString expected_result;
2346 { "11:00 -0200", "13:00 +0000" },
2347 { "11:00 +0200", "09:00 +0000" },
2348 { "11:00 +0400", "07:00 +0000" },
2349 { "11:00 +0530", "05:30 +0000" }
2352 UnicodeString result;
2353 int32_t tests_length = UPRV_LENGTHOF(tests);
2354 for (int i = 0; i < tests_length; ++i) {
2356 UDate d = univ.parse(tests[i].input, pp);
2357 if(pp.getIndex() != tests[i].input.length()){
2358 errln("Test %i: setZoneString() did not succeed. Consumed: %i instead of %i",
2359 i, pp.getIndex(), tests[i].input.length());
2363 univ.format(d, result);
2364 if(result != tests[i].expected_result) {
2365 errln("Expected " + tests[i].expected_result
2366 + " got " + result);
2369 logln("SUCCESS: Parsed " + tests[i].input
2371 + " expected " + tests[i].expected_result);
2375 void DateFormatTest::TestHost(void)
2377 #if U_PLATFORM_HAS_WIN32_API
2378 Win32DateTimeTest::testLocales(this);
2382 // Relative Date Tests
2384 void DateFormatTest::TestRelative(int daysdelta,
2386 const char *expectChars) {
2388 sprintf(banner, "%d", daysdelta);
2389 UnicodeString bannerStr(banner, "");
2391 UErrorCode status = U_ZERO_ERROR;
2393 FieldPosition pos(FieldPosition::DONT_CARE);
2396 DateFormat *fullrelative = DateFormat::createDateInstance(DateFormat::kFullRelative, loc);
2398 if (fullrelative == NULL) {
2399 dataerrln("DateFormat::createDateInstance(DateFormat::kFullRelative, %s) returned NULL", loc.getName());
2403 DateFormat *full = DateFormat::createDateInstance(DateFormat::kFull , loc);
2406 errln("DateFormat::createDateInstance(DateFormat::kFull, %s) returned NULL", loc.getName());
2410 DateFormat *en_full = DateFormat::createDateInstance(DateFormat::kFull, en);
2412 if (en_full == NULL) {
2413 errln("DateFormat::createDateInstance(DateFormat::kFull, en) returned NULL");
2417 DateFormat *en_fulltime = DateFormat::createDateTimeInstance(DateFormat::kFull,DateFormat::kFull,en);
2419 if (en_fulltime == NULL) {
2420 errln("DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, en) returned NULL");
2424 UnicodeString result;
2425 UnicodeString normalResult;
2426 UnicodeString expect;
2427 UnicodeString parseResult;
2429 Calendar *c = Calendar::createInstance(status);
2432 c->setTime(Calendar::getNow(), status);
2433 if(daysdelta != 0) {
2434 c->add(Calendar::DATE,daysdelta,status);
2438 // calculate the expected string
2439 if(expectChars != NULL) {
2440 expect = expectChars;
2442 full->format(*c, expect, pos); // expected = normal full
2445 fullrelative ->format(*c, result, pos);
2446 en_full ->format(*c, normalResult, pos);
2448 if(result != expect) {
2449 errln("FAIL: Relative Format ["+bannerStr+"] of "+normalResult+" failed, expected "+expect+" but got " + result);
2451 logln("PASS: Relative Format ["+bannerStr+"] of "+normalResult+" got " + result);
2456 UDate d = fullrelative->parse(result, status);
2459 UnicodeString parseFormat; // parse rel->format full
2460 en_full->format(d, parseFormat, status);
2462 UnicodeString origFormat;
2463 en_full->format(*c, origFormat, pos);
2465 if(parseFormat!=origFormat) {
2466 errln("FAIL: Relative Parse ["+bannerStr+"] of "+result+" failed, expected "+parseFormat+" but got "+origFormat);
2468 logln("PASS: Relative Parse ["+bannerStr+"] of "+result+" passed, got "+parseFormat);
2472 delete fullrelative;
2479 void DateFormatTest::TestRelative(void)
2482 TestRelative( 0, en, "today");
2483 TestRelative(-1, en, "yesterday");
2484 TestRelative( 1, en, "tomorrow");
2485 TestRelative( 2, en, NULL);
2486 TestRelative( -2, en, NULL);
2487 TestRelative( 3, en, NULL);
2488 TestRelative( -3, en, NULL);
2489 TestRelative( 300, en, NULL);
2490 TestRelative( -300, en, NULL);
2493 void DateFormatTest::TestRelativeClone(void)
2496 Verify that a cloned formatter gives the same results
2497 and is useable after the original has been deleted.
2499 UErrorCode status = U_ZERO_ERROR;
2501 UDate now = Calendar::getNow();
2502 DateFormat *full = DateFormat::createDateInstance(DateFormat::kFullRelative, loc);
2504 dataerrln("FAIL: Can't create Relative date instance");
2507 UnicodeString result1;
2508 full->format(now, result1, status);
2509 Format *fullClone = full->clone();
2513 UnicodeString result2;
2514 fullClone->format(now, result2, status);
2516 if (result1 != result2) {
2517 errln("FAIL: Clone returned different result from non-clone.");
2522 void DateFormatTest::TestHostClone(void)
2525 Verify that a cloned formatter gives the same results
2526 and is useable after the original has been deleted.
2528 // This is mainly important on Windows.
2529 UErrorCode status = U_ZERO_ERROR;
2530 Locale loc("en_US@compat=host");
2531 UDate now = Calendar::getNow();
2532 DateFormat *full = DateFormat::createDateInstance(DateFormat::kFull, loc);
2534 dataerrln("FAIL: Can't create host date instance");
2537 UnicodeString result1;
2538 full->format(now, result1, status);
2539 Format *fullClone = full->clone();
2543 UnicodeString result2;
2544 fullClone->format(now, result2, status);
2546 if (result1 != result2) {
2547 errln("FAIL: Clone returned different result from non-clone.");
2552 void DateFormatTest::TestHebrewClone(void)
2555 Verify that a cloned formatter gives the same results
2556 and is useable after the original has been deleted.
2558 UErrorCode status = U_ZERO_ERROR;
2559 Locale loc("he@calendar=hebrew");
2560 UDate now = Calendar::getNow();
2561 LocalPointer<DateFormat> fmt(
2562 DateFormat::createDateInstance(DateFormat::kLong, loc));
2564 dataerrln("FAIL: Can't create Hebrew date instance");
2567 UnicodeString result1;
2568 fmt->format(now, result1, status);
2569 LocalPointer<Format> fmtClone(fmt->clone());
2571 // free fmt to be sure that fmtClone is independent of fmt.
2572 fmt.adoptInstead(NULL);
2574 UnicodeString result2;
2575 fmtClone->format(now, result2, status);
2577 if (result1 != result2) {
2578 errln("FAIL: Clone returned different result from non-clone.");
2582 static UBool getActualAndValidLocales(
2583 const Format &fmt, Locale &valid, Locale &actual) {
2584 const SimpleDateFormat* dat = dynamic_cast<const SimpleDateFormat*>(&fmt);
2588 const DateFormatSymbols *sym = dat->getDateFormatSymbols();
2592 UErrorCode status = U_ZERO_ERROR;
2593 valid = sym->getLocale(ULOC_VALID_LOCALE, status);
2594 actual = sym->getLocale(ULOC_ACTUAL_LOCALE, status);
2595 return U_SUCCESS(status);
2598 void DateFormatTest::TestDateFormatSymbolsClone(void)
2601 Verify that a cloned formatter gives the same results
2602 and is useable after the original has been deleted.
2604 Locale loc("de_CH_LUCERNE");
2605 LocalPointer<DateFormat> fmt(
2606 DateFormat::createDateInstance(DateFormat::kDefault, loc));
2609 if (!getActualAndValidLocales(*fmt, valid1, actual1)) {
2610 dataerrln("FAIL: Could not fetch valid + actual locales");
2613 LocalPointer<Format> fmtClone(fmt->clone());
2615 // Free fmt to be sure that fmtClone is really independent of fmt.
2616 fmt.adoptInstead(NULL);
2619 if (!getActualAndValidLocales(*fmtClone, valid2, actual2)) {
2620 errln("FAIL: Could not fetch valid + actual locales");
2623 if (valid1 != valid2 || actual1 != actual2) {
2624 errln("Date format symbol locales of clone don't match original");
2628 void DateFormatTest::TestTimeZoneDisplayName()
2630 // This test data was ported from ICU4J. Don't know why the 6th column in there because it's not being
2632 const char *fallbackTests[][6] = {
2633 { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
2634 { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
2635 { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZZ", "-08:00", "-8:00" },
2636 { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "PST", "America/Los_Angeles" },
2637 { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "Pacific Standard Time", "America/Los_Angeles" },
2638 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
2639 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
2640 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "PDT", "America/Los_Angeles" },
2641 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "Pacific Daylight Time", "America/Los_Angeles" },
2642 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "PT", "America/Los_Angeles" },
2643 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Pacific Time", "America/Los_Angeles" },
2644 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "Los Angeles Time", "America/Los_Angeles" },
2645 { "en_GB", "America/Los_Angeles", "2004-01-15T12:00:00Z", "z", "GMT-8", "America/Los_Angeles" },
2646 { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "Z", "-0700", "-7:00" },
2647 { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
2648 { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "z", "MST", "America/Phoenix" },
2649 { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "zzzz", "Mountain Standard Time", "America/Phoenix" },
2650 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
2651 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
2652 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "z", "MST", "America/Phoenix" },
2653 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "zzzz", "Mountain Standard Time", "America/Phoenix" },
2654 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "v", "MST", "America/Phoenix" },
2655 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "vvvv", "Mountain Standard Time", "America/Phoenix" },
2656 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "VVVV", "Phoenix Time", "America/Phoenix" },
2658 { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2659 { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2660 { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2661 { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" },
2662 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2663 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2664 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2665 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" },
2666 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Time", "America/Buenos_Aires" },
2667 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentina Standard Time", "America/Buenos_Aires" },
2668 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "VVVV", "Buenos Aires Time", "America/Buenos_Aires" },
2670 { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2671 { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2672 { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2673 { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" },
2674 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2675 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2676 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2677 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" },
2678 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Time", "America/Buenos_Aires" },
2679 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentina Standard Time", "America/Buenos_Aires" },
2680 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "VVVV", "Buenos Aires Time", "America/Buenos_Aires" },
2682 { "en", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
2683 { "en", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
2684 { "en", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
2685 { "en", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "Cuba Standard Time", "-5:00" },
2686 { "en", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
2687 { "en", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
2688 { "en", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
2689 { "en", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "Cuba Daylight Time", "-4:00" },
2690 { "en", "America/Havana", "2004-07-15T00:00:00Z", "v", "Cuba Time", "America/Havana" },
2691 { "en", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Cuba Time", "America/Havana" },
2692 { "en", "America/Havana", "2004-07-15T00:00:00Z", "VVVV", "Cuba Time", "America/Havana" },
2694 { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2695 { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
2696 { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2697 { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "Australian Eastern Daylight Time", "+11:00" },
2698 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2699 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
2700 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2701 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "Australian Eastern Standard Time", "+10:00" },
2702 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Sydney Time", "Australia/Sydney" },
2703 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Eastern Australia Time", "Australia/Sydney" },
2704 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "VVVV", "Sydney Time", "Australia/Sydney" },
2706 { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2707 { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
2708 { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2709 { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "Australian Eastern Daylight Time", "+11:00" },
2710 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2711 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
2712 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2713 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "Australian Eastern Standard Time", "+10:00" },
2714 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Sydney Time", "Australia/Sydney" },
2715 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Eastern Australia Time", "Australia/Sydney" },
2716 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "VVVV", "Sydney Time", "Australia/Sydney" },
2718 { "en", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
2719 { "en", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
2720 { "en", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
2721 { "en", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "Greenwich Mean Time", "+0:00" },
2722 { "en", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
2723 { "en", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
2724 { "en", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "Europe/London" },
2725 { "en", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "British Summer Time", "Europe/London" },
2726 // icu en.txt has exemplar city for this time zone
2727 { "en", "Europe/London", "2004-07-15T00:00:00Z", "v", "United Kingdom Time", "Europe/London" },
2728 { "en", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "United Kingdom Time", "Europe/London" },
2729 { "en", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "United Kingdom Time", "Europe/London" },
2731 { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2732 { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2733 { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2734 { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
2735 { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2736 { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2737 { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2738 { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
2739 { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
2740 { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
2743 { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
2744 { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
2745 { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
2746 { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "India Standard Time", "+5:30" },
2747 { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
2748 { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
2749 { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
2750 { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "India Standard Time", "+5:30" },
2751 { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "India Time", "Asia/Calcutta" },
2752 { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "India Standard Time", "Asia/Calcutta" },
2754 // Proper CLDR primary zone support #9733
2755 { "en", "America/Santiago", "2013-01-01T00:00:00Z", "VVVV", "Chile Time", "America/Santiago" },
2756 { "en", "Pacific/Easter", "2013-01-01T00:00:00Z", "VVVV", "Easter Time", "Pacific/Easter" },
2760 { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
2761 { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
2762 { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "-8:00" },
2763 { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "Nordamerikanische Westk\\u00fcsten-Normalzeit", "-8:00" },
2764 { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
2765 { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
2766 { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "-7:00" },
2767 { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "Nordamerikanische Westk\\u00fcsten-Sommerzeit", "-7:00" },
2768 { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "Los Angeles Zeit", "America/Los_Angeles" },
2769 { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Nordamerikanische Westk\\u00fcstenzeit", "America/Los_Angeles" },
2771 { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2772 { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2773 { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2774 { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" },
2775 { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2776 { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2777 { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2778 { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" },
2779 { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Zeit", "America/Buenos_Aires" },
2780 { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentinische Normalzeit", "America/Buenos_Aires" },
2782 { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2783 { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2784 { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2785 { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" },
2786 { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2787 { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2788 { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2789 { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" },
2790 { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Zeit", "America/Buenos_Aires" },
2791 { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentinische Normalzeit", "America/Buenos_Aires" },
2793 { "de", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
2794 { "de", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
2795 { "de", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
2796 { "de", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "Kubanische Normalzeit", "-5:00" },
2797 { "de", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
2798 { "de", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
2799 { "de", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
2800 { "de", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "Kubanische Sommerzeit", "-4:00" },
2801 { "de", "America/Havana", "2004-07-15T00:00:00Z", "v", "Kuba Zeit", "America/Havana" },
2802 { "de", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Kubanische Zeit", "America/Havana" },
2803 // added to test proper fallback of country name
2804 { "de_CH", "America/Havana", "2004-07-15T00:00:00Z", "v", "Kuba Zeit", "America/Havana" },
2805 { "de_CH", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Kubanische Zeit", "America/Havana" },
2807 { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2808 { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
2809 { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2810 { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "Ostaustralische Sommerzeit", "+11:00" },
2811 { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2812 { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
2813 { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2814 { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "Ostaustralische Normalzeit", "+10:00" },
2815 { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Sydney Zeit", "Australia/Sydney" },
2816 { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Ostaustralische Zeit", "Australia/Sydney" },
2818 { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2819 { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
2820 { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2821 { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "Ostaustralische Sommerzeit", "+11:00" },
2822 { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2823 { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
2824 { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2825 { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "Ostaustralische Normalzeit", "+10:00" },
2826 { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Sydney Zeit", "Australia/Sydney" },
2827 { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Ostaustralische Zeit", "Australia/Sydney" },
2829 { "de", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
2830 { "de", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
2831 { "de", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
2832 { "de", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "Mittlere Greenwich-Zeit", "+0:00" },
2833 { "de", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
2834 { "de", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
2835 { "de", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
2836 { "de", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "Britische Sommerzeit", "+1:00" },
2837 { "de", "Europe/London", "2004-07-15T00:00:00Z", "v", "Vereinigtes K\\u00f6nigreich Zeit", "Europe/London" },
2838 { "de", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "Vereinigtes K\\u00f6nigreich Zeit", "Europe/London" },
2840 { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2841 { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2842 { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2843 { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
2844 { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2845 { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2846 { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2847 { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
2848 { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
2849 { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
2852 { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
2853 { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
2854 { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
2855 { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "Indische Zeit", "+5:30" },
2856 { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
2857 { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
2858 { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
2859 { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "Indische Zeit", "+5:30" },
2860 { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "Indien Zeit", "Asia/Calcutta" },
2861 { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "Indische Zeit", "Asia/Calcutta" },
2865 { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
2866 { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
2867 { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "America/Los_Angeles" },
2868 { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u6807\\u51c6\\u65f6\\u95f4", "America/Los_Angeles" },
2869 { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
2870 { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
2871 { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "America/Los_Angeles" },
2872 { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u590f\\u4ee4\\u65f6\\u95f4", "America/Los_Angeles" },
2873 // icu zh.txt has exemplar city for this time zone
2874 { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4", "America/Los_Angeles" },
2875 { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u65f6\\u95f4", "America/Los_Angeles" },
2877 { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2878 { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2879 { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2880 { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" },
2881 { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2882 { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2883 { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2884 { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" },
2885 { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u5E03\\u5B9C\\u8BFA\\u65AF\\u827E\\u5229\\u65AF\\u65F6\\u95F4", "America/Buenos_Aires" },
2886 { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "America/Buenos_Aires" },
2888 { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2889 { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2890 { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2891 { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" },
2892 { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2893 { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2894 { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2895 { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" },
2896 { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u5E03\\u5B9C\\u8BFA\\u65AF\\u827E\\u5229\\u65AF\\u65F6\\u95F4", "America/Buenos_Aires" },
2897 { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "America/Buenos_Aires" },
2899 { "zh", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
2900 { "zh", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
2901 { "zh", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
2902 { "zh", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u53e4\\u5df4\\u6807\\u51c6\\u65f6\\u95f4", "-5:00" },
2903 { "zh", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
2904 { "zh", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
2905 { "zh", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
2906 { "zh", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u53e4\\u5df4\\u590f\\u4ee4\\u65f6\\u95f4", "-4:00" },
2907 { "zh", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u53e4\\u5df4\\u65f6\\u95f4", "America/Havana" },
2908 { "zh", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u53e4\\u5df4\\u65f6\\u95f4", "America/Havana" },
2910 { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2911 { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
2912 { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2913 { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u590f\\u4ee4\\u65f6\\u95f4", "+11:00" },
2914 { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2915 { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
2916 { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2917 { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u6807\\u51c6\\u65f6\\u95f4", "+10:00" },
2918 // icu zh.txt does not have info for this time zone
2919 { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u6089\\u5C3C\\u65F6\\u95F4", "Australia/Sydney" },
2920 { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u65f6\\u95f4", "Australia/Sydney" },
2922 { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
2923 { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
2924 { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
2925 { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u590f\\u4ee4\\u65f6\\u95f4", "+11:00" },
2926 { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
2927 { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
2928 { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
2929 { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u6807\\u51c6\\u65f6\\u95f4", "+10:00" },
2930 { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u6089\\u5C3C\\u65F6\\u95F4", "Australia/Sydney" },
2931 { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u65f6\\u95f4", "Australia/Sydney" },
2933 { "zh", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
2934 { "zh", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
2935 { "zh", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
2936 { "zh", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
2937 { "zh", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
2938 { "zh", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u683C\\u6797\\u5C3C\\u6CBB\\u6807\\u51C6\\u65F6\\u95F4", "+0:00" },
2939 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
2940 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
2941 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
2942 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u82f1\\u56fd\\u590f\\u4ee4\\u65f6\\u95f4", "+1:00" },
2943 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" },
2944 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" },
2945 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" },
2947 { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2948 { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2949 { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2950 { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
2951 { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2952 { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2953 { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2954 { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
2955 { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
2956 { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
2959 { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
2960 { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
2961 { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
2962 { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u5370\\u5ea6\\u65f6\\u95f4", "+5:30" },
2963 { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
2964 { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
2965 { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
2966 { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u5370\\u5ea6\\u65f6\\u95f4", "+5:30" },
2967 { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u5370\\u5ea6\\u65f6\\u95f4", "Asia/Calcutta" },
2968 { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u5370\\u5ea6\\u65f6\\u95f4", "Asia/Calcutta" },
2972 { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
2973 { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
2974 { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "-8:00" },
2975 { "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" },
2976 { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
2977 { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
2978 { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "-7:00" },
2979 { "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" },
2980 { "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" },
2981 { "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" },
2983 { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2984 { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2985 { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2986 { "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" },
2987 { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2988 { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2989 { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2990 { "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" },
2991 { "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" },
2992 { "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" },
2994 { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
2995 { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
2996 { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
2997 { "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" },
2998 { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
2999 { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3000 { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3001 { "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" },
3002 { "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" },
3003 { "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" },
3005 { "hi", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
3006 { "hi", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
3007 { "hi", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
3008 { "hi", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u092e\\u093e\\u0928\\u0915 \\u0938\\u092e\\u092f", "-5:00" },
3009 { "hi", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
3010 { "hi", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
3011 { "hi", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
3012 { "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" },
3013 { "hi", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0938\\u092E\\u092F", "America/Havana" },
3014 { "hi", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0938\\u092e\\u092f", "America/Havana" },
3016 { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
3017 { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
3018 { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
3019 { "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" },
3020 { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
3021 { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
3022 { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
3023 { "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" },
3024 { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u0938\\u093F\\u0921\\u0928\\u0940 \\u0938\\u092E\\u092F", "Australia/Sydney" },
3025 { "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" },
3027 { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
3028 { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
3029 { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
3030 { "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" },
3031 { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
3032 { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
3033 { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
3034 { "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" },
3035 { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u0938\\u093F\\u0921\\u0928\\u0940 \\u0938\\u092E\\u092F", "Australia/Sydney" },
3036 { "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" },
3038 { "hi", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
3039 { "hi", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
3040 { "hi", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
3041 { "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" },
3042 { "hi", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
3043 { "hi", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
3044 { "hi", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
3045 { "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" },
3046 { "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" },
3047 { "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" },
3049 { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3050 { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3051 { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3052 { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3053 { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3054 { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3055 { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3056 { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3057 { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
3058 { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
3060 { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
3061 { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
3062 { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "IST", "+5:30" },
3063 { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "+5:30" },
3064 { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
3065 { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
3066 { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "IST", "+05:30" },
3067 { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "+5:30" },
3068 { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "IST", "Asia/Calcutta" },
3069 { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "Asia/Calcutta" },
3073 { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
3074 { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-08:00", "-8:00" },
3075 { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-8", "America/Los_Angeles" },
3076 { "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" },
3077 { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
3078 { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-07:00", "-7:00" },
3079 { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-7", "America/Los_Angeles" },
3080 { "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" },
3081 // icu bg.txt has exemplar city for this time zone
3082 { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u041B\\u043E\\u0441 \\u0410\\u043D\\u0434\\u0436\\u0435\\u043B\\u0438\\u0441", "America/Los_Angeles" },
3083 { "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" },
3084 { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "\\u041B\\u043E\\u0441 \\u0410\\u043D\\u0434\\u0436\\u0435\\u043B\\u0438\\u0441", "America/Los_Angeles" },
3086 { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3087 { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
3088 { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
3089 { "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" },
3090 { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3091 { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
3092 { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
3093 { "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" },
3094 { "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" },
3095 { "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" },
3097 { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3098 { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
3099 { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
3100 { "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" },
3101 { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3102 { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
3103 { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
3104 { "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" },
3105 // icu bg.txt does not have info for this time zone
3106 { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u0411\\u0443\\u0435\\u043D\\u043E\\u0441 \\u0410\\u0439\\u0440\\u0435\\u0441", "America/Buenos_Aires" },
3107 { "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" },
3109 { "bg", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
3110 { "bg", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-05:00", "-5:00" },
3111 { "bg", "America/Havana", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-5", "-5:00" },
3112 { "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" },
3113 { "bg", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
3114 { "bg", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-04:00", "-4:00" },
3115 { "bg", "America/Havana", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-4", "-4:00" },
3116 { "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" },
3117 { "bg", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u041a\\u0443\\u0431\\u0430", "America/Havana" },
3118 { "bg", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u041a\\u0443\\u0431\\u0438\\u043d\\u0441\\u043a\\u043e \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Havana" },
3120 { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
3121 { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11:00", "+11:00" },
3122 { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11", "+11:00" },
3123 { "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" },
3124 { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
3125 { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10:00", "+10:00" },
3126 { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10", "+10:00" },
3127 { "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" },
3128 { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u0421\\u0438\\u0434\\u043D\\u0438", "Australia/Sydney" },
3129 { "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" },
3131 { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
3132 { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11:00", "+11:00" },
3133 { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11", "+11:00" },
3134 { "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" },
3135 { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
3136 { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10:00", "+10:00" },
3137 { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10", "+10:00" },
3138 { "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" },
3139 { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u0421\\u0438\\u0434\\u043D\\u0438", "Australia/Sydney" },
3140 { "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" },
3142 { "bg", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
3143 { "bg", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" },
3144 { "bg", "Europe/London", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" },
3145 { "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" },
3146 { "bg", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
3147 { "bg", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+01:00", "+1:00" },
3148 { "bg", "Europe/London", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+1", "+1:00" },
3149 { "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" },
3150 { "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" },
3151 { "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" },
3153 { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3154 { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
3155 { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
3156 { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
3157 { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3158 { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
3159 { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
3160 { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
3161 { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" },
3162 { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" },
3165 { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
3166 { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+05:30", "+5:30" },
3167 { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+5:30", "+5:30" },
3168 { "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" },
3169 { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
3170 { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+05:30", "+5:30" },
3171 { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+5:30", "+05:30" },
3172 { "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" },
3173 { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u0418\\u043D\\u0434\\u0438\\u044F", "Asia/Calcutta" },
3174 { "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" },
3177 { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
3178 { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
3179 { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "America/Los_Angeles" },
3180 { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u30a2\\u30e1\\u30ea\\u30ab\\u592a\\u5e73\\u6d0b\\u6a19\\u6e96\\u6642", "America/Los_Angeles" },
3181 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-700" },
3182 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
3183 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "America/Los_Angeles" },
3184 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u30a2\\u30e1\\u30ea\\u30ab\\u592a\\u5e73\\u6d0b\\u590f\\u6642\\u9593", "America/Los_Angeles" },
3185 // icu ja.txt has exemplar city for this time zone
3186 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u30ED\\u30B5\\u30F3\\u30BC\\u30EB\\u30B9\\u6642\\u9593", "America/Los_Angeles" },
3187 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u30A2\\u30E1\\u30EA\\u30AB\\u592A\\u5e73\\u6D0B\\u6642\\u9593", "America/Los_Angeles" },
3188 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "\\u30ED\\u30B5\\u30F3\\u30BC\\u30EB\\u30B9\\u6642\\u9593", "America/Los_Angeles" },
3190 { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3191 { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3192 { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3193 { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" },
3194 { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3195 { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3196 { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3197 { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" },
3198 // icu ja.txt does not have info for this time zone
3199 { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u30D6\\u30A8\\u30CE\\u30B9\\u30A2\\u30A4\\u30EC\\u30B9\\u6642\\u9593", "America/Buenos_Aires" },
3200 { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "America/Buenos_Aires" },
3202 { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3203 { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3204 { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3205 { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" },
3206 { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3207 { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3208 { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3209 { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" },
3210 { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u30D6\\u30A8\\u30CE\\u30B9\\u30A2\\u30A4\\u30EC\\u30B9\\u6642\\u9593", "America/Buenos_Aires" },
3211 { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "America/Buenos_Aires" },
3213 { "ja", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
3214 { "ja", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
3215 { "ja", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
3216 { "ja", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u30AD\\u30E5\\u30FC\\u30D0\\u6A19\\u6E96\\u6642", "-5:00" },
3217 { "ja", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
3218 { "ja", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
3219 { "ja", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
3220 { "ja", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u30AD\\u30E5\\u30FC\\u30D0\\u590F\\u6642\\u9593", "-4:00" },
3221 { "ja", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u30ad\\u30e5\\u30fc\\u30d0\\u6642\\u9593", "America/Havana" },
3222 { "ja", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u30ad\\u30e5\\u30fc\\u30d0\\u6642\\u9593", "America/Havana" },
3224 { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
3225 { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
3226 { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
3227 { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u590F\\u6642\\u9593", "+11:00" },
3228 { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
3229 { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
3230 { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
3231 { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6A19\\u6E96\\u6642", "+10:00" },
3232 // icu ja.txt does not have info for this time zone
3233 { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u30B7\\u30C9\\u30CB\\u30FC\\u6642\\u9593", "Australia/Sydney" },
3234 { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6642\\u9593", "Australia/Sydney" },
3236 { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
3237 { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
3238 { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
3239 { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u590F\\u6642\\u9593", "+11:00" },
3240 { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
3241 { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
3242 { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
3243 { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6A19\\u6E96\\u6642", "+10:00" },
3244 { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u30B7\\u30C9\\u30CB\\u30FC\\u6642\\u9593", "Australia/Sydney" },
3245 { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6642\\u9593", "Australia/Sydney" },
3247 { "ja", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
3248 { "ja", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
3249 { "ja", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
3250 { "ja", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u30B0\\u30EA\\u30CB\\u30C3\\u30B8\\u6A19\\u6E96\\u6642", "+0:00" },
3251 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
3252 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
3253 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
3254 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u82f1\\u56fd\\u590f\\u6642\\u9593", "+1:00" },
3255 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u30a4\\u30ae\\u30ea\\u30b9\\u6642\\u9593", "Europe/London" },
3256 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u30a4\\u30ae\\u30ea\\u30b9\\u6642\\u9593", "Europe/London" },
3257 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "\\u30a4\\u30ae\\u30ea\\u30b9\\u6642\\u9593", "Europe/London" },
3259 { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3260 { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3261 { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3262 { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3263 { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3264 { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3265 { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3266 { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3267 { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
3268 { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
3271 { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
3272 { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
3273 { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
3274 { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u30A4\\u30F3\\u30C9\\u6A19\\u6E96\\u6642", "+5:30" },
3275 { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
3276 { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
3277 { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
3278 { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u30A4\\u30F3\\u30C9\\u6A19\\u6E96\\u6642", "+5:30" },
3279 { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u30A4\\u30F3\\u30C9\\u6642\\u9593", "Asia/Calcutta" },
3280 { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u30A4\\u30F3\\u30C9\\u6A19\\u6E96\\u6642", "Asia/Calcutta" },
3284 { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" },
3285 { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" },
3286 { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "-8:00" },
3287 { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "GMT-08:00", "-8:00" },
3288 { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" },
3289 { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" },
3290 { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "-7:00" },
3291 { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "GMT-07:00", "-7:00" },
3292 { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "Los Angeles", "America/Los_Angeles" },
3293 { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Los Angeles", "America/Los_Angeles" },
3295 { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3296 { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3297 { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3298 { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3299 { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3300 { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3301 { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3302 { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3303 { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires", "America/Buenos_Aires" },
3304 { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Buenos Aires", "America/Buenos_Aires" },
3306 { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3307 { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3308 { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3309 { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3310 { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3311 { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3312 { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3313 { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3314 { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires", "America/Buenos_Aires" },
3315 { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Buenos Aires", "America/Buenos_Aires" },
3317 { "ti", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" },
3318 { "ti", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" },
3319 { "ti", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" },
3320 { "ti", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "GMT-05:00", "-5:00" },
3321 { "ti", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" },
3322 { "ti", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" },
3323 { "ti", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" },
3324 { "ti", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "GMT-04:00", "-4:00" },
3325 { "ti", "America/Havana", "2004-07-15T00:00:00Z", "v", "CU", "America/Havana" },
3326 { "ti", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "CU", "America/Havana" },
3328 { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
3329 { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
3330 { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
3331 { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" },
3332 { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
3333 { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
3334 { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
3335 { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" },
3336 { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Sydney", "Australia/Sydney" },
3337 { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Sydney", "Australia/Sydney" },
3339 { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" },
3340 { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" },
3341 { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" },
3342 { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" },
3343 { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" },
3344 { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" },
3345 { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" },
3346 { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" },
3347 { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Sydney", "Australia/Sydney" },
3348 { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Sydney", "Australia/Sydney" },
3350 { "ti", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" },
3351 { "ti", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" },
3352 { "ti", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" },
3353 { "ti", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "GMT", "+0:00" },
3354 { "ti", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" },
3355 { "ti", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" },
3356 { "ti", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" },
3357 { "ti", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "GMT+01:00", "+1:00" },
3358 { "ti", "Europe/London", "2004-07-15T00:00:00Z", "v", "GB", "Europe/London" },
3359 { "ti", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "GB", "Europe/London" },
3361 { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" },
3362 { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3363 { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3364 { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3365 { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" },
3366 { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" },
3367 { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" },
3368 { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" },
3369 { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" },
3370 { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" },
3373 { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" },
3374 { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
3375 { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" },
3376 { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
3377 { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" },
3378 { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" },
3379 { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" },
3380 { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" },
3381 { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "IN", "Alna/Calcutta" },
3382 { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "IN", "Asia/Calcutta" },
3384 // Ticket#8589 Partial location name to use country name if the zone is the golden
3385 // zone for the time zone's country.
3386 { "en_MX", "America/Chicago", "1995-07-15T00:00:00Z", "vvvv", "Central Time (United States)", "America/Chicago"},
3388 // Tests proper handling of time zones that should have empty sets when inherited from the parent.
3389 // For example, en_GB understands CET as Central European Time, but en_HK, which inherits from en_GB
3391 { "en_GB", "Europe/Paris", "2004-01-15T00:00:00Z", "zzzz", "Central European Standard Time", "+1:00"},
3392 { "en_GB", "Europe/Paris", "2004-07-15T00:00:00Z", "zzzz", "Central European Summer Time", "+2:00"},
3393 { "en_GB", "Europe/Paris", "2004-01-15T00:00:00Z", "z", "CET", "+1:00"},
3394 { "en_GB", "Europe/Paris", "2004-07-15T00:00:00Z", "z", "CEST", "+2:00"},
3395 { "en_HK", "Europe/Paris", "2004-01-15T00:00:00Z", "zzzz", "Central European Standard Time", "+1:00"},
3396 { "en_HK", "Europe/Paris", "2004-07-15T00:00:00Z", "zzzz", "Central European Summer Time", "+2:00"},
3397 { "en_HK", "Europe/Paris", "2004-01-15T00:00:00Z", "z", "GMT+1", "+1:00"},
3398 { "en_HK", "Europe/Paris", "2004-07-15T00:00:00Z", "z", "GMT+2", "+2:00"},
3400 { NULL, NULL, NULL, NULL, NULL, NULL },
3403 UErrorCode status = U_ZERO_ERROR;
3404 Calendar *cal = GregorianCalendar::createInstance(status);
3405 if (failure(status, "GregorianCalendar::createInstance", TRUE)) return;
3406 SimpleDateFormat testfmt(UnicodeString("yyyy-MM-dd'T'HH:mm:ss'Z'"), status);
3407 if (failure(status, "SimpleDateFormat constructor", TRUE)) return;
3408 testfmt.setTimeZone(*TimeZone::getGMT());
3410 for (int i = 0; fallbackTests[i][0]; i++) {
3411 const char **testLine = fallbackTests[i];
3412 UnicodeString info[5];
3413 for ( int j = 0 ; j < 5 ; j++ ) {
3414 info[j] = UnicodeString(testLine[j], -1, US_INV);
3416 info[4] = info[4].unescape();
3417 logln("%s;%s;%s;%s", testLine[0], testLine[1], testLine[2], testLine[3]);
3419 TimeZone *tz = TimeZone::createTimeZone(info[1]);
3421 UDate d = testfmt.parse(testLine[2], status);
3422 cal->setTime(d, status);
3423 if (U_FAILURE(status)) {
3424 errln(UnicodeString("Failed to set date: ") + testLine[2]);
3427 SimpleDateFormat fmt(info[3], Locale(testLine[0]),status);
3429 cal->adoptTimeZone(tz);
3430 UnicodeString result;
3431 FieldPosition pos(FieldPosition::DONT_CARE);
3432 fmt.format(*cal,result,pos);
3433 if (result != info[4]) {
3434 errln(info[0] + ";" + info[1] + ";" + info[2] + ";" + info[3] + " expected: '" +
3435 info[4] + "' but got: '" + result + "'");
3441 void DateFormatTest::TestRoundtripWithCalendar(void) {
3442 UErrorCode status = U_ZERO_ERROR;
3444 TimeZone *tz = TimeZone::createTimeZone("Europe/Paris");
3445 TimeZone *gmt = TimeZone::createTimeZone("Etc/GMT");
3447 Calendar *calendars[] = {
3448 Calendar::createInstance(*tz, Locale("und@calendar=gregorian"), status),
3449 Calendar::createInstance(*tz, Locale("und@calendar=buddhist"), status),
3450 // Calendar::createInstance(*tz, Locale("und@calendar=hebrew"), status),
3451 Calendar::createInstance(*tz, Locale("und@calendar=islamic"), status),
3452 Calendar::createInstance(*tz, Locale("und@calendar=japanese"), status),
3455 if (U_FAILURE(status)) {
3456 dataerrln("Failed to initialize calendars: %s", u_errorName(status));
3457 for (int i = 0; calendars[i] != NULL; i++) {
3458 delete calendars[i];
3463 //FIXME The formatters commented out below are currently failing because of
3464 // the calendar calculation problem reported by #6691
3466 // The order of test formatters must match the order of calendars above.
3467 DateFormat *formatters[] = {
3468 DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("en_US")), //calendar=gregorian
3469 DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("th_TH")), //calendar=buddhist
3470 // DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("he_IL@calendar=hebrew")),
3471 DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("ar_EG@calendar=islamic")),
3472 // DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("ja_JP@calendar=japanese")),
3476 UDate d = Calendar::getNow();
3481 for (int i = 0; formatters[i] != NULL; i++) {
3483 fpos.setBeginIndex(0);
3484 fpos.setEndIndex(0);
3485 calendars[i]->setTime(d, status);
3487 // Normal case output - the given calendar matches the calendar
3488 // used by the formatter
3489 formatters[i]->format(*calendars[i], buf, fpos);
3490 UnicodeString refStr(buf);
3492 for (int j = 0; calendars[j] != NULL; j++) {
3497 fpos.setBeginIndex(0);
3498 fpos.setEndIndex(0);
3499 calendars[j]->setTime(d, status);
3501 // Even the different calendar type is specified,
3502 // we should get the same result.
3503 formatters[i]->format(*calendars[j], buf, fpos);
3504 if (refStr != buf) {
3505 errln((UnicodeString)"FAIL: Different format result with a different calendar for the same time -"
3506 + "\n Reference calendar type=" + calendars[i]->getType()
3507 + "\n Another calendar type=" + calendars[j]->getType()
3508 + "\n Expected result=" + refStr
3509 + "\n Actual result=" + buf);
3513 calendars[i]->setTimeZone(*gmt);
3514 calendars[i]->clear();
3515 ppos.setErrorIndex(-1);
3518 // Normal case parse result - the given calendar matches the calendar
3519 // used by the formatter
3520 formatters[i]->parse(refStr, *calendars[i], ppos);
3522 for (int j = 0; calendars[j] != NULL; j++) {
3526 calendars[j]->setTimeZone(*gmt);
3527 calendars[j]->clear();
3528 ppos.setErrorIndex(-1);
3531 // Even the different calendar type is specified,
3532 // we should get the same time and time zone.
3533 formatters[i]->parse(refStr, *calendars[j], ppos);
3534 if (calendars[i]->getTime(status) != calendars[j]->getTime(status)
3535 || calendars[i]->getTimeZone() != calendars[j]->getTimeZone()) {
3537 errln((UnicodeString)"FAIL: Different parse result with a different calendar for the same string -"
3538 + "\n Reference calendar type=" + calendars[i]->getType()
3539 + "\n Another calendar type=" + calendars[j]->getType()
3540 + "\n Date string=" + refStr
3541 + "\n Expected time=" + calendars[i]->getTime(status)
3542 + "\n Expected time zone=" + calendars[i]->getTimeZone().getID(tzid)
3543 + "\n Actual time=" + calendars[j]->getTime(status)
3544 + "\n Actual time zone=" + calendars[j]->getTimeZone().getID(tzid));
3547 if (U_FAILURE(status)) {
3548 errln((UnicodeString)"FAIL: " + u_errorName(status));
3555 for (int i = 0; calendars[i] != NULL; i++) {
3556 delete calendars[i];
3558 for (int i = 0; formatters[i] != NULL; i++) {
3559 delete formatters[i];
3564 void DateFormatTest::TestRelativeError(void)
3569 DateFormat *en_reltime_reldate = DateFormat::createDateTimeInstance(DateFormat::kFullRelative,DateFormat::kFullRelative,en);
3570 if(en_reltime_reldate == NULL) {
3571 logln("PASS: rel date/rel time failed");
3573 errln("FAIL: rel date/rel time created, should have failed.");
3574 delete en_reltime_reldate;
3578 void DateFormatTest::TestRelativeOther(void)
3580 logln("Nothing in this test. When we get more data from CLDR, put in some tests of -2, +2, etc. ");
3584 void DateFormatTest::Test6338(void)
3586 UErrorCode status = U_ZERO_ERROR;
3588 SimpleDateFormat *fmt1 = new SimpleDateFormat(UnicodeString("y-M-d"), Locale("ar"), status);
3589 if (failure(status, "new SimpleDateFormat", TRUE)) return;
3591 UDate dt1 = date(2008-1900, UCAL_JUNE, 10, 12, 00);
3593 str1 = fmt1->format(dt1, str1);
3596 UDate dt11 = fmt1->parse(str1, status);
3597 failure(status, "fmt->parse");
3599 UnicodeString str11;
3600 str11 = fmt1->format(dt11, str11);
3603 if (str1 != str11) {
3604 errln((UnicodeString)"FAIL: Different dates str1:" + str1
3605 + " str2:" + str11);
3611 status = U_ZERO_ERROR;
3612 SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("y M d"), Locale("ar"), status);
3613 failure(status, "new SimpleDateFormat");
3615 UDate dt2 = date(2008-1900, UCAL_JUNE, 10, 12, 00);
3617 str2 = fmt2->format(dt2, str2);
3620 UDate dt22 = fmt2->parse(str2, status);
3621 failure(status, "fmt->parse");
3623 UnicodeString str22;
3624 str22 = fmt2->format(dt22, str22);
3627 if (str2 != str22) {
3628 errln((UnicodeString)"FAIL: Different dates str1:" + str2
3629 + " str2:" + str22);
3635 status = U_ZERO_ERROR;
3636 SimpleDateFormat *fmt3 = new SimpleDateFormat(UnicodeString("y-M-d"), Locale("en-us"), status);
3637 failure(status, "new SimpleDateFormat");
3639 UDate dt3 = date(2008-1900, UCAL_JUNE, 10, 12, 00);
3641 str3 = fmt3->format(dt3, str3);
3644 UDate dt33 = fmt3->parse(str3, status);
3645 failure(status, "fmt->parse");
3647 UnicodeString str33;
3648 str33 = fmt3->format(dt33, str33);
3651 if (str3 != str33) {
3652 errln((UnicodeString)"FAIL: Different dates str1:" + str3
3653 + " str2:" + str33);
3659 status = U_ZERO_ERROR;
3660 SimpleDateFormat *fmt4 = new SimpleDateFormat(UnicodeString("y M d"), Locale("en-us"), status);
3661 failure(status, "new SimpleDateFormat");
3663 UDate dt4 = date(2008-1900, UCAL_JUNE, 10, 12, 00);
3665 str4 = fmt4->format(dt4, str4);
3668 UDate dt44 = fmt4->parse(str4, status);
3669 failure(status, "fmt->parse");
3671 UnicodeString str44;
3672 str44 = fmt4->format(dt44, str44);
3675 if (str4 != str44) {
3676 errln((UnicodeString)"FAIL: Different dates str1:" + str4
3677 + " str2:" + str44);
3683 void DateFormatTest::Test6726(void)
3686 // UErrorCode status = U_ZERO_ERROR;
3688 // fmtf, fmtl, fmtm, fmts;
3689 UnicodeString strf, strl, strm, strs;
3690 UDate dt = date(2008-1900, UCAL_JUNE, 10, 12, 00);
3693 DateFormat* fmtf = DateFormat::createDateTimeInstance(DateFormat::FULL, DateFormat::FULL, loc);
3694 DateFormat* fmtl = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::FULL, loc);
3695 DateFormat* fmtm = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL, loc);
3696 DateFormat* fmts = DateFormat::createDateTimeInstance(DateFormat::SHORT, DateFormat::FULL, loc);
3697 if (fmtf == NULL || fmtl == NULL || fmtm == NULL || fmts == NULL) {
3698 dataerrln("Unable to create DateFormat. got NULL.");
3699 /* It may not be true that if one is NULL all is NULL. Just to be safe. */
3707 strf = fmtf->format(dt, strf);
3708 strl = fmtl->format(dt, strl);
3709 strm = fmtm->format(dt, strm);
3710 strs = fmts->format(dt, strs);
3713 logln("strm.charAt(10)=%04X wanted 0x20\n", strm.charAt(10));
3714 if (strm.charAt(10) != UChar(0x0020)) {
3715 errln((UnicodeString)"FAIL: Improper formatted date: " + strm );
3717 logln("strs.charAt(10)=%04X wanted 0x20\n", strs.charAt(8));
3718 if (strs.charAt(10) != UChar(0x0020)) {
3719 errln((UnicodeString)"FAIL: Improper formatted date: " + strs);
3731 * Test DateFormat's parsing of default GMT variants. See ticket#6135
3733 void DateFormatTest::TestGMTParsing() {
3734 const char* DATA[] = {
3737 // pattern, input, expected output (in quotes)
3738 "HH:mm:ss Z", "10:20:30 GMT+03:00", "10:20:30 +0300",
3739 "HH:mm:ss Z", "10:20:30 UT-02:00", "10:20:30 -0200",
3740 "HH:mm:ss Z", "10:20:30 GMT", "10:20:30 +0000",
3741 "HH:mm:ss vvvv", "10:20:30 UT+10:00", "10:20:30 +1000",
3742 "HH:mm:ss zzzz", "10:20:30 UTC", "10:20:30 +0000", // standalone "UTC"
3743 "ZZZZ HH:mm:ss", "UT 10:20:30", "10:20:30 +0000",
3744 "z HH:mm:ss", "UT+0130 10:20:30", "10:20:30 +0130",
3745 "z HH:mm:ss", "UTC+0130 10:20:30", "10:20:30 +0130",
3746 // Note: GMT-1100 no longer works because of the introduction of the short
3747 // localized GMT support. Previous implementation support this level of
3748 // leniency (no separator char in localized GMT format), but the new
3749 // implementation handles GMT-11 as the legitimate short localized GMT format
3750 // and stop at there. Otherwise, roundtrip would be broken.
3751 //"HH mm Z ss", "10 20 GMT-1100 30", "10:20:30 -1100",
3752 "HH mm Z ss", "10 20 GMT-11 30", "10:20:30 -1100",
3753 "HH:mm:ssZZZZZ", "14:25:45Z", "14:25:45 +0000",
3754 "HH:mm:ssZZZZZ", "15:00:00-08:00", "15:00:00 -0800",
3756 const int32_t DATA_len = UPRV_LENGTHOF(DATA);
3757 expectParse(DATA, DATA_len, Locale("en"));
3760 // Test case for localized GMT format parsing
3761 // with no delimitters in offset format (Chinese locale)
3762 void DateFormatTest::Test6880() {
3763 UErrorCode status = U_ZERO_ERROR;
3764 UDate d1, d2, dp1, dp2, dexp1, dexp2;
3765 UnicodeString s1, s2;
3767 TimeZone *tz = TimeZone::createTimeZone("Asia/Shanghai");
3768 GregorianCalendar gcal(*tz, status);
3769 if (failure(status, "construct GregorianCalendar", TRUE)) return;
3772 gcal.set(1900, UCAL_JULY, 1, 12, 00); // offset 8:05:43
3773 d1 = gcal.getTime(status);
3776 gcal.set(1950, UCAL_JULY, 1, 12, 00); // offset 8:00
3777 d2 = gcal.getTime(status);
3780 gcal.set(1970, UCAL_JANUARY, 1, 12, 00);
3781 dexp2 = gcal.getTime(status);
3782 dexp1 = dexp2 - (5*60 + 43)*1000; // subtract 5m43s
3784 if (U_FAILURE(status)) {
3785 errln("FAIL: Gregorian calendar error");
3788 DateFormat *fmt = DateFormat::createTimeInstance(DateFormat::kFull, Locale("zh"));
3790 dataerrln("Unable to create DateFormat. Got NULL.");
3793 fmt->adoptTimeZone(tz);
3795 fmt->format(d1, s1);
3796 fmt->format(d2, s2);
3798 dp1 = fmt->parse(s1, status);
3799 dp2 = fmt->parse(s2, status);
3801 if (U_FAILURE(status)) {
3802 errln("FAIL: Parse failure");
3806 errln("FAIL: Failed to parse " + s1 + " parsed: " + dp1 + " expected: " + dexp1);
3809 errln("FAIL: Failed to parse " + s2 + " parsed: " + dp2 + " expected: " + dexp2);
3816 const char * localeStr;
3819 UnicodeString datePattern;
3820 UnicodeString dateString;
3823 void DateFormatTest::TestNumberAsStringParsing()
3825 const NumAsStringItem items[] = {
3826 // loc lenient fail? datePattern dateString
3827 { "", FALSE, TRUE, UnicodeString("y MMMM d HH:mm:ss"), UnicodeString("2009 7 14 08:43:57") },
3828 { "", TRUE, FALSE, UnicodeString("y MMMM d HH:mm:ss"), UnicodeString("2009 7 14 08:43:57") },
3829 { "en", FALSE, FALSE, UnicodeString("MMM d, y"), UnicodeString("Jul 14, 2009") },
3830 { "en", TRUE, FALSE, UnicodeString("MMM d, y"), UnicodeString("Jul 14, 2009") },
3831 { "en", FALSE, TRUE, UnicodeString("MMM d, y"), UnicodeString("7 14, 2009") },
3832 { "en", TRUE, FALSE, UnicodeString("MMM d, y"), UnicodeString("7 14, 2009") },
3833 { "ja", FALSE, FALSE, UnicodeString("yyyy/MM/dd"), UnicodeString("2009/07/14") },
3834 { "ja", TRUE, FALSE, UnicodeString("yyyy/MM/dd"), UnicodeString("2009/07/14") },
3835 //{ "ja", FALSE, FALSE, UnicodeString("yyyy/MMMMM/d"), UnicodeString("2009/7/14") }, // #8860 covers test failure
3836 { "ja", TRUE, FALSE, UnicodeString("yyyy/MMMMM/d"), UnicodeString("2009/7/14") },
3837 { "ja", FALSE, FALSE, CharsToUnicodeString("y\\u5E74M\\u6708d\\u65E5"), CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5") },
3838 { "ja", TRUE, FALSE, CharsToUnicodeString("y\\u5E74M\\u6708d\\u65E5"), CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5") },
3839 { "ja", FALSE, FALSE, CharsToUnicodeString("y\\u5E74MMMd\\u65E5"), CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5") },
3840 { "ja", TRUE, FALSE, CharsToUnicodeString("y\\u5E74MMMd\\u65E5"), CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5") }, // #8820 fixes test failure
3841 { "ko", FALSE, FALSE, UnicodeString("yyyy. M. d."), UnicodeString("2009. 7. 14.") },
3842 { "ko", TRUE, FALSE, UnicodeString("yyyy. M. d."), UnicodeString("2009. 7. 14.") },
3843 { "ko", FALSE, FALSE, UnicodeString("yyyy. MMMMM d."), CharsToUnicodeString("2009. 7\\uC6D4 14.") },
3844 { "ko", TRUE, FALSE, UnicodeString("yyyy. MMMMM d."), CharsToUnicodeString("2009. 7\\uC6D4 14.") }, // #8820 fixes test failure
3845 { "ko", FALSE, FALSE, CharsToUnicodeString("y\\uB144 M\\uC6D4 d\\uC77C"), CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") },
3846 { "ko", TRUE, FALSE, CharsToUnicodeString("y\\uB144 M\\uC6D4 d\\uC77C"), CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") },
3847 { "ko", FALSE, FALSE, CharsToUnicodeString("y\\uB144 MMM d\\uC77C"), CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") },
3848 { "ko", TRUE, FALSE, CharsToUnicodeString("y\\uB144 MMM d\\uC77C"), CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") }, // #8820 fixes test failure
3849 { NULL, FALSE, FALSE, UnicodeString(""), UnicodeString("") }
3851 const NumAsStringItem * itemPtr;
3852 for (itemPtr = items; itemPtr->localeStr != NULL; itemPtr++ ) {
3853 Locale locale = Locale::createFromName(itemPtr->localeStr);
3854 UErrorCode status = U_ZERO_ERROR;
3855 SimpleDateFormat *formatter = new SimpleDateFormat(itemPtr->datePattern, locale, status);
3856 if (formatter == NULL || U_FAILURE(status)) {
3857 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
3861 formatter->setLenient(itemPtr->lenient);
3862 formatter->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->lenient, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->lenient, status);
3863 UDate date1 = formatter->parse(itemPtr->dateString, status);
3864 if (U_FAILURE(status)) {
3865 if (!itemPtr->expectFail) {
3866 errln("FAIL, err when expected success: Locale \"" + UnicodeString(itemPtr->localeStr) + "\", lenient " + itemPtr->lenient +
3867 ": using pattern \"" + itemPtr->datePattern + "\", could not parse \"" + itemPtr->dateString + "\"; err: " + u_errorName(status) );
3869 } else if (itemPtr->expectFail) {
3870 errln("FAIL, expected err but got none: Locale \"" + UnicodeString(itemPtr->localeStr) + "\", lenient " + itemPtr->lenient +
3871 ": using pattern \"" + itemPtr->datePattern + "\", did parse \"" + itemPtr->dateString + "\"." );
3872 } else if (!itemPtr->lenient) {
3873 UnicodeString formatted;
3874 formatter->format(date1, formatted);
3875 if (formatted != itemPtr->dateString) {
3876 errln("FAIL, mismatch formatting parsed date: Locale \"" + UnicodeString(itemPtr->localeStr) + "\", lenient " + itemPtr->lenient +
3877 ": using pattern \"" + itemPtr->datePattern + "\", did parse \"" + itemPtr->dateString + "\", formatted result \"" + formatted + "\".");
3885 void DateFormatTest::TestISOEra() {
3887 const char* data[] = {
3889 "BC 4004-10-23T07:00:00Z", "BC 4004-10-23T07:00:00Z",
3890 "AD 4004-10-23T07:00:00Z", "AD 4004-10-23T07:00:00Z",
3891 "-4004-10-23T07:00:00Z" , "BC 4005-10-23T07:00:00Z",
3892 "4004-10-23T07:00:00Z" , "AD 4004-10-23T07:00:00Z",
3895 int32_t numData = 8;
3897 UErrorCode status = U_ZERO_ERROR;
3900 SimpleDateFormat *fmt1 = new SimpleDateFormat(UnicodeString("GGG yyyy-MM-dd'T'HH:mm:ss'Z"), status);
3901 failure(status, "new SimpleDateFormat", TRUE);
3902 if (status == U_MISSING_RESOURCE_ERROR) {
3908 for(int i=0; i < numData; i+=2) {
3909 // create input string
3910 UnicodeString in = data[i];
3912 // parse string to date
3913 UDate dt1 = fmt1->parse(in, status);
3914 failure(status, "fmt->parse", TRUE);
3916 // format date back to string
3918 out = fmt1->format(dt1, out);
3921 // check that roundtrip worked as expected
3922 UnicodeString expected = data[i+1];
3923 if (out != expected) {
3924 dataerrln((UnicodeString)"FAIL: " + in + " -> " + out + " expected -> " + expected);
3930 void DateFormatTest::TestFormalChineseDate() {
3932 UErrorCode status = U_ZERO_ERROR;
3933 UnicodeString pattern ("y\\u5e74M\\u6708d\\u65e5", -1, US_INV );
3934 pattern = pattern.unescape();
3935 UnicodeString override ("y=hanidec;M=hans;d=hans", -1, US_INV );
3938 SimpleDateFormat *sdf = new SimpleDateFormat(pattern,override,Locale::getChina(),status);
3939 if (failure(status, "new SimpleDateFormat with override", TRUE)) {
3943 UDate thedate = date(2009-1900, UCAL_JULY, 28);
3944 FieldPosition pos(FieldPosition::DONT_CARE);
3945 UnicodeString result;
3946 sdf->format(thedate,result,pos);
3948 UnicodeString expected = "\\u4e8c\\u3007\\u3007\\u4e5d\\u5e74\\u4e03\\u6708\\u4e8c\\u5341\\u516b\\u65e5";
3949 expected = expected.unescape();
3950 if (result != expected) {
3951 dataerrln((UnicodeString)"FAIL: -> " + result + " expected -> " + expected);
3954 UDate parsedate = sdf->parse(expected,status);
3955 if ( parsedate != thedate ) {
3956 UnicodeString pat1 ("yyyy-MM-dd'T'HH:mm:ss'Z'", -1, US_INV );
3957 SimpleDateFormat *usf = new SimpleDateFormat(pat1,Locale::getEnglish(),status);
3958 UnicodeString parsedres,expres;
3959 usf->format(parsedate,parsedres,pos);
3960 usf->format(thedate,expres,pos);
3961 dataerrln((UnicodeString)"FAIL: parsed -> " + parsedres + " expected -> " + expres);
3967 // Test case for #8675
3968 // Incorrect parse offset with stand alone GMT string on 2nd or later iteration.
3969 void DateFormatTest::TestStandAloneGMTParse() {
3970 UErrorCode status = U_ZERO_ERROR;
3971 SimpleDateFormat *sdf = new SimpleDateFormat("ZZZZ", Locale(""), status);
3973 if (U_SUCCESS(status)) {
3975 UnicodeString inText("GMT$$$");
3976 for (int32_t i = 0; i < 10; i++) {
3977 ParsePosition pos(0);
3978 sdf->parse(inText, pos);
3979 if (pos.getIndex() != 3) {
3980 errln((UnicodeString)"FAIL: Incorrect output parse position: actual=" + pos.getIndex() + " expected=3");
3986 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
3990 void DateFormatTest::TestParsePosition() {
3991 const char* TestData[][4] = {
3992 // {<pattern>, <lead>, <date string>, <trail>}
3993 {"yyyy-MM-dd HH:mm:ssZ", "", "2010-01-10 12:30:00+0500", ""},
3994 {"yyyy-MM-dd HH:mm:ss ZZZZ", "", "2010-01-10 12:30:00 GMT+05:00", ""},
3995 {"Z HH:mm:ss", "", "-0100 13:20:30", ""},
3996 {"y-M-d Z", "", "2011-8-25 -0400", " Foo"},
3997 {"y/M/d H:mm:ss z", "", "2011/7/1 12:34:00 PDT", ""},
3998 {"y/M/d H:mm:ss z", "+123", "2011/7/1 12:34:00 PDT", " PST"},
3999 {"vvvv a h:mm:ss", "", "Pacific Time AM 10:21:45", ""},
4000 {"HH:mm v M/d", "111", "14:15 PT 8/10", " 12345"},
4001 {"'time zone:' VVVV 'date:' yyyy-MM-dd", "xxxx", "time zone: Los Angeles Time date: 2010-02-25", "xxxx"},
4002 {"yG", "", "2012AD", ""},
4003 {"yG", "", "2012", "x"},
4007 for (int32_t i = 0; TestData[i][0]; i++) {
4008 UErrorCode status = U_ZERO_ERROR;
4009 SimpleDateFormat *sdf = new SimpleDateFormat(UnicodeString(TestData[i][0]), status);
4010 if (failure(status, "new SimpleDateFormat", TRUE)) return;
4012 int32_t startPos, resPos;
4015 UnicodeString input(TestData[i][1]);
4016 startPos = input.length();
4019 input += TestData[i][2];
4020 resPos = input.length();
4023 input += TestData[i][3];
4025 ParsePosition pos(startPos);
4026 //UDate d = sdf->parse(input, pos);
4027 (void)sdf->parse(input, pos);
4029 if (pos.getIndex() != resPos) {
4030 errln(UnicodeString("FAIL: Parsing [") + input + "] with pattern [" + TestData[i][0] + "] returns position - "
4031 + pos.getIndex() + ", expected - " + resPos);
4042 int32_t month; // 1-based
4043 int32_t isLeapMonth;
4045 } ChineseCalTestDate;
4047 #define NUM_TEST_DATES 3
4050 const char * locale;
4051 int32_t style; // <0 => custom
4052 UnicodeString dateString[NUM_TEST_DATES];
4055 void DateFormatTest::TestMonthPatterns()
4057 const ChineseCalTestDate dates[NUM_TEST_DATES] = {
4059 { 78, 29, 4, 0, 2 }, // (in chinese era 78) gregorian 2012-4-22
4060 { 78, 29, 4, 1, 2 }, // (in chinese era 78) gregorian 2012-5-22
4061 { 78, 29, 5, 0, 2 }, // (in chinese era 78) gregorian 2012-6-20
4064 const MonthPatternItem items[] = {
4065 // locale date style; expected formats for the 3 dates above
4066 { "root@calendar=chinese", DateFormat::kLong, { UnicodeString("2012(ren-chen) M04 2"), UnicodeString("2012(ren-chen) M04bis 2"), UnicodeString("2012(ren-chen) M05 2") } },
4067 { "root@calendar=chinese", DateFormat::kShort, { UnicodeString("2012-04-02"), UnicodeString("2012-04bis-02"), UnicodeString("2012-05-02") } },
4068 { "root@calendar=chinese", -1, { UnicodeString("29-4-2"), UnicodeString("29-4bis-2"), UnicodeString("29-5-2") } },
4069 { "root@calendar=chinese", -2, { UnicodeString("78x29-4-2"), UnicodeString("78x29-4bis-2"), UnicodeString("78x29-5-2") } },
4070 { "root@calendar=chinese", -3, { UnicodeString("ren-chen-4-2"), UnicodeString("ren-chen-4bis-2"), UnicodeString("ren-chen-5-2") } },
4071 { "root@calendar=chinese", -4, { UnicodeString("ren-chen M04 2"), UnicodeString("ren-chen M04bis 2"), UnicodeString("ren-chen M05 2") } },
4072 { "en@calendar=gregorian", -3, { UnicodeString("2012-4-22"), UnicodeString("2012-5-22"), UnicodeString("2012-6-20") } },
4073 { "en@calendar=chinese", DateFormat::kLong, { UnicodeString("Fourth Month 2, 2012(ren-chen)"), UnicodeString("Fourth Monthbis 2, 2012(ren-chen)"), UnicodeString("Fifth Month 2, 2012(ren-chen)") } },
4074 { "en@calendar=chinese", DateFormat::kShort, { UnicodeString("4/2/2012"), UnicodeString("4bis/2/2012"), UnicodeString("5/2/2012") } },
4075 { "zh@calendar=chinese", DateFormat::kLong, { CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u56DB\\u6708\\u521D\\u4E8C"),
4076 CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u95F0\\u56DB\\u6708\\u521D\\u4E8C"),
4077 CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u4E94\\u6708\\u521D\\u4E8C") } },
4078 { "zh@calendar=chinese", DateFormat::kShort, { CharsToUnicodeString("2012/4/2"),
4079 CharsToUnicodeString("2012/\\u95F04/2"),
4080 CharsToUnicodeString("2012/5/2") } },
4081 { "zh@calendar=chinese", -3, { CharsToUnicodeString("\\u58EC\\u8FB0-4-2"),
4082 CharsToUnicodeString("\\u58EC\\u8FB0-\\u95F04-2"),
4083 CharsToUnicodeString("\\u58EC\\u8FB0-5-2") } },
4084 { "zh@calendar=chinese", -4, { CharsToUnicodeString("\\u58EC\\u8FB0 \\u56DB\\u6708 2"),
4085 CharsToUnicodeString("\\u58EC\\u8FB0 \\u95F0\\u56DB\\u6708 2"),
4086 CharsToUnicodeString("\\u58EC\\u8FB0 \\u4E94\\u6708 2") } },
4087 { "zh_Hant@calendar=chinese", DateFormat::kLong, { CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u56DB\\u6708\\u521D\\u4E8C"),
4088 CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u958F\\u56DB\\u6708\\u521D\\u4E8C"),
4089 CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u4E94\\u6708\\u521D\\u4E8C") } },
4090 { "zh_Hant@calendar=chinese", DateFormat::kShort, { CharsToUnicodeString("2012/4/2"),
4091 CharsToUnicodeString("2012/\\u958F4/2"),
4092 CharsToUnicodeString("2012/5/2") } },
4093 { "fr@calendar=chinese", DateFormat::kLong, { CharsToUnicodeString("2 s\\u00ECyu\\u00E8 ren-chen"),
4094 CharsToUnicodeString("2 s\\u00ECyu\\u00E8bis ren-chen"),
4095 CharsToUnicodeString("2 w\\u01D4yu\\u00E8 ren-chen") } },
4096 { "fr@calendar=chinese", DateFormat::kShort, { UnicodeString("2/4/29"), UnicodeString("2/4bis/29"), UnicodeString("2/5/29") } },
4097 { "en@calendar=dangi", DateFormat::kLong, { UnicodeString("Third Monthbis 2, 2012(ren-chen)"), UnicodeString("Fourth Month 2, 2012(ren-chen)"), UnicodeString("Fifth Month 1, 2012(ren-chen)") } },
4098 { "en@calendar=dangi", DateFormat::kShort, { UnicodeString("3bis/2/2012"), UnicodeString("4/2/2012"), UnicodeString("5/1/2012") } },
4099 { "en@calendar=dangi", -2, { UnicodeString("78x29-3bis-2"), UnicodeString("78x29-4-2"), UnicodeString("78x29-5-1") } },
4100 { "ko@calendar=dangi", DateFormat::kLong, { CharsToUnicodeString("\\uC784\\uC9C4\\uB144 \\uC7243\\uC6D4 2\\uC77C"),
4101 CharsToUnicodeString("\\uC784\\uC9C4\\uB144 4\\uC6D4 2\\uC77C"),
4102 CharsToUnicodeString("\\uC784\\uC9C4\\uB144 5\\uC6D4 1\\uC77C") } },
4103 { "ko@calendar=dangi", DateFormat::kShort, { CharsToUnicodeString("29. \\uC7243. 2."),
4104 CharsToUnicodeString("29. 4. 2."),
4105 CharsToUnicodeString("29. 5. 1.") } },
4107 { NULL, 0, { UnicodeString(""), UnicodeString(""), UnicodeString("") } }
4110 //. style: -1 -2 -3 -4
4111 const UnicodeString customPatterns[] = { "y-Ml-d", "G'x'y-Ml-d", "U-M-d", "U MMM d" }; // like old root pattern, using 'l'
4113 UErrorCode status = U_ZERO_ERROR;
4114 Locale rootChineseCalLocale = Locale::createFromName("root@calendar=chinese");
4115 Calendar * rootChineseCalendar = Calendar::createInstance(rootChineseCalLocale, status);
4116 if (U_SUCCESS(status)) {
4117 const MonthPatternItem * itemPtr;
4118 for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
4119 Locale locale = Locale::createFromName(itemPtr->locale);
4120 DateFormat * dmft = (itemPtr->style >= 0)?
4121 DateFormat::createDateInstance((DateFormat::EStyle)itemPtr->style, locale):
4122 new SimpleDateFormat(customPatterns[-itemPtr->style - 1], locale, status);
4123 if ( dmft != NULL ) {
4124 if (U_SUCCESS(status)) {
4125 const ChineseCalTestDate * datePtr = dates;
4127 for (idate = 0; idate < NUM_TEST_DATES; idate++, datePtr++) {
4128 rootChineseCalendar->clear();
4129 rootChineseCalendar->set(UCAL_ERA, datePtr->era);
4130 rootChineseCalendar->set(datePtr->year, datePtr->month-1, datePtr->day);
4131 rootChineseCalendar->set(UCAL_IS_LEAP_MONTH, datePtr->isLeapMonth);
4132 UnicodeString result;
4133 FieldPosition fpos(FieldPosition::DONT_CARE);
4134 dmft->format(*rootChineseCalendar, result, fpos);
4135 if ( result.compare(itemPtr->dateString[idate]) != 0 ) {
4136 errln( UnicodeString("FAIL: Chinese calendar format for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
4137 ", expected \"" + itemPtr->dateString[idate] + "\", got \"" + result + "\"");
4139 // formatted OK, try parse
4140 ParsePosition ppos(0);
4141 // ensure we are really parsing the fields we should be
4142 rootChineseCalendar->set(UCAL_YEAR, 1);
4143 rootChineseCalendar->set(UCAL_MONTH, 0);
4144 rootChineseCalendar->set(UCAL_IS_LEAP_MONTH, 0);
4145 rootChineseCalendar->set(UCAL_DATE, 1);
4147 dmft->parse(result, *rootChineseCalendar, ppos);
4148 int32_t year = rootChineseCalendar->get(UCAL_YEAR, status);
4149 int32_t month = rootChineseCalendar->get(UCAL_MONTH, status) + 1;
4150 int32_t isLeapMonth = rootChineseCalendar->get(UCAL_IS_LEAP_MONTH, status);
4151 int32_t day = rootChineseCalendar->get(UCAL_DATE, status);
4152 if ( ppos.getIndex() < result.length() || year != datePtr->year || month != datePtr->month || isLeapMonth != datePtr->isLeapMonth || day != datePtr->day ) {
4153 errln( UnicodeString("FAIL: Chinese calendar parse for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
4154 ", string \"" + result + "\", expected " + datePtr->year +"-"+datePtr->month+"("+datePtr->isLeapMonth+")-"+datePtr->day + ", got pos " +
4155 ppos.getIndex() + " " + year +"-"+month+"("+isLeapMonth+")-"+day);
4160 dataerrln("Error creating SimpleDateFormat for Chinese calendar- %s", u_errorName(status));
4164 dataerrln("FAIL: Unable to create DateFormat for Chinese calendar- %s", u_errorName(status));
4167 delete rootChineseCalendar;
4169 errln(UnicodeString("FAIL: Unable to create Calendar for root@calendar=chinese"));
4174 const char * locale;
4175 UnicodeString pattern;
4176 UDisplayContext capitalizationContext;
4177 UnicodeString expectedFormat;
4180 void DateFormatTest::TestContext()
4182 const UDate july022008 = 1215000001979.0;
4183 const TestContextItem items[] = {
4184 //locale pattern capitalizationContext expected formatted date
4185 { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_NONE, UnicodeString("juillet 2008") },
4186 #if !UCONFIG_NO_BREAK_ITERATION
4187 { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UnicodeString("juillet 2008") },
4188 { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UnicodeString("Juillet 2008") },
4189 { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UnicodeString("juillet 2008") },
4190 { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_STANDALONE, UnicodeString("Juillet 2008") },
4192 { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_NONE, CharsToUnicodeString("\\u010Dervenec 2008") },
4193 #if !UCONFIG_NO_BREAK_ITERATION
4194 { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, CharsToUnicodeString("\\u010Dervenec 2008") },
4195 { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, CharsToUnicodeString("\\u010Cervenec 2008") },
4196 { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, CharsToUnicodeString("\\u010Cervenec 2008") },
4197 { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_STANDALONE, CharsToUnicodeString("\\u010Dervenec 2008") },
4200 { NULL, UnicodeString(""), (UDisplayContext)0, UnicodeString("") }
4202 UErrorCode status = U_ZERO_ERROR;
4203 Calendar* cal = Calendar::createInstance(status);
4204 if (U_FAILURE(status)) {
4205 dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale."));
4207 cal->setTime(july022008, status);
4208 const TestContextItem * itemPtr;
4209 for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
4210 Locale locale = Locale::createFromName(itemPtr->locale);
4211 status = U_ZERO_ERROR;
4212 SimpleDateFormat * sdmft = new SimpleDateFormat(itemPtr->pattern, locale, status);
4213 if (U_FAILURE(status)) {
4214 dataerrln(UnicodeString("FAIL: Unable to create SimpleDateFormat for specified pattern with locale ") + UnicodeString(itemPtr->locale));
4216 sdmft->setContext(itemPtr->capitalizationContext, status);
4217 UnicodeString result;
4218 FieldPosition pos(FieldPosition::DONT_CARE);
4219 sdmft->format(*cal, result, pos);
4220 if (result.compare(itemPtr->expectedFormat) != 0) {
4221 errln(UnicodeString("FAIL: format for locale ") + UnicodeString(itemPtr->locale) +
4222 ", status " + (int)status +
4223 ", capitalizationContext " + (int)itemPtr->capitalizationContext +
4224 ", expected " + itemPtr->expectedFormat + ", got " + result);
4237 // test item for a particular locale + calendar and date format
4245 UnicodeString formattedDate;
4246 } CalAndFmtTestItem;
4248 // test item giving locale + calendar, date format, and CalAndFmtTestItems
4250 const char * locale; // with calendar
4251 DateFormat::EStyle style;
4252 UnicodeString pattern; // ignored unless style == DateFormat::kNone
4253 const CalAndFmtTestItem *caftItems;
4256 void DateFormatTest::TestNonGregoFmtParse()
4258 // test items for he@calendar=hebrew, long date format
4259 const CalAndFmtTestItem cafti_he_hebrew_long[] = {
4260 { 0, 4999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05D3\\u05F3\\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") },
4261 { 0, 5100, 0, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05E7\\u05F3") },
4262 { 0, 5774, 5, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05D0\\u05D3\\u05E8 \\u05D0\\u05F3 \\u05EA\\u05E9\\u05E2\\u05F4\\u05D3") },
4263 { 0, 5999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") },
4264 { 0, 6100, 0, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05D5\\u05F3\\u05E7\\u05F3") },
4265 { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator
4267 const CalAndFmtTestItem cafti_zh_chinese_custU[] = {
4268 { 78, 31, 0, 1, 12, 0, CharsToUnicodeString("2014\\u7532\\u5348\\u5E74\\u6B63\\u67081") },
4269 { 77, 31, 0, 1, 12, 0, CharsToUnicodeString("1954\\u7532\\u5348\\u5E74\\u6B63\\u67081") },
4270 { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator
4272 const CalAndFmtTestItem cafti_zh_chinese_custNoU[] = {
4273 { 78, 31, 0, 1, 12, 0, CharsToUnicodeString("2014\\u5E74\\u6B63\\u67081") },
4274 { 77, 31, 0, 1, 12, 0, CharsToUnicodeString("1954\\u5E74\\u6B63\\u67081") },
4275 { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator
4277 const CalAndFmtTestItem cafti_ja_japanese_custGy[] = {
4278 {235, 26, 2, 5, 12, 0, CharsToUnicodeString("2014(\\u5E73\\u621026)\\u5E743\\u67085\\u65E5") },
4279 {234, 60, 2, 5, 12, 0, CharsToUnicodeString("1985(\\u662D\\u548C60)\\u5E743\\u67085\\u65E5") },
4280 { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator
4282 const CalAndFmtTestItem cafti_ja_japanese_custNoGy[] = {
4283 {235, 26, 2, 5, 12, 0, CharsToUnicodeString("2014\\u5E743\\u67085\\u65E5") },
4284 {234, 60, 2, 5, 12, 0, CharsToUnicodeString("1985\\u5E743\\u67085\\u65E5") },
4285 { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator
4287 const CalAndFmtTestItem cafti_en_islamic_cust[] = {
4288 { 0, 1384, 0, 1, 12, 0, UnicodeString("1 Muh. 1384 AH, 1964") },
4289 { 0, 1436, 0, 1, 12, 0, UnicodeString("1 Muh. 1436 AH, 2014") },
4290 { 0, 1487, 0, 1, 12, 0, UnicodeString("1 Muh. 1487 AH, 2064") },
4291 { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator
4293 // overal test items
4294 const TestNonGregoItem items[] = {
4295 { "he@calendar=hebrew", DateFormat::kLong, UnicodeString(""), cafti_he_hebrew_long },
4296 { "zh@calendar=chinese", DateFormat::kNone, CharsToUnicodeString("rU\\u5E74MMMd"), cafti_zh_chinese_custU },
4297 { "zh@calendar=chinese", DateFormat::kNone, CharsToUnicodeString("r\\u5E74MMMd"), cafti_zh_chinese_custNoU },
4298 { "ja@calendar=japanese", DateFormat::kNone, CharsToUnicodeString("r(Gy)\\u5E74M\\u6708d\\u65E5"), cafti_ja_japanese_custGy },
4299 { "ja@calendar=japanese", DateFormat::kNone, CharsToUnicodeString("r\\u5E74M\\u6708d\\u65E5"), cafti_ja_japanese_custNoGy },
4300 { "en@calendar=islamic", DateFormat::kNone, UnicodeString("d MMM y G, r"), cafti_en_islamic_cust },
4301 { NULL, DateFormat::kNone, UnicodeString(""), NULL } // terminator
4303 const TestNonGregoItem * itemPtr;
4304 for (itemPtr = items; itemPtr->locale != NULL; itemPtr++) {
4305 Locale locale = Locale::createFromName(itemPtr->locale);
4306 DateFormat * dfmt = NULL;
4307 UErrorCode status = U_ZERO_ERROR;
4308 if (itemPtr->style != DateFormat::kNone) {
4309 dfmt = DateFormat::createDateInstance(itemPtr->style, locale);
4311 dfmt = new SimpleDateFormat(itemPtr->pattern, locale, status);
4313 if (U_FAILURE(status)) {
4314 dataerrln("new SimpleDateFormat fails for locale %s", itemPtr->locale);
4315 } else if (dfmt == NULL) {
4316 dataerrln("DateFormat::createDateInstance fails for locale %s", itemPtr->locale);
4318 Calendar * cal = (dfmt->getCalendar())->clone();
4320 dataerrln("(DateFormat::getCalendar)->clone() fails for locale %s", itemPtr->locale);
4322 const CalAndFmtTestItem * caftItemPtr;
4323 for (caftItemPtr = itemPtr->caftItems; caftItemPtr->year != 0; caftItemPtr++) {
4325 cal->set(UCAL_ERA, caftItemPtr->era);
4326 cal->set(UCAL_YEAR, caftItemPtr->year);
4327 cal->set(UCAL_MONTH, caftItemPtr->month);
4328 cal->set(UCAL_DATE, caftItemPtr->day);
4329 cal->set(UCAL_HOUR_OF_DAY, caftItemPtr->hour);
4330 cal->set(UCAL_MINUTE, caftItemPtr->minute);
4331 UnicodeString result;
4332 FieldPosition fpos(FieldPosition::DONT_CARE);
4333 dfmt->format(*cal, result, fpos);
4334 if ( result.compare(caftItemPtr->formattedDate) != 0 ) {
4335 errln( UnicodeString("FAIL: date format for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
4336 ", expected \"" + caftItemPtr->formattedDate + "\", got \"" + result + "\"");
4338 // formatted OK, try parse
4339 ParsePosition ppos(0);
4340 dfmt->parse(result, *cal, ppos);
4341 status = U_ZERO_ERROR;
4342 int32_t era = cal->get(UCAL_ERA, status);
4343 int32_t year = cal->get(UCAL_YEAR, status);
4344 int32_t month = cal->get(UCAL_MONTH, status);
4345 int32_t day = cal->get(UCAL_DATE, status);
4346 if ( U_FAILURE(status) || ppos.getIndex() < result.length() || era != caftItemPtr->era ||
4347 year != caftItemPtr->year || month != caftItemPtr->month || day != caftItemPtr->day ) {
4348 errln( UnicodeString("FAIL: date parse for locale ") + UnicodeString(itemPtr->locale) +
4349 ", style " + itemPtr->style + ", string \"" + result + "\", expected " +
4350 caftItemPtr->era +":"+caftItemPtr->year +"-"+caftItemPtr->month+"-"+caftItemPtr->day + ", got pos " +
4351 ppos.getIndex() + " " + year +"-"+month+"-"+day + " status " + UnicodeString(u_errorName(status)) );
4363 const char* localeID;
4364 DateFormat::EStyle style;
4365 UnicodeString expectPattern;
4366 UnicodeString expectFormat;
4367 } TestFmtWithNumSysItem;
4368 enum { kBBufMax = 128 };
4369 void DateFormatTest::TestFormatsWithNumberSystems()
4371 LocalPointer<TimeZone> zone(TimeZone::createTimeZone(UnicodeString("UTC")));
4372 const UDate date = 1451556000000.0; // for UTC: grego 31-Dec-2015 10 AM, hebrew 19 tevet 5776, chinese yi-wei 11mo 21day
4373 const TestFmtWithNumSysItem items[] = {
4374 { "haw@calendar=gregorian", DateFormat::kShort, UnicodeString("d/M/yy"), UnicodeString("31/xii/15") },
4375 { "he@calendar=hebrew", DateFormat::kLong, CharsToUnicodeString("d \\u05D1MMMM y"), CharsToUnicodeString("\\u05D9\\u05F4\\u05D8 \\u05D1\\u05D8\\u05D1\\u05EA \\u05EA\\u05E9\\u05E2\\u05F4\\u05D5") },
4376 { "zh@calendar=chinese", DateFormat::kLong, CharsToUnicodeString("rU\\u5E74MMMd"), CharsToUnicodeString("2015\\u4E59\\u672A\\u5E74\\u5341\\u4E00\\u6708\\u5EFF\\u4E00") },
4377 { "zh_Hant@calendar=chinese", DateFormat::kLong, CharsToUnicodeString("rU\\u5E74MMMd"), CharsToUnicodeString("2015\\u4E59\\u672A\\u5E74\\u51AC\\u6708\\u5EFF\\u4E00") },
4378 { "ja@calendar=chinese", DateFormat::kLong, CharsToUnicodeString("U\\u5E74MMMd\\u65E5"), CharsToUnicodeString("\\u4E59\\u672A\\u5E74\\u5341\\u4E00\\u6708\\u4E8C\\u4E00\\u65E5") },
4379 { NULL, DateFormat::kNone, UnicodeString(""), UnicodeString("") },
4381 const TestFmtWithNumSysItem * itemPtr;
4382 for (itemPtr = items; itemPtr->localeID != NULL; itemPtr++) {
4383 char bExpected[kBBufMax];
4384 char bResult[kBBufMax];
4385 UErrorCode status = U_ZERO_ERROR;
4386 Locale locale = Locale::createFromName(itemPtr->localeID);
4387 LocalPointer<Calendar> cal(Calendar::createInstance(zone.orphan(), locale, status));
4388 if (U_FAILURE(status)) {
4389 dataerrln("Calendar::createInstance fails for locale %s, status %s", itemPtr->localeID, u_errorName(status));
4392 cal->setTime(date, status);
4393 if (U_FAILURE(status)) {
4394 dataerrln("Calendar::setTime fails for locale %s, date %.1f, status %s", itemPtr->localeID, date, u_errorName(status));
4397 LocalPointer<SimpleDateFormat> sdfmt(static_cast<SimpleDateFormat *>(DateFormat::createDateInstance(itemPtr->style, locale)));
4398 if (sdfmt.isNull()) {
4399 dataerrln("DateFormat::createDateInstance fails for locale %s", itemPtr->localeID);
4402 UnicodeString getFormat;
4403 sdfmt->format(*(cal.getAlias()), getFormat, NULL, status);
4404 if (U_FAILURE(status)) {
4405 errln("DateFormat::format fails for locale %s, status %s", itemPtr->localeID, u_errorName(status));
4408 if (getFormat.compare(itemPtr->expectFormat) != 0) {
4409 itemPtr->expectFormat.extract(0, itemPtr->expectFormat.length(), bExpected, kBBufMax);
4410 getFormat.extract(0, getFormat.length(), bResult, kBBufMax);
4411 errln("DateFormat::format for locale %s, expected \"%s\", got \"%s\"", itemPtr->localeID, bExpected, bResult);
4413 UnicodeString getPattern;
4414 sdfmt->toPattern(getPattern);
4415 if (getPattern.compare(itemPtr->expectPattern) != 0) {
4416 itemPtr->expectPattern.extract(0, itemPtr->expectPattern.length(), bExpected, kBBufMax);
4417 getPattern.extract(0, getPattern.length(), bResult, kBBufMax);
4418 errln("DateFormat::toPattern() for locale %s, expected \"%s\", got \"%s\"", itemPtr->localeID, bExpected, bResult);
4423 static const UDate TEST_DATE = 1326585600000.; // 2012-jan-15
4425 void DateFormatTest::TestDotAndAtLeniency() {
4426 // Test for date/time parsing regression with CLDR 22.1/ICU 50 pattern strings.
4427 // For details see http://bugs.icu-project.org/trac/ticket/9789
4428 static const char *locales[] = { "en", "fr" };
4429 for (int32_t i = 0; i < UPRV_LENGTHOF(locales); ++i) {
4430 Locale locale(locales[i]);
4432 for (DateFormat::EStyle dateStyle = DateFormat::FULL; dateStyle <= DateFormat::SHORT;
4433 dateStyle = static_cast<DateFormat::EStyle>(dateStyle + 1)) {
4434 LocalPointer<DateFormat> dateFormat(DateFormat::createDateInstance(dateStyle, locale));
4436 for (DateFormat::EStyle timeStyle = DateFormat::FULL; timeStyle <= DateFormat::SHORT;
4437 timeStyle = static_cast<DateFormat::EStyle>(timeStyle + 1)) {
4438 LocalPointer<DateFormat> format(DateFormat::createDateTimeInstance(dateStyle, timeStyle, locale));
4439 LocalPointer<DateFormat> timeFormat(DateFormat::createTimeInstance(timeStyle, locale));
4440 UnicodeString formattedString;
4441 if (format.isNull()) {
4442 dataerrln("Unable to create DateFormat");
4445 format->format(TEST_DATE, formattedString);
4447 if (!showParse(*format, formattedString)) {
4448 errln(UnicodeString(" with date-time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle);
4451 UnicodeString ds, ts;
4452 formattedString = dateFormat->format(TEST_DATE, ds) + " " + timeFormat->format(TEST_DATE, ts);
4453 if (!showParse(*format, formattedString)) {
4454 errln(UnicodeString(" with date sp sp time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle);
4456 if (formattedString.indexOf("n ") >= 0) { // will add "." after the end of text ending in 'n', like Jan.
4457 UnicodeString plusDot(formattedString);
4458 plusDot.findAndReplace("n ", "n. ").append(".");
4459 if (!showParse(*format, plusDot)) {
4460 errln(UnicodeString(" with date plus-dot time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle);
4463 if (formattedString.indexOf(". ") >= 0) { // will subtract "." at the end of strings.
4464 UnicodeString minusDot(formattedString);
4465 minusDot.findAndReplace(". ", " ");
4466 if (!showParse(*format, minusDot)) {
4467 errln(UnicodeString(" with date minus-dot time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle);
4475 UBool DateFormatTest::showParse(DateFormat &format, const UnicodeString &formattedString) {
4476 ParsePosition parsePosition;
4477 UDate parsed = format.parse(formattedString, parsePosition);
4478 UBool ok = TEST_DATE == parsed && parsePosition.getIndex() == formattedString.length();
4479 UnicodeString pattern;
4480 static_cast<SimpleDateFormat &>(format).toPattern(pattern);
4482 logln(pattern + " parsed: " + formattedString);
4484 errln(pattern + " fails to parse: " + formattedString);
4491 const char * locale;
4493 UnicodeString parseString;
4494 UnicodeString pattern;
4495 UnicodeString expectedResult; // empty string indicates expected error
4496 } TestDateFormatLeniencyItem;
4498 void DateFormatTest::TestDateFormatLeniency() {
4499 // For details see http://bugs.icu-project.org/trac/ticket/10261
4501 const UDate july022008 = 1215000001979.0;
4502 const TestDateFormatLeniencyItem items[] = {
4503 //locale leniency parse String pattern expected result
4504 { "en", true, UnicodeString("2008-07 02"), UnicodeString("yyyy-LLLL dd"), UnicodeString("2008-July 02") },
4505 { "en", false, UnicodeString("2008-07 02"), UnicodeString("yyyy-LLLL dd"), UnicodeString("") },
4506 { "en", true, UnicodeString("2008-Jan 02"), UnicodeString("yyyy-LLL. dd"), UnicodeString("2008-Jan. 02") },
4507 { "en", false, UnicodeString("2008-Jan 02"), UnicodeString("yyyy-LLL. dd"), UnicodeString("") },
4508 { "en", true, UnicodeString("2008-Jan--02"), UnicodeString("yyyy-MMM' -- 'dd"), UnicodeString("2008-Jan -- 02") },
4509 { "en", false, UnicodeString("2008-Jan--02"), UnicodeString("yyyy-MMM' -- 'dd"), UnicodeString("") },
4511 { NULL, true, UnicodeString(""), UnicodeString(""), UnicodeString("") }
4513 UErrorCode status = U_ZERO_ERROR;
4514 LocalPointer<Calendar> cal(Calendar::createInstance(status));
4515 if (U_FAILURE(status)) {
4516 dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale."));
4519 cal->setTime(july022008, status);
4520 const TestDateFormatLeniencyItem * itemPtr;
4521 LocalPointer<SimpleDateFormat> sdmft;
4522 for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
4524 Locale locale = Locale::createFromName(itemPtr->locale);
4525 status = U_ZERO_ERROR;
4526 ParsePosition pos(0);
4527 sdmft.adoptInsteadAndCheckErrorCode(new SimpleDateFormat(itemPtr->pattern, locale, status), status);
4528 if (U_FAILURE(status)) {
4529 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
4532 sdmft->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->leniency, status).
4533 setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->leniency, status).
4534 setBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, itemPtr->leniency, status);
4535 UDate d = sdmft->parse(itemPtr->parseString, pos);
4537 if(itemPtr->expectedResult.length() == 0) {
4538 if(pos.getErrorIndex() != -1) {
4541 errln("error: unexpected parse success - " + itemPtr->parseString +
4542 " - pattern " + itemPtr->pattern +
4543 " - error index " + pos.getErrorIndex() +
4544 " - leniency " + itemPtr->leniency);
4548 if(pos.getErrorIndex() != -1) {
4549 errln("error: parse error for string - " + itemPtr->parseString +
4550 " - pattern " + itemPtr->pattern +
4551 " - idx " + pos.getIndex() +
4552 " - error index "+pos.getErrorIndex() +
4553 " - leniency " + itemPtr->leniency);
4557 UnicodeString formatResult("");
4558 sdmft->format(d, formatResult);
4559 if(formatResult.compare(itemPtr->expectedResult) != 0) {
4560 errln("error: unexpected format result. pattern["+itemPtr->pattern+"] expected[" + itemPtr->expectedResult + "] but result was[" + formatResult + "]");
4563 logln("formatted results match! - " + formatResult);
4572 UnicodeString parseString;
4573 UnicodeString pattern;
4574 UnicodeString expectedResult; // empty string indicates expected error
4575 } TestMultiPatternMatchItem;
4577 void DateFormatTest::TestParseMultiPatternMatch() {
4578 // For details see http://bugs.icu-project.org/trac/ticket/10336
4579 const TestMultiPatternMatchItem items[] = {
4580 // leniency parse String pattern expected result
4581 {true, UnicodeString("2013-Sep 13"), UnicodeString("yyyy-MMM dd"), UnicodeString("2013-Sep 13")},
4582 {true, UnicodeString("2013-September 14"), UnicodeString("yyyy-MMM dd"), UnicodeString("2013-Sep 14")},
4583 {false, UnicodeString("2013-September 15"), UnicodeString("yyyy-MMM dd"), UnicodeString("")},
4584 {false, UnicodeString("2013-September 16"), UnicodeString("yyyy-MMMM dd"), UnicodeString("2013-September 16")},
4585 {true, UnicodeString("2013-Sep 17"), UnicodeString("yyyy-LLL dd"), UnicodeString("2013-Sep 17")},
4586 {true, UnicodeString("2013-September 18"), UnicodeString("yyyy-LLL dd"), UnicodeString("2013-Sep 18")},
4587 {false, UnicodeString("2013-September 19"), UnicodeString("yyyy-LLL dd"), UnicodeString("")},
4588 {false, UnicodeString("2013-September 20"), UnicodeString("yyyy-LLLL dd"), UnicodeString("2013-September 20")},
4589 {true, UnicodeString("2013 Sat Sep 21"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("2013 Sat Sep 21")},
4590 {true, UnicodeString("2013 Sunday Sep 22"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("2013 Sun Sep 22")},
4591 {false, UnicodeString("2013 Monday Sep 23"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("")},
4592 {false, UnicodeString("2013 Tuesday Sep 24"), UnicodeString("yyyy EEEE MMM dd"), UnicodeString("2013 Tuesday Sep 24")},
4593 {true, UnicodeString("2013 Wed Sep 25"), UnicodeString("yyyy eee MMM dd"), UnicodeString("2013 Wed Sep 25")},
4594 {true, UnicodeString("2013 Thu Sep 26"), UnicodeString("yyyy eee MMM dd"), UnicodeString("2013 Thu Sep 26")},
4595 {false, UnicodeString("2013 Friday Sep 27"), UnicodeString("yyyy eee MMM dd"), UnicodeString("")},
4596 {false, UnicodeString("2013 Saturday Sep 28"), UnicodeString("yyyy eeee MMM dd"), UnicodeString("2013 Saturday Sep 28")},
4597 {true, UnicodeString("2013 Sun Sep 29"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("2013 Sun Sep 29")},
4598 {true, UnicodeString("2013 Monday Sep 30"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("2013 Mon Sep 30")},
4599 {false, UnicodeString("2013 Sunday Oct 13"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("")},
4600 {false, UnicodeString("2013 Monday Oct 14"), UnicodeString("yyyy cccc MMM dd"), UnicodeString("2013 Monday Oct 14")},
4601 {true, UnicodeString("2013 Oct 15 Q4"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 15 Q4")},
4602 {true, UnicodeString("2013 Oct 16 4th quarter"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 16 Q4")},
4603 {false, UnicodeString("2013 Oct 17 4th quarter"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("")},
4604 {false, UnicodeString("2013 Oct 18 Q4"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 18 Q4")},
4605 {true, UnicodeString("2013 Oct 19 Q4"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 19 4th quarter")},
4606 {true, UnicodeString("2013 Oct 20 4th quarter"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 20 4th quarter")},
4607 {false, UnicodeString("2013 Oct 21 Q4"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("")},
4608 {false, UnicodeString("2013 Oct 22 4th quarter"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 22 4th quarter")},
4609 {false, UnicodeString("--end--"), UnicodeString(""), UnicodeString("")},
4612 UErrorCode status = U_ZERO_ERROR;
4613 LocalPointer<Calendar> cal(Calendar::createInstance(status));
4614 if (U_FAILURE(status)) {
4615 dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale."));
4618 const TestMultiPatternMatchItem * itemPtr;
4619 DateFormat* sdmft = DateFormat::createDateInstance();
4620 if (sdmft == NULL) {
4621 dataerrln(UnicodeString("FAIL: Unable to create DateFormat"));
4624 for (itemPtr = items; itemPtr->parseString != "--end--"; itemPtr++ ) {
4625 status = U_ZERO_ERROR;
4626 ParsePosition pos(0);
4627 ((SimpleDateFormat*) sdmft)->applyPattern(itemPtr->pattern);
4628 if (U_FAILURE(status)) {
4629 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
4632 sdmft->setBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, itemPtr->leniency, status);
4633 UDate d = sdmft->parse(itemPtr->parseString, pos);
4635 if(itemPtr->expectedResult.length() == 0) {
4636 if(pos.getErrorIndex() != -1) {
4639 errln("error: unexpected parse success - " + itemPtr->parseString +
4640 " - error index " + pos.getErrorIndex() +
4641 " - leniency " + itemPtr->leniency);
4645 if(pos.getErrorIndex() != -1) {
4646 errln("error: parse error for string - " +itemPtr->parseString + " -- idx["+pos.getIndex()+"] errIdx["+pos.getErrorIndex()+"]");
4650 UnicodeString formatResult("");
4651 sdmft->format(d, formatResult);
4652 if(formatResult.compare(itemPtr->expectedResult) != 0) {
4653 errln("error: unexpected format result. expected[" + itemPtr->expectedResult + "] but result was[" + formatResult + "]");
4655 logln("formatted results match! - " + formatResult);
4661 void DateFormatTest::TestParseLeniencyAPIs() {
4662 UErrorCode status = U_ZERO_ERROR;
4663 LocalPointer<DateFormat> dateFormat(DateFormat::createDateInstance());
4664 DateFormat *fmt = dateFormat.getAlias();
4666 dataerrln("Failed calling dateFormat.getAlias()");
4670 assertTrue("isLenient default", fmt->isLenient());
4671 assertTrue("isCalendarLenient default", fmt->isCalendarLenient());
4672 assertTrue("ALLOW_WHITESPACE default", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status));
4673 assertTrue("ALLOW_NUMERIC default", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status));
4674 assertTrue("PARTIAL_MATCH default", fmt->getBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, status));
4675 assertTrue("MULTIPLE_PATTERNS default", fmt->getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status));
4677 // Set calendar to strict
4678 fmt->setCalendarLenient(FALSE);
4680 assertFalse("isLeninent after setCalendarLenient(FALSE)", fmt->isLenient());
4681 assertFalse("isCalendarLenient after setCalendarLenient(FALSE)", fmt->isCalendarLenient());
4682 assertTrue("ALLOW_WHITESPACE after setCalendarLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status));
4683 assertTrue("ALLOW_NUMERIC after setCalendarLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status));
4686 fmt->setLenient(FALSE);
4688 assertFalse("isLeninent after setLenient(FALSE)", fmt->isLenient());
4689 assertFalse("isCalendarLenient after setLenient(FALSE)", fmt->isCalendarLenient());
4690 assertFalse("ALLOW_WHITESPACE after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status));
4691 assertFalse("ALLOW_NUMERIC after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status));
4692 // These two boolean attributes are NOT affected according to the API specification
4693 assertTrue("PARTIAL_MATCH after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, status));
4694 assertTrue("MULTIPLE_PATTERNS after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status));
4696 // Allow white space leniency
4697 fmt->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, TRUE, status);
4699 assertFalse("isLeninent after ALLOW_WHITESPACE/TRUE", fmt->isLenient());
4700 assertFalse("isCalendarLenient after ALLOW_WHITESPACE/TRUE", fmt->isCalendarLenient());
4701 assertTrue("ALLOW_WHITESPACE after ALLOW_WHITESPACE/TRUE", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status));
4702 assertFalse("ALLOW_NUMERIC after ALLOW_WHITESPACE/TRUE", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status));
4705 fmt->setLenient(TRUE);
4707 assertTrue("isLenient after setLenient(TRUE)", fmt->isLenient());
4708 assertTrue("isCalendarLenient after setLenient(TRUE)", fmt->isCalendarLenient());
4709 assertTrue("ALLOW_WHITESPACE after setLenient(TRUE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status));
4710 assertTrue("ALLOW_NUMERIC after setLenient(TRUE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status));
4713 void DateFormatTest::TestNumberFormatOverride() {
4714 UErrorCode status = U_ZERO_ERROR;
4715 UnicodeString fields = (UnicodeString) "M";
4717 LocalPointer<SimpleDateFormat> fmt;
4718 fmt.adoptInsteadAndCheckErrorCode(new SimpleDateFormat((UnicodeString)"MM d", status), status);
4719 if (!assertSuccess("SimpleDateFormat with pattern MM d", status)) {
4724 for(int i=0; i<3; i++){
4725 NumberFormat* check_nf = NumberFormat::createInstance(Locale("en_US"), status);
4726 assertSuccess("NumberFormat en_US", status);
4727 fmt->adoptNumberFormat(fields, check_nf, status);
4728 assertSuccess("adoptNumberFormat check_nf", status);
4730 const NumberFormat* get_nf = fmt->getNumberFormatForField((UChar)0x004D /*'M'*/);
4731 if (get_nf != check_nf) errln("FAIL: getter and setter do not work");
4733 NumberFormat* check_nf = NumberFormat::createInstance(Locale("en_US"), status);
4734 assertSuccess("NumberFormat en_US", status);
4735 fmt->adoptNumberFormat(check_nf); // make sure using the same NF will not crash
4737 const char * DATA [][2] = {
4738 { "", "\\u521D\\u516D \\u5341\\u4E94"},
4739 { "M", "\\u521D\\u516D 15"},
4740 { "Mo", "\\u521D\\u516D 15"},
4741 { "Md", "\\u521D\\u516D \\u5341\\u4E94"},
4742 { "MdMMd", "\\u521D\\u516D \\u5341\\u4E94"},
4743 { "mixed", "\\u521D\\u516D \\u5341\\u4E94"}
4746 UDate test_date = date(97, 6 - 1, 15);
4748 for(int i=0; i < UPRV_LENGTHOF(DATA); i++){
4749 fields = DATA[i][0];
4751 LocalPointer<SimpleDateFormat> fmt;
4752 fmt.adoptInsteadAndCheckErrorCode(new SimpleDateFormat((UnicodeString)"MM d", status), status);
4753 assertSuccess("SimpleDateFormat with pattern MM d", status);
4754 NumberFormat* overrideNF = NumberFormat::createInstance(Locale::createFromName("zh@numbers=hanidays"),status);
4755 assertSuccess("NumberFormat zh@numbers=hanidays", status);
4757 if (fields == (UnicodeString) "") { // use the one w/o fields
4758 fmt->adoptNumberFormat(overrideNF);
4759 } else if (fields == (UnicodeString) "mixed") { // set 1 field at first but then full override, both(M & d) should be override
4760 NumberFormat* singleOverrideNF = NumberFormat::createInstance(Locale::createFromName("en@numbers=hebr"),status);
4761 assertSuccess("NumberFormat en@numbers=hebr", status);
4763 fields = (UnicodeString) "M";
4764 fmt->adoptNumberFormat(fields, singleOverrideNF, status);
4765 assertSuccess("adoptNumberFormat singleOverrideNF", status);
4767 fmt->adoptNumberFormat(overrideNF);
4768 } else if (fields == (UnicodeString) "Mo"){ // o is invlid field
4769 fmt->adoptNumberFormat(fields, overrideNF, status);
4770 if(status == U_INVALID_FORMAT_ERROR) {
4771 status = U_ZERO_ERROR;
4775 fmt->adoptNumberFormat(fields, overrideNF, status);
4776 assertSuccess("adoptNumberFormat overrideNF", status);
4779 UnicodeString result;
4780 FieldPosition pos(FieldPosition::DONT_CARE);
4781 fmt->format(test_date,result, pos);
4783 UnicodeString expected = ((UnicodeString)DATA[i][1]).unescape();;
4785 if (result != expected)
4786 errln("FAIL: Expected " + expected + " get: " + result);
4790 void DateFormatTest::TestCreateInstanceForSkeleton() {
4791 UErrorCode status = U_ZERO_ERROR;
4792 LocalPointer<DateFormat> fmt(DateFormat::createInstanceForSkeleton(
4793 "yMMMMd", "en", status));
4794 if (!assertSuccess("Create with pattern yMMMMd", status)) {
4797 UnicodeString result;
4798 FieldPosition pos(FieldPosition::DONT_CARE);
4799 fmt->format(date(98, 5-1, 25), result, pos);
4800 assertEquals("format yMMMMd", "May 25, 1998", result);
4801 fmt.adoptInstead(DateFormat::createInstanceForSkeleton(
4802 "yMd", "en", status));
4803 if (!assertSuccess("Create with pattern yMd", status)) {
4807 fmt->format(date(98, 5-1, 25), result, pos);
4808 assertEquals("format yMd", "5/25/1998", result);
4811 void DateFormatTest::TestCreateInstanceForSkeletonDefault() {
4812 UErrorCode status = U_ZERO_ERROR;
4814 Locale::setDefault(Locale::getUS(), status);
4815 LocalPointer<DateFormat> fmt(DateFormat::createInstanceForSkeleton(
4817 Locale::setDefault(savedLocale, status);
4818 if (!assertSuccess("Create with pattern yMMMd", status)) {
4821 UnicodeString result;
4822 FieldPosition pos(FieldPosition::DONT_CARE);
4823 fmt->format(date(98, 5-1, 25), result, pos);
4824 assertEquals("format yMMMd", "May 25, 1998", result);
4827 void DateFormatTest::TestCreateInstanceForSkeletonWithCalendar() {
4828 UErrorCode status = U_ZERO_ERROR;
4829 LocalPointer<DateFormat> fmt(
4830 DateFormat::createInstanceForSkeleton(
4831 Calendar::createInstance(
4832 TimeZone::createTimeZone("GMT-3:00"),
4834 "yMdHm", "en", status));
4835 if (!assertSuccess("Create with pattern yMMMMd", status)) {
4838 UnicodeString result;
4839 FieldPosition pos(FieldPosition::DONT_CARE);
4841 LocalPointer<Calendar> cal(Calendar::createInstance(
4842 TimeZone::createTimeZone("GMT-7:00"),
4844 if (!assertSuccess("Creating GMT-7 time zone failed", status)) {
4848 cal->set(1998, 5-1, 25, 0, 0, 0);
4850 // date format time zone should be 4 hours ahead.
4851 fmt->format(cal->getTime(status), result, pos);
4852 assertEquals("format yMdHm", "5/25/1998, 04:00", result);
4853 assertSuccess("", status);
4856 void DateFormatTest::TestDFSCreateForLocaleNonGregorianLocale() {
4857 UErrorCode status = U_ZERO_ERROR;
4859 LocalPointer<DateFormatSymbols> sym(
4860 DateFormatSymbols::createForLocale(fa, status));
4861 if (!assertSuccess("", status)) {
4865 // Farsi should default to the persian calendar, not gregorian
4867 const UnicodeString *months = sym->getShortMonths(count);
4869 // First persian month.
4870 UnicodeString expected("\\u0641\\u0631\\u0648\\u0631\\u062f\\u06cc\\u0646");
4871 assertEquals("", expected.unescape(), months[0]);
4874 void DateFormatTest::TestDFSCreateForLocaleWithCalendarInLocale() {
4875 UErrorCode status = U_ZERO_ERROR;
4876 Locale en_heb("en@calendar=hebrew");
4877 LocalPointer<DateFormatSymbols> sym(
4878 DateFormatSymbols::createForLocale(en_heb, status));
4879 if (!assertSuccess("", status)) {
4883 // We should get the months of the hebrew calendar, not the gregorian
4886 const UnicodeString *months = sym->getShortMonths(count);
4888 // First hebrew month.
4889 UnicodeString expected("Tishri");
4890 assertEquals("", expected, months[0]);
4893 void DateFormatTest::TestChangeCalendar() {
4894 UErrorCode status = U_ZERO_ERROR;
4896 Locale en_heb("en@calendar=hebrew");
4897 LocalPointer<DateFormat> fmt(
4898 DateFormat::createInstanceForSkeleton("yMMMd", en, status));
4899 if (!assertSuccess("", status)) {
4902 fmt->adoptCalendar(Calendar::createInstance(en_heb, status));
4903 if (!assertSuccess("", status)) {
4906 UnicodeString result;
4907 FieldPosition pos(FieldPosition::DONT_CARE);
4908 fmt->format(date(98, 5-1, 25), result, pos);
4909 assertEquals("format yMMMd", "Iyar 29, 5758", result);
4912 void DateFormatTest::TestPatternFromSkeleton() {
4913 static const struct {
4914 const Locale& locale;
4915 const char* const skeleton;
4916 const char* const pattern;
4919 {Locale::getEnglish(), "jjmm", "h:mm a"},
4920 {Locale::getEnglish(), "JJmm", "hh:mm"},
4921 {Locale::getGerman(), "jjmm", "HH:mm"},
4922 {Locale::getGerman(), "JJmm", "HH:mm"}
4925 for (size_t i = 0; i < UPRV_LENGTHOF(TESTDATA); i++) {
4926 UErrorCode status = U_ZERO_ERROR;
4927 LocalPointer<DateFormat> fmt(
4928 DateFormat::createInstanceForSkeleton(
4929 TESTDATA[i].skeleton, TESTDATA[i].locale, status));
4930 if (!assertSuccess("createInstanceForSkeleton", status)) {
4933 UnicodeString pattern;
4934 static_cast<const SimpleDateFormat*>(fmt.getAlias())->toPattern(pattern);
4935 assertEquals("Format pattern", TESTDATA[i].pattern, pattern);
4939 void DateFormatTest::TestAmPmMidnightNoon() {
4940 // Some times on 2015-11-13 (UTC+0).
4941 UDate k000000 = 1447372800000.0;
4942 UDate k000030 = 1447372830000.0;
4943 UDate k003000 = 1447374600000.0;
4944 UDate k060000 = 1447394400000.0;
4945 UDate k120000 = 1447416000000.0;
4946 UDate k180000 = 1447437600000.0;
4948 UErrorCode errorCode = U_ZERO_ERROR;
4949 SimpleDateFormat sdf(UnicodeString(), errorCode);
4950 if (U_FAILURE(errorCode)) {
4951 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
4954 const TimeZone *tz = TimeZone::getGMT();
4955 sdf.setTimeZone(*tz);
4958 // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
4959 // For ICU 57 output of "midnight" is temporarily suppressed.
4962 sdf.applyPattern(UnicodeString("hh:mm:ss bbb"));
4964 // assertEquals("hh:mm:ss bbb | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove()));
4965 assertEquals("hh:mm:ss bbb | 00:00:00", "12:00:00 AM", sdf.format(k000000, out.remove()));
4966 assertEquals("hh:mm:ss bbb | 00:00:30", "12:00:30 AM", sdf.format(k000030, out.remove()));
4967 assertEquals("hh:mm:ss bbb | 00:30:00", "12:30:00 AM", sdf.format(k003000, out.remove()));
4968 assertEquals("hh:mm:ss bbb | 06:00:00", "06:00:00 AM", sdf.format(k060000, out.remove()));
4969 assertEquals("hh:mm:ss bbb | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove()));
4970 assertEquals("hh:mm:ss bbb | 18:00:00", "06:00:00 PM", sdf.format(k180000, out.remove()));
4972 sdf.applyPattern(UnicodeString("hh:mm bbb"));
4974 // assertEquals("hh:mm bbb | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove()));
4975 assertEquals("hh:mm bbb | 00:00:00", "12:00 AM", sdf.format(k000000, out.remove()));
4976 // assertEquals("hh:mm bbb | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove()));
4977 assertEquals("hh:mm bbb | 00:00:30", "12:00 AM", sdf.format(k000030, out.remove()));
4978 assertEquals("hh:mm bbb | 00:30:00", "12:30 AM", sdf.format(k003000, out.remove()));
4980 sdf.applyPattern(UnicodeString("hh bbb"));
4982 // assertEquals("hh bbb | 00:00:00", "12 midnight", sdf.format(k000000, out.remove()));
4983 assertEquals("hh bbb | 00:00:00", "12 AM", sdf.format(k000000, out.remove()));
4984 // assertEquals("hh bbb | 00:00:30", "12 midnight", sdf.format(k000030, out.remove()));
4985 assertEquals("hh bbb | 00:00:30", "12 AM", sdf.format(k000030, out.remove()));
4986 // assertEquals("hh bbb | 00:30:00", "12 midnight", sdf.format(k003000, out.remove()));
4987 assertEquals("hh bbb | 00:30:00", "12 AM", sdf.format(k003000, out.remove()));
4990 sdf.applyPattern(UnicodeString("hh:mm:ss bbbb"));
4992 // assertEquals("hh:mm:ss bbbb | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove()));
4993 assertEquals("hh:mm:ss bbbb | 00:00:00", "12:00:00 AM", sdf.format(k000000, out.remove()));
4994 assertEquals("hh:mm:ss bbbb | 00:00:30", "12:00:30 AM", sdf.format(k000030, out.remove()));
4995 assertEquals("hh:mm:ss bbbb | 00:30:00", "12:30:00 AM", sdf.format(k003000, out.remove()));
4996 assertEquals("hh:mm:ss bbbb | 06:00:00", "06:00:00 AM", sdf.format(k060000, out.remove()));
4997 assertEquals("hh:mm:ss bbbb | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove()));
4998 assertEquals("hh:mm:ss bbbb | 18:00:00", "06:00:00 PM", sdf.format(k180000, out.remove()));
5000 sdf.applyPattern(UnicodeString("hh:mm bbbb"));
5002 // assertEquals("hh:mm bbbb | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove()));
5003 assertEquals("hh:mm bbbb | 00:00:00", "12:00 AM", sdf.format(k000000, out.remove()));
5004 // assertEquals("hh:mm bbbb | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove()));
5005 assertEquals("hh:mm bbbb | 00:00:30", "12:00 AM", sdf.format(k000030, out.remove()));
5006 assertEquals("hh:mm bbbb | 00:30:00", "12:30 AM", sdf.format(k003000, out.remove()));
5008 sdf.applyPattern(UnicodeString("hh bbbb"));
5010 // assertEquals("hh bbbb | 00:00:00", "12 midnight", sdf.format(k000000, out.remove()));
5011 assertEquals("hh bbbb | 00:00:00", "12 AM", sdf.format(k000000, out.remove()));
5012 // assertEquals("hh bbbb | 00:00:30", "12 midnight", sdf.format(k000030, out.remove()));
5013 assertEquals("hh bbbb | 00:00:30", "12 AM", sdf.format(k000030, out.remove()));
5014 // assertEquals("hh bbbb | 00:30:00", "12 midnight", sdf.format(k003000, out.remove()));
5015 assertEquals("hh bbbb | 00:30:00", "12 AM", sdf.format(k003000, out.remove()));
5018 sdf.applyPattern(UnicodeString("hh:mm:ss bbbbb"));
5020 // assertEquals("hh:mm:ss bbbbb | 00:00:00", "12:00:00 mi", sdf.format(k000000, out.remove()));
5021 assertEquals("hh:mm:ss bbbbb | 00:00:00", "12:00:00 a", sdf.format(k000000, out.remove()));
5022 assertEquals("hh:mm:ss bbbbb | 00:00:30", "12:00:30 a", sdf.format(k000030, out.remove()));
5023 assertEquals("hh:mm:ss bbbbb | 00:30:00", "12:30:00 a", sdf.format(k003000, out.remove()));
5024 assertEquals("hh:mm:ss bbbbb | 06:00:00", "06:00:00 a", sdf.format(k060000, out.remove()));
5025 assertEquals("hh:mm:ss bbbbb | 12:00:00", "12:00:00 n", sdf.format(k120000, out.remove()));
5026 assertEquals("hh:mm:ss bbbbb | 18:00:00", "06:00:00 p", sdf.format(k180000, out.remove()));
5028 sdf.applyPattern(UnicodeString("hh:mm bbbbb"));
5030 // assertEquals("hh:mm bbbbb | 00:00:00", "12:00 mi", sdf.format(k000000, out.remove()));
5031 assertEquals("hh:mm bbbbb | 00:00:00", "12:00 a", sdf.format(k000000, out.remove()));
5032 // assertEquals("hh:mm bbbbb | 00:00:30", "12:00 mi", sdf.format(k000030, out.remove()));
5033 assertEquals("hh:mm bbbbb | 00:00:30", "12:00 a", sdf.format(k000030, out.remove()));
5034 assertEquals("hh:mm bbbbb | 00:30:00", "12:30 a", sdf.format(k003000, out.remove()));
5036 sdf.applyPattern(UnicodeString("hh bbbbb"));
5038 // assertEquals("hh bbbbb | 00:00:00", "12 mi", sdf.format(k000000, out.remove()));
5039 assertEquals("hh bbbbb | 00:00:00", "12 a", sdf.format(k000000, out.remove()));
5040 // assertEquals("hh bbbbb | 00:00:30", "12 mi", sdf.format(k000030, out.remove()));
5041 assertEquals("hh bbbbb | 00:00:30", "12 a", sdf.format(k000030, out.remove()));
5042 // assertEquals("hh bbbbb | 00:30:00", "12 mi", sdf.format(k003000, out.remove()));
5043 assertEquals("hh bbbbb | 00:30:00", "12 a", sdf.format(k003000, out.remove()));
5046 void DateFormatTest::TestFlexibleDayPeriod() {
5047 // Some times on 2015-11-13 (UTC+0).
5048 UDate k000000 = 1447372800000.0;
5049 UDate k000030 = 1447372830000.0;
5050 UDate k003000 = 1447374600000.0;
5051 UDate k060000 = 1447394400000.0;
5052 UDate k120000 = 1447416000000.0;
5053 UDate k180000 = 1447437600000.0;
5055 UErrorCode errorCode = U_ZERO_ERROR;
5056 SimpleDateFormat sdf(UnicodeString(), errorCode);
5057 if (U_FAILURE(errorCode)) {
5058 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
5061 const TimeZone *tz = TimeZone::getGMT();
5062 sdf.setTimeZone(*tz);
5065 // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
5066 // For ICU 57 output of "midnight" is temporarily suppressed.
5069 sdf.applyPattern(UnicodeString("hh:mm:ss BBB"));
5071 // assertEquals("hh:mm:ss BBB | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove()));
5072 assertEquals("hh:mm:ss BBB | 00:00:00", "12:00:00 at night", sdf.format(k000000, out.remove()));
5073 assertEquals("hh:mm:ss BBB | 00:00:30", "12:00:30 at night", sdf.format(k000030, out.remove()));
5074 assertEquals("hh:mm:ss BBB | 00:30:00", "12:30:00 at night", sdf.format(k003000, out.remove()));
5075 assertEquals("hh:mm:ss BBB | 06:00:00", "06:00:00 in the morning", sdf.format(k060000, out.remove()));
5076 assertEquals("hh:mm:ss BBB | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove()));
5077 assertEquals("hh:mm:ss BBB | 18:00:00", "06:00:00 in the evening", sdf.format(k180000, out.remove()));
5079 sdf.applyPattern(UnicodeString("hh:mm BBB"));
5081 // assertEquals("hh:mm BBB | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove()));
5082 assertEquals("hh:mm BBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove()));
5083 // assertEquals("hh:mm BBB | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove()));
5084 assertEquals("hh:mm BBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove()));
5085 assertEquals("hh:mm BBB | 00:30:00", "12:30 at night", sdf.format(k003000, out.remove()));
5087 sdf.applyPattern(UnicodeString("hh BBB"));
5089 // assertEquals("hh BBB | 00:00:00", "12 midnight", sdf.format(k000000, out.remove()));
5090 assertEquals("hh BBB | 00:00:30", "12 at night", sdf.format(k000030, out.remove()));
5091 // assertEquals("hh BBB | 00:00:30", "12 midnight", sdf.format(k000030, out.remove()));
5092 assertEquals("hh BBB | 00:00:30", "12 at night", sdf.format(k000030, out.remove()));
5093 // assertEquals("hh BBB | 00:30:00", "12 midnight", sdf.format(k003000, out.remove()));
5094 assertEquals("hh BBB | 00:30:00", "12 at night", sdf.format(k003000, out.remove()));
5097 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
5099 // assertEquals("hh:mm:ss BBBB | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove()));
5100 assertEquals("hh:mm:ss BBBB | 00:00:00", "12:00:00 at night", sdf.format(k000000, out.remove()));
5101 assertEquals("hh:mm:ss BBBB | 00:00:30", "12:00:30 at night", sdf.format(k000030, out.remove()));
5102 assertEquals("hh:mm:ss BBBB | 00:30:00", "12:30:00 at night", sdf.format(k003000, out.remove()));
5103 assertEquals("hh:mm:ss BBBB | 06:00:00", "06:00:00 in the morning", sdf.format(k060000, out.remove()));
5104 assertEquals("hh:mm:ss BBBB | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove()));
5105 assertEquals("hh:mm:ss BBBB | 18:00:00", "06:00:00 in the evening", sdf.format(k180000, out.remove()));
5107 sdf.applyPattern(UnicodeString("hh:mm BBBB"));
5109 // assertEquals("hh:mm BBBB | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove()));
5110 assertEquals("hh:mm BBBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove()));
5111 // assertEquals("hh:mm BBBB | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove()));
5112 assertEquals("hh:mm BBBB | 00:00:30", "12:00 at night", sdf.format(k000030, out.remove()));
5113 assertEquals("hh:mm BBBB | 00:30:00", "12:30 at night", sdf.format(k003000, out.remove()));
5115 sdf.applyPattern(UnicodeString("hh BBBB"));
5117 // assertEquals("hh BBBB | 00:00:00", "12 midnight", sdf.format(k000000, out.remove()));
5118 assertEquals("hh BBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove()));
5119 // assertEquals("hh BBBB | 00:00:30", "12 midnight", sdf.format(k000030, out.remove()));
5120 assertEquals("hh BBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove()));
5121 // assertEquals("hh BBBB | 00:80:00", "12 midnight", sdf.format(k003000, out.remove()));
5122 assertEquals("hh BBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove()));
5125 sdf.applyPattern(UnicodeString("hh:mm:ss BBBBB"));
5127 // assertEquals("hh:mm:ss BBBBB | 00:00:00", "12:00:00 mi", sdf.format(k000000, out.remove()));
5128 assertEquals("hh:mm:ss BBBBB | 00:00:00", "12:00:00 at night", sdf.format(k000000, out.remove()));
5129 assertEquals("hh:mm:ss BBBBB | 00:00:30", "12:00:30 at night", sdf.format(k000030, out.remove()));
5130 assertEquals("hh:mm:ss BBBBB | 00:30:00", "12:30:00 at night", sdf.format(k003000, out.remove()));
5131 assertEquals("hh:mm:ss BBBBB | 06:00:00", "06:00:00 in the morning", sdf.format(k060000, out.remove()));
5132 assertEquals("hh:mm:ss BBBBB | 12:00:00", "12:00:00 n", sdf.format(k120000, out.remove()));
5133 assertEquals("hh:mm:ss BBBBB | 18:00:00", "06:00:00 in the evening", sdf.format(k180000, out.remove()));
5135 sdf.applyPattern(UnicodeString("hh:mm BBBBB"));
5137 // assertEquals("hh:mm BBBBB | 00:00:00", "12:00 mi", sdf.format(k000000, out.remove()));
5138 assertEquals("hh:mm BBBBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove()));
5139 // assertEquals("hh:mm BBBBB | 00:00:30", "12:00 mi", sdf.format(k000030, out.remove()));
5140 assertEquals("hh:mm BBBBB | 00:00:30", "12:00 at night", sdf.format(k000030, out.remove()));
5141 assertEquals("hh:mm BBBBB | 00:30:00", "12:30 at night", sdf.format(k003000, out.remove()));
5143 sdf.applyPattern(UnicodeString("hh BBBBB"));
5145 // assertEquals("hh BBBBB | 00:00:00", "12 mi", sdf.format(k000000, out.remove()));
5146 assertEquals("hh BBBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove()));
5147 // assertEquals("hh BBBBB | 00:00:30", "12 mi", sdf.format(k000030, out.remove()));
5148 assertEquals("hh BBBBB | 00:00:30", "12 at night", sdf.format(k000030, out.remove()));
5149 // assertEquals("hh BBBBB | 00:30:00", "12 mi", sdf.format(k003000, out.remove()));
5150 assertEquals("hh BBBBB | 00:30:00", "12 at night", sdf.format(k003000, out.remove()));
5153 void DateFormatTest::TestDayPeriodWithLocales() {
5154 // Some times on 2015-11-13 (UTC+0).
5155 UDate k000000 = 1447372800000.0;
5156 UDate k010000 = 1447376400000.0;
5157 UDate k120000 = 1447416000000.0;
5158 UDate k220000 = 1447452000000.0;
5160 UErrorCode errorCode = U_ZERO_ERROR;
5161 const TimeZone *tz = TimeZone::getGMT();
5164 // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
5165 // For ICU 57 output of "midnight" and its localized equivalentns is temporarily suppressed.
5167 // Locale de has a word for midnight, but not noon.
5168 SimpleDateFormat sdf(UnicodeString(), Locale::getGermany(), errorCode);
5169 if (U_FAILURE(errorCode)) {
5170 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
5173 sdf.setTimeZone(*tz);
5175 sdf.applyPattern(UnicodeString("hh:mm:ss bbbb"));
5177 // assertEquals("hh:mm:ss bbbb | 00:00:00 | de", "12:00:00 Mitternacht",
5178 // sdf.format(k000000, out.remove()));
5179 assertEquals("hh:mm:ss bbbb | 00:00:00 | de", "12:00:00 vorm.",
5180 sdf.format(k000000, out.remove()));
5181 assertEquals("hh:mm:ss bbbb | 12:00:00 | de", "12:00:00 nachm.",
5182 sdf.format(k120000, out.remove()));
5184 // Locale ee has a rule that wraps around midnight (21h - 4h).
5185 sdf = SimpleDateFormat(UnicodeString(), Locale("ee"), errorCode);
5186 sdf.setTimeZone(*tz);
5188 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
5190 assertEquals("hh:mm:ss BBBB | 22:00:00 | ee", UnicodeString("10:00:00 z\\u00E3").unescape(),
5191 sdf.format(k220000, out.remove()));
5192 assertEquals("hh:mm:ss BBBB | 00:00:00 | ee", UnicodeString("12:00:00 z\\u00E3").unescape(),
5193 sdf.format(k000000, out.remove()));
5194 assertEquals("hh:mm:ss BBBB | 01:00:00 | ee", UnicodeString("01:00:00 z\\u00E3").unescape(),
5195 sdf.format(k010000, out.remove()));
5197 // Locale root has rules for AM/PM only.
5198 sdf = SimpleDateFormat(UnicodeString(), Locale("root"), errorCode);
5199 sdf.setTimeZone(*tz);
5201 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
5203 assertEquals("hh:mm:ss BBBB | 00:00:00 | root", "12:00:00 AM",
5204 sdf.format(k000000, out.remove()));
5205 assertEquals("hh:mm:ss BBBB | 12:00:00 | root", "12:00:00 PM",
5206 sdf.format(k120000, out.remove()));
5208 // Empty string should behave exactly as root.
5209 sdf = SimpleDateFormat(UnicodeString(), Locale(""), errorCode);
5210 sdf.setTimeZone(*tz);
5212 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
5214 assertEquals("hh:mm:ss BBBB | 00:00:00 | \"\" (root)", "12:00:00 AM",
5215 sdf.format(k000000, out.remove()));
5216 assertEquals("hh:mm:ss BBBB | 12:00:00 | \"\" (root)", "12:00:00 PM",
5217 sdf.format(k120000, out.remove()));
5219 // Locale en_US should fall back to en.
5220 sdf = SimpleDateFormat(UnicodeString(), Locale("en_US"), errorCode);
5221 sdf.setTimeZone(*tz);
5223 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
5225 // assertEquals("hh:mm:ss BBBB | 00:00:00 | en_US", "12:00:00 midnight",
5226 // sdf.format(k000000, out.remove()));
5227 assertEquals("hh:mm:ss BBBB | 00:00:00 | en_US", "12:00:00 at night",
5228 sdf.format(k000000, out.remove()));
5229 assertEquals("hh:mm:ss BBBB | 01:00:00 | en_US", "01:00:00 at night",
5230 sdf.format(k010000, out.remove()));
5231 assertEquals("hh:mm:ss BBBB | 12:00:00 | en_US", "12:00:00 noon",
5232 sdf.format(k120000, out.remove()));
5234 // Locale es_CO should not fall back to es and should have a
5235 // different string for 1 in the morning.
5236 // (es_CO: "de la manana" (first n has a tilde) vs. es: "de la madrugada")
5237 sdf = SimpleDateFormat(UnicodeString(), Locale("es_CO"), errorCode);
5238 sdf.setTimeZone(*tz);
5240 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
5241 assertEquals("hh:mm:ss BBBB | 01:00:00 | es_CO", UnicodeString("01:00:00 de la ma\\u00F1ana").unescape(),
5242 sdf.format(k010000, out.remove()));
5244 sdf = SimpleDateFormat(UnicodeString(), Locale("es"), errorCode);
5245 sdf.setTimeZone(*tz);
5247 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB"));
5248 assertEquals("hh:mm:ss BBBB | 01:00:00 | es", "01:00:00 de la madrugada",
5249 sdf.format(k010000, out.remove()));
5252 void DateFormatTest::TestMinuteSecondFieldsInOddPlaces() {
5253 // Some times on 2015-11-13 (UTC+0).
5254 UDate k000000 = 1447372800000.0;
5255 UDate k000030 = 1447372830000.0;
5256 UDate k003000 = 1447374600000.0;
5257 UDate k060030 = 1447394430000.0;
5258 UDate k063000 = 1447396200000.0;
5260 UErrorCode errorCode = U_ZERO_ERROR;
5261 const TimeZone *tz = TimeZone::getGMT();
5264 // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day.
5265 // For ICU 57 output of "midnight" is temporarily suppressed.
5267 // Seconds field is not present.
5269 // Apply pattern through constructor to make sure parsePattern() is called during initialization.
5270 SimpleDateFormat sdf(UnicodeString("hh:mm 'ss' bbbb"), errorCode);
5271 if (U_FAILURE(errorCode)) {
5272 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
5275 sdf.setTimeZone(*tz);
5277 // assertEquals("hh:mm 'ss' bbbb | 00:00:30", "12:00 ss midnight",
5278 // sdf.format(k000030, out.remove()));
5279 assertEquals("hh:mm 'ss' bbbb | 00:00:30", "12:00 ss AM",
5280 sdf.format(k000030, out.remove()));
5281 assertEquals("hh:mm 'ss' bbbb | 06:00:30", "06:00 ss AM",
5282 sdf.format(k060030, out.remove()));
5284 sdf.applyPattern(UnicodeString("hh:mm 'ss' BBBB"));
5286 // assertEquals("hh:mm 'ss' BBBB | 00:00:30", "12:00 ss midnight",
5287 // sdf.format(k000030, out.remove()));
5288 assertEquals("hh:mm 'ss' BBBB | 00:00:30", "12:00 ss at night",
5289 sdf.format(k000030, out.remove()));
5290 assertEquals("hh:mm 'ss' BBBB | 06:00:30", "06:00 ss in the morning",
5291 sdf.format(k060030, out.remove()));
5293 // Minutes field is not present.
5294 sdf.applyPattern(UnicodeString("hh 'mm ss' bbbb"));
5296 // assertEquals("hh 'mm ss' bbbb | 00:30:00", "12 mm ss midnight",
5297 // sdf.format(k003000, out.remove()));
5298 assertEquals("hh 'mm ss' bbbb | 00:30:00", "12 mm ss AM",
5299 sdf.format(k003000, out.remove()));
5300 assertEquals("hh 'mm ss' bbbb | 06:30:00", "06 mm ss AM",
5301 sdf.format(k063000, out.remove()));
5303 sdf.applyPattern(UnicodeString("hh 'mm ss' BBBB"));
5305 // assertEquals("hh 'mm ss' BBBB | 00:30:00", "12 mm ss midnight",
5306 // sdf.format(k003000, out.remove()));
5307 assertEquals("hh 'mm ss' BBBB | 00:30:00", "12 mm ss at night",
5308 sdf.format(k003000, out.remove()));
5309 assertEquals("hh 'mm ss' BBBB | 06:30:00", "06 mm ss in the morning",
5310 sdf.format(k063000, out.remove()));
5312 // Minutes and seconds fields appear after day periods.
5313 sdf.applyPattern(UnicodeString("bbbb hh:mm:ss"));
5315 // assertEquals("bbbb hh:mm:ss | 00:00:00", "midnight 12:00:00",
5316 // sdf.format(k000000, out.remove()));
5317 assertEquals("bbbb hh:mm:ss | 00:00:00", "AM 12:00:00",
5318 sdf.format(k000000, out.remove()));
5319 assertEquals("bbbb hh:mm:ss | 00:00:30", "AM 12:00:30",
5320 sdf.format(k000030, out.remove()));
5321 assertEquals("bbbb hh:mm:ss | 00:30:00", "AM 12:30:00",
5322 sdf.format(k003000, out.remove()));
5324 sdf.applyPattern(UnicodeString("BBBB hh:mm:ss"));
5326 // assertEquals("BBBB hh:mm:ss | 00:00:00", "midnight 12:00:00",
5327 // sdf.format(k000000, out.remove()));
5328 assertEquals("BBBB hh:mm:ss | 00:00:00", "at night 12:00:00",
5329 sdf.format(k000000, out.remove()));
5330 assertEquals("BBBB hh:mm:ss | 00:00:30", "at night 12:00:30",
5331 sdf.format(k000030, out.remove()));
5332 assertEquals("BBBB hh:mm:ss | 00:30:00", "at night 12:30:00",
5333 sdf.format(k003000, out.remove()));
5335 // Confirm applyPattern() reparses the pattern string.
5336 sdf.applyPattern(UnicodeString("BBBB hh"));
5337 // assertEquals("BBBB hh | 00:00:30", "midnight 12",
5338 // sdf.format(k000030, out.remove()));
5339 assertEquals("BBBB hh | 00:00:30", "at night 12",
5340 sdf.format(k000030, out.remove()));
5342 sdf.applyPattern(UnicodeString("BBBB hh:mm:'ss'"));
5343 // assertEquals("BBBB hh:mm:'ss' | 00:00:30", "midnight 12:00:ss",
5344 // sdf.format(k000030, out.remove()));
5345 assertEquals("BBBB hh | 00:00:30", "at night 12:00:ss",
5346 sdf.format(k000030, out.remove()));
5348 sdf.applyPattern(UnicodeString("BBBB hh:mm:ss"));
5349 assertEquals("BBBB hh:mm:ss | 00:00:30", "at night 12:00:30",
5350 sdf.format(k000030, out.remove()));
5353 void DateFormatTest::TestDayPeriodParsing() {
5354 // Some times on 2015-11-13 (UTC+0).
5355 UDate k000000 = 1447372800000.0;
5356 UDate k003700 = 1447375020000.0;
5357 UDate k010000 = 1447376400000.0;
5358 UDate k013000 = 1447378200000.0;
5359 UDate k030000 = 1447383600000.0;
5360 UDate k090000 = 1447405200000.0;
5361 UDate k120000 = 1447416000000.0;
5362 UDate k130000 = 1447419600000.0;
5363 UDate k133700 = 1447421820000.0;
5364 UDate k150000 = 1447426800000.0;
5365 UDate k190000 = 1447441200000.0;
5366 UDate k193000 = 1447443000000.0;
5367 UDate k200000 = 1447444800000.0;
5368 UDate k210000 = 1447448400000.0;
5370 UErrorCode errorCode = U_ZERO_ERROR;
5371 SimpleDateFormat sdf(UnicodeString(), errorCode);
5372 if (U_FAILURE(errorCode)) {
5373 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode));
5376 const TimeZone *tz = TimeZone::getGMT();
5377 sdf.setTimeZone(*tz);
5380 // 'B' -- flexible day periods
5381 // A day period on its own parses to the center of that period.
5382 sdf.applyPattern(UnicodeString("yyyy-MM-dd B"));
5383 assertEquals("yyyy-MM-dd B | 2015-11-13 midnight",
5384 k000000, sdf.parse(UnicodeString("2015-11-13 midnight"), errorCode));
5385 assertEquals("yyyy-MM-dd B | 2015-11-13 noon",
5386 k120000, sdf.parse(UnicodeString("2015-11-13 noon"), errorCode));
5387 assertEquals("yyyy-MM-dd B | 2015-11-13 in the afternoon",
5388 k150000, sdf.parse(UnicodeString("2015-11-13 in the afternoon"), errorCode));
5389 assertEquals("yyyy-MM-dd B | 2015-11-13 in the evening",
5390 k193000, sdf.parse(UnicodeString("2015-11-13 in the evening"), errorCode));
5391 assertEquals("yyyy-MM-dd B | 2015-11-13 at night",
5392 k013000, sdf.parse(UnicodeString("2015-11-13 at night"), errorCode));
5394 // If time and day period are consistent with each other then time is parsed accordingly.
5395 sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm B"));
5396 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 12:00 midnight",
5397 k000000, sdf.parse(UnicodeString("2015-11-13 12:00 midnight"), errorCode));
5398 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 12:00 noon",
5399 k120000, sdf.parse(UnicodeString("2015-11-13 12:00 noon"), errorCode));
5400 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 01:00 at night",
5401 k010000, sdf.parse(UnicodeString("2015-11-13 01:00 at night"), errorCode));
5402 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 01:00 in the afternoon",
5403 k130000, sdf.parse(UnicodeString("2015-11-13 01:00 in the afternoon"), errorCode));
5404 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 09:00 in the morning",
5405 k090000, sdf.parse(UnicodeString("2015-11-13 09:00 in the morning"), errorCode));
5406 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 09:00 at night",
5407 k210000, sdf.parse(UnicodeString("2015-11-13 09:00 at night"), errorCode));
5409 // If the hour is 13 thru 23 then day period has no effect on time (since time is assumed
5410 // to be in 24-hour format).
5411 sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm B"));
5412 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 midnight",
5413 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 midnight"), errorCode));
5414 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 noon",
5415 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 noon"), errorCode));
5416 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 at night",
5417 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 at night"), errorCode));
5418 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 in the afternoon",
5419 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 in the afternoon"), errorCode));
5420 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 in the morning",
5421 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 in the morning"), errorCode));
5422 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 at night",
5423 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 at night"), errorCode));
5425 // Hour 0 is synonymous with hour 12 when parsed with 'h'.
5426 // This unfortunately means we have to tolerate "0 noon" as it's synonymous with "12 noon".
5427 sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm B"));
5428 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 00:00 midnight",
5429 k000000, sdf.parse(UnicodeString("2015-11-13 00:00 midnight"), errorCode));
5430 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 00:00 noon",
5431 k120000, sdf.parse(UnicodeString("2015-11-13 00:00 noon"), errorCode));
5433 // But when parsed with 'H', 0 indicates a 24-hour time, therefore we disregard the day period.
5434 sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm B"));
5435 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 midnight",
5436 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 midnight"), errorCode));
5437 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 noon",
5438 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 noon"), errorCode));
5439 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 at night",
5440 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 at night"), errorCode));
5441 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 in the afternoon",
5442 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 in the afternoon"), errorCode));
5443 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 in the morning",
5444 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 in the morning"), errorCode));
5445 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 at night",
5446 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 at night"), errorCode));
5448 // Even when parsed with 'H', hours 1 thru 12 are considered 12-hour time and takes
5449 // day period into account in parsing.
5450 sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm B"));
5451 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 12:00 midnight",
5452 k000000, sdf.parse(UnicodeString("2015-11-13 12:00 midnight"), errorCode));
5453 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 12:00 noon",
5454 k120000, sdf.parse(UnicodeString("2015-11-13 12:00 noon"), errorCode));
5455 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 01:00 at night",
5456 k010000, sdf.parse(UnicodeString("2015-11-13 01:00 at night"), errorCode));
5457 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 01:00 in the afternoon",
5458 k130000, sdf.parse(UnicodeString("2015-11-13 01:00 in the afternoon"), errorCode));
5459 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 09:00 in the morning",
5460 k090000, sdf.parse(UnicodeString("2015-11-13 09:00 in the morning"), errorCode));
5461 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 09:00 at night",
5462 k210000, sdf.parse(UnicodeString("2015-11-13 09:00 at night"), errorCode));
5464 // If a 12-hour time and the day period don't agree with each other, time is parsed as close
5465 // to the given day period as possible.
5466 sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm B"));
5468 // AFTERNOON1 is [12, 18), but "7 in the afternoon" parses to 19:00.
5469 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 07:00 in the afternoon",
5470 k190000, sdf.parse(UnicodeString("2015-11-13 07:00 in the afternoon"), errorCode));
5471 // NIGHT1 is [21, 6), but "8 at night" parses to 20:00.
5472 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 08:00 at night",
5473 k200000, sdf.parse(UnicodeString("2015-11-13 08:00 at night"), errorCode));
5475 // 'b' -- fixed day periods (AM, PM, midnight, noon)
5476 // On their own, "midnight" parses to 00:00 and "noon" parses to 12:00.
5477 // AM and PM are handled by the 'a' parser (which doesn't handle this case well).
5478 sdf.applyPattern(UnicodeString("yyyy-MM-dd b"));
5479 assertEquals("yyyy-MM-dd b | 2015-11-13 midnight",
5480 k000000, sdf.parse(UnicodeString("2015-11-13 midnight"), errorCode));
5481 assertEquals("yyyy-MM-dd b | 2015-11-13 noon",
5482 k120000, sdf.parse(UnicodeString("2015-11-13 noon"), errorCode));
5484 // For 12-hour times, AM and PM should be parsed as if with pattern character 'a'.
5485 sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm b"));
5486 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 01:00 AM",
5487 k010000, sdf.parse(UnicodeString("2015-11-13 01:00 AM"), errorCode));
5488 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 01:00 PM",
5489 k130000, sdf.parse(UnicodeString("2015-11-13 01:00 PM"), errorCode));
5491 // 12 midnight parses to 00:00, and 12 noon parses to 12:00.
5492 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 12:00 midnight",
5493 k000000, sdf.parse(UnicodeString("2015-11-13 12:00 midnight"), errorCode));
5494 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 12:00 noon",
5495 k120000, sdf.parse(UnicodeString("2015-11-13 12:00 noon"), errorCode));
5497 // Hours 13-23 indicate 24-hour time so we disregard "midnight" or "noon".
5498 // Again, AM and PM are handled by the 'a' parser which doesn't handle this case well.
5499 sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm b"));
5500 assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 13:37 midnight",
5501 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 midnight"), errorCode));
5502 assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 13:37 noon",
5503 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 noon"), errorCode));
5505 // Hour 0 is synonymous with hour 12 when parsed with 'h'.
5506 // Again, this means we have to tolerate "0 noon" as it's synonymous with "12 noon".
5507 sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm b"));
5508 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 00:00 midnight",
5509 k000000, sdf.parse(UnicodeString("2015-11-13 00:00 midnight"), errorCode));
5510 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 00:00 noon",
5511 k120000, sdf.parse(UnicodeString("2015-11-13 00:00 noon"), errorCode));
5513 // With 'H' though 0 indicates a 24-hour time, therefore we disregard the day period.
5514 sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm b"));
5515 assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 00:37 midnight",
5516 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 midnight"), errorCode));
5517 assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 00:37 noon",
5518 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 noon"), errorCode));
5520 // If "midnight" or "noon" is parsed with a 12-hour time other than 12:00, choose
5521 // the version that's closer to the period given.
5522 sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm b"));
5523 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 03:00 midnight",
5524 k030000, sdf.parse(UnicodeString("2015-11-13 03:00 midnight"), errorCode));
5525 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 03:00 noon",
5526 k150000, sdf.parse(UnicodeString("2015-11-13 03:00 noon"), errorCode));
5529 #endif /* #if !UCONFIG_NO_FORMATTING */