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