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