1 // Copyright (C) 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_HAS_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_HAS_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 Locale valid1; 2608 Locale actual1; 2609 if (!getActualAndValidLocales(*fmt, valid1, actual1)) { 2610 dataerrln("FAIL: Could not fetch valid + actual locales"); 2611 return; 2612 } 2613 LocalPointer<Format> fmtClone(fmt->clone()); 2614 2615 // Free fmt to be sure that fmtClone is really independent of fmt. 2616 fmt.adoptInstead(NULL); 2617 Locale valid2; 2618 Locale actual2; 2619 if (!getActualAndValidLocales(*fmtClone, valid2, actual2)) { 2620 errln("FAIL: Could not fetch valid + actual locales"); 2621 return; 2622 } 2623 if (valid1 != valid2 || actual1 != actual2) { 2624 errln("Date format symbol locales of clone don't match original"); 2625 } 2626 } 2627 2628 void DateFormatTest::TestTimeZoneDisplayName() 2629 { 2630 // This test data was ported from ICU4J. Don't know why the 6th column in there because it's not being 2631 // used currently. 2632 const char *fallbackTests[][6] = { 2633 { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, 2634 { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" }, 2635 { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZZ", "-08:00", "-8:00" }, 2636 { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "PST", "America/Los_Angeles" }, 2637 { "en", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "Pacific Standard Time", "America/Los_Angeles" }, 2638 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" }, 2639 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" }, 2640 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "PDT", "America/Los_Angeles" }, 2641 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "Pacific Daylight Time", "America/Los_Angeles" }, 2642 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "PT", "America/Los_Angeles" }, 2643 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Pacific Time", "America/Los_Angeles" }, 2644 { "en", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "Los Angeles Time", "America/Los_Angeles" }, 2645 { "en_GB", "America/Los_Angeles", "2004-01-15T12:00:00Z", "z", "GMT-8", "America/Los_Angeles" }, 2646 { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "Z", "-0700", "-7:00" }, 2647 { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" }, 2648 { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "z", "MST", "America/Phoenix" }, 2649 { "en", "America/Phoenix", "2004-01-15T00:00:00Z", "zzzz", "Mountain Standard Time", "America/Phoenix" }, 2650 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" }, 2651 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" }, 2652 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "z", "MST", "America/Phoenix" }, 2653 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "zzzz", "Mountain Standard Time", "America/Phoenix" }, 2654 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "v", "MST", "America/Phoenix" }, 2655 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "vvvv", "Mountain Standard Time", "America/Phoenix" }, 2656 { "en", "America/Phoenix", "2004-07-15T00:00:00Z", "VVVV", "Phoenix Time", "America/Phoenix" }, 2657 2658 { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2659 { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2660 { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2661 { "en", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" }, 2662 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2663 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2664 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2665 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" }, 2666 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Time", "America/Buenos_Aires" }, 2667 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentina Standard Time", "America/Buenos_Aires" }, 2668 { "en", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "VVVV", "Buenos Aires Time", "America/Buenos_Aires" }, 2669 2670 { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2671 { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2672 { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2673 { "en", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" }, 2674 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2675 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2676 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2677 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentina Standard Time", "-3:00" }, 2678 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Time", "America/Buenos_Aires" }, 2679 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentina Standard Time", "America/Buenos_Aires" }, 2680 { "en", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "VVVV", "Buenos Aires Time", "America/Buenos_Aires" }, 2681 2682 { "en", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" }, 2683 { "en", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" }, 2684 { "en", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" }, 2685 { "en", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "Cuba Standard Time", "-5:00" }, 2686 { "en", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" }, 2687 { "en", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" }, 2688 { "en", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" }, 2689 { "en", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "Cuba Daylight Time", "-4:00" }, 2690 { "en", "America/Havana", "2004-07-15T00:00:00Z", "v", "Cuba Time", "America/Havana" }, 2691 { "en", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Cuba Time", "America/Havana" }, 2692 { "en", "America/Havana", "2004-07-15T00:00:00Z", "VVVV", "Cuba Time", "America/Havana" }, 2693 2694 { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 2695 { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, 2696 { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, 2697 { "en", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "Australian Eastern Daylight Time", "+11:00" }, 2698 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 2699 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, 2700 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, 2701 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "Australian Eastern Standard Time", "+10:00" }, 2702 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Sydney Time", "Australia/Sydney" }, 2703 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Eastern Australia Time", "Australia/Sydney" }, 2704 { "en", "Australia/ACT", "2004-07-15T00:00:00Z", "VVVV", "Sydney Time", "Australia/Sydney" }, 2705 2706 { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 2707 { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, 2708 { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, 2709 { "en", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "Australian Eastern Daylight Time", "+11:00" }, 2710 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 2711 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, 2712 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, 2713 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "Australian Eastern Standard Time", "+10:00" }, 2714 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Sydney Time", "Australia/Sydney" }, 2715 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Eastern Australia Time", "Australia/Sydney" }, 2716 { "en", "Australia/Sydney", "2004-07-15T00:00:00Z", "VVVV", "Sydney Time", "Australia/Sydney" }, 2717 2718 { "en", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" }, 2719 { "en", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" }, 2720 { "en", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" }, 2721 { "en", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "Greenwich Mean Time", "+0:00" }, 2722 { "en", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" }, 2723 { "en", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" }, 2724 { "en", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "Europe/London" }, 2725 { "en", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "British Summer Time", "Europe/London" }, 2726 // icu en.txt has exemplar city for this time zone 2727 { "en", "Europe/London", "2004-07-15T00:00:00Z", "v", "United Kingdom Time", "Europe/London" }, 2728 { "en", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "United Kingdom Time", "Europe/London" }, 2729 { "en", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "United Kingdom Time", "Europe/London" }, 2730 2731 { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2732 { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2733 { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2734 { "en", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 2735 { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2736 { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2737 { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2738 { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 2739 { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" }, 2740 { "en", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" }, 2741 2742 // JB#5150 2743 { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" }, 2744 { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, 2745 { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" }, 2746 { "en", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "India Standard Time", "+5:30" }, 2747 { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" }, 2748 { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, 2749 { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" }, 2750 { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "India Standard Time", "+5:30" }, 2751 { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "India Time", "Asia/Calcutta" }, 2752 { "en", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "India Standard Time", "Asia/Calcutta" }, 2753 2754 // Proper CLDR primary zone support #9733 2755 { "en", "America/Santiago", "2013-01-01T00:00:00Z", "VVVV", "Chile Time", "America/Santiago" }, 2756 { "en", "Pacific/Easter", "2013-01-01T00:00:00Z", "VVVV", "Easter Time", "Pacific/Easter" }, 2757 2758 // ========== 2759 2760 { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, 2761 { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" }, 2762 { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "-8:00" }, 2763 { "de", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "Nordamerikanische Westk\\u00fcsten-Normalzeit", "-8:00" }, 2764 { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" }, 2765 { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" }, 2766 { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "-7:00" }, 2767 { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "Nordamerikanische Westk\\u00fcsten-Sommerzeit", "-7:00" }, 2768 { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "Los Angeles Zeit", "America/Los_Angeles" }, 2769 { "de", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Nordamerikanische Westk\\u00fcstenzeit", "America/Los_Angeles" }, 2770 2771 { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2772 { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2773 { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2774 { "de", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" }, 2775 { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2776 { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2777 { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2778 { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" }, 2779 { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Zeit", "America/Buenos_Aires" }, 2780 { "de", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentinische Normalzeit", "America/Buenos_Aires" }, 2781 2782 { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2783 { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2784 { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2785 { "de", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" }, 2786 { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2787 { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2788 { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2789 { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "Argentinische Normalzeit", "-3:00" }, 2790 { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires Zeit", "America/Buenos_Aires" }, 2791 { "de", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Argentinische Normalzeit", "America/Buenos_Aires" }, 2792 2793 { "de", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" }, 2794 { "de", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" }, 2795 { "de", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" }, 2796 { "de", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "Kubanische Normalzeit", "-5:00" }, 2797 { "de", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" }, 2798 { "de", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" }, 2799 { "de", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" }, 2800 { "de", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "Kubanische Sommerzeit", "-4:00" }, 2801 { "de", "America/Havana", "2004-07-15T00:00:00Z", "v", "Kuba Zeit", "America/Havana" }, 2802 { "de", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Kubanische Zeit", "America/Havana" }, 2803 // added to test proper fallback of country name 2804 { "de_CH", "America/Havana", "2004-07-15T00:00:00Z", "v", "Kuba Zeit", "America/Havana" }, 2805 { "de_CH", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "Kubanische Zeit", "America/Havana" }, 2806 2807 { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 2808 { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, 2809 { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, 2810 { "de", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "Ostaustralische Sommerzeit", "+11:00" }, 2811 { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 2812 { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, 2813 { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, 2814 { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "Ostaustralische Normalzeit", "+10:00" }, 2815 { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Sydney Zeit", "Australia/Sydney" }, 2816 { "de", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Ostaustralische Zeit", "Australia/Sydney" }, 2817 2818 { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 2819 { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, 2820 { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, 2821 { "de", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "Ostaustralische Sommerzeit", "+11:00" }, 2822 { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 2823 { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, 2824 { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, 2825 { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "Ostaustralische Normalzeit", "+10:00" }, 2826 { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Sydney Zeit", "Australia/Sydney" }, 2827 { "de", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Ostaustralische Zeit", "Australia/Sydney" }, 2828 2829 { "de", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" }, 2830 { "de", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" }, 2831 { "de", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" }, 2832 { "de", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "Mittlere Greenwich-Zeit", "+0:00" }, 2833 { "de", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" }, 2834 { "de", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" }, 2835 { "de", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" }, 2836 { "de", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "Britische Sommerzeit", "+1:00" }, 2837 { "de", "Europe/London", "2004-07-15T00:00:00Z", "v", "Vereinigtes K\\u00f6nigreich Zeit", "Europe/London" }, 2838 { "de", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "Vereinigtes K\\u00f6nigreich Zeit", "Europe/London" }, 2839 2840 { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2841 { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2842 { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2843 { "de", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 2844 { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2845 { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2846 { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2847 { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 2848 { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" }, 2849 { "de", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" }, 2850 2851 // JB#5150 2852 { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" }, 2853 { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, 2854 { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" }, 2855 { "de", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "Indische Zeit", "+5:30" }, 2856 { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" }, 2857 { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, 2858 { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" }, 2859 { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "Indische Zeit", "+5:30" }, 2860 { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "Indien Zeit", "Asia/Calcutta" }, 2861 { "de", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "Indische Zeit", "Asia/Calcutta" }, 2862 2863 // ========== 2864 2865 { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, 2866 { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" }, 2867 { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "America/Los_Angeles" }, 2868 { "zh", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u6807\\u51c6\\u65f6\\u95f4", "America/Los_Angeles" }, 2869 { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" }, 2870 { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" }, 2871 { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "America/Los_Angeles" }, 2872 { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u590f\\u4ee4\\u65f6\\u95f4", "America/Los_Angeles" }, 2873 // icu zh.txt has exemplar city for this time zone 2874 { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u6D1B\\u6749\\u77F6\\u65F6\\u95F4", "America/Los_Angeles" }, 2875 { "zh", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u5317\\u7f8e\\u592a\\u5e73\\u6d0b\\u65f6\\u95f4", "America/Los_Angeles" }, 2876 2877 { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2878 { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2879 { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2880 { "zh", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" }, 2881 { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2882 { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2883 { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2884 { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" }, 2885 { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u5E03\\u5B9C\\u8BFA\\u65AF\\u827E\\u5229\\u65AF\\u65F6\\u95F4", "America/Buenos_Aires" }, 2886 { "zh", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "America/Buenos_Aires" }, 2887 2888 { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2889 { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2890 { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2891 { "zh", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" }, 2892 { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2893 { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2894 { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2895 { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "-3:00" }, 2896 { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u5E03\\u5B9C\\u8BFA\\u65AF\\u827E\\u5229\\u65AF\\u65F6\\u95F4", "America/Buenos_Aires" }, 2897 { "zh", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u963f\\u6839\\u5ef7\\u6807\\u51c6\\u65f6\\u95f4", "America/Buenos_Aires" }, 2898 2899 { "zh", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" }, 2900 { "zh", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" }, 2901 { "zh", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" }, 2902 { "zh", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u53e4\\u5df4\\u6807\\u51c6\\u65f6\\u95f4", "-5:00" }, 2903 { "zh", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" }, 2904 { "zh", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" }, 2905 { "zh", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" }, 2906 { "zh", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u53e4\\u5df4\\u590f\\u4ee4\\u65f6\\u95f4", "-4:00" }, 2907 { "zh", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u53e4\\u5df4\\u65f6\\u95f4", "America/Havana" }, 2908 { "zh", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u53e4\\u5df4\\u65f6\\u95f4", "America/Havana" }, 2909 2910 { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 2911 { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, 2912 { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, 2913 { "zh", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u590f\\u4ee4\\u65f6\\u95f4", "+11:00" }, 2914 { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 2915 { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, 2916 { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, 2917 { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u6807\\u51c6\\u65f6\\u95f4", "+10:00" }, 2918 // icu zh.txt does not have info for this time zone 2919 { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u6089\\u5C3C\\u65F6\\u95F4", "Australia/Sydney" }, 2920 { "zh", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u65f6\\u95f4", "Australia/Sydney" }, 2921 2922 { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 2923 { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, 2924 { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, 2925 { "zh", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u590f\\u4ee4\\u65f6\\u95f4", "+11:00" }, 2926 { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 2927 { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, 2928 { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, 2929 { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u6807\\u51c6\\u65f6\\u95f4", "+10:00" }, 2930 { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u6089\\u5C3C\\u65F6\\u95F4", "Australia/Sydney" }, 2931 { "zh", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u6fb3\\u5927\\u5229\\u4e9a\\u4e1c\\u90e8\\u65f6\\u95f4", "Australia/Sydney" }, 2932 2933 { "zh", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" }, 2934 { "zh", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" }, 2935 { "zh", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" }, 2936 { "zh", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" }, 2937 { "zh", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" }, 2938 { "zh", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u683C\\u6797\\u5C3C\\u6CBB\\u6807\\u51C6\\u65F6\\u95F4", "+0:00" }, 2939 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" }, 2940 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" }, 2941 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" }, 2942 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u82f1\\u56fd\\u590f\\u4ee4\\u65f6\\u95f4", "+1:00" }, 2943 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" }, 2944 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" }, 2945 { "zh", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "\\u82f1\\u56fd\\u65f6\\u95f4", "Europe/London" }, 2946 2947 { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2948 { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2949 { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2950 { "zh", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 2951 { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2952 { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2953 { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2954 { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 2955 { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" }, 2956 { "zh", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" }, 2957 2958 // JB#5150 2959 { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" }, 2960 { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, 2961 { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" }, 2962 { "zh", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u5370\\u5ea6\\u65f6\\u95f4", "+5:30" }, 2963 { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" }, 2964 { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, 2965 { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" }, 2966 { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u5370\\u5ea6\\u65f6\\u95f4", "+5:30" }, 2967 { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u5370\\u5ea6\\u65f6\\u95f4", "Asia/Calcutta" }, 2968 { "zh", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u5370\\u5ea6\\u65f6\\u95f4", "Asia/Calcutta" }, 2969 2970 // ========== 2971 2972 { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, 2973 { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" }, 2974 { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "-8:00" }, 2975 { "hi", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u0909\\u0924\\u094d\\u0924\\u0930\\u0940 \\u0905\\u092e\\u0947\\u0930\\u093f\\u0915\\u0940 \\u092a\\u094d\\u0930\\u0936\\u093e\\u0902\\u0924 \\u092e\\u093e\\u0928\\u0915 \\u0938\\u092e\\u092f", "-8:00" }, 2976 { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" }, 2977 { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" }, 2978 { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "-7:00" }, 2979 { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u0909\\u0924\\u094d\\u0924\\u0930\\u0940 \\u0905\\u092e\\u0947\\u0930\\u093f\\u0915\\u0940 \\u092a\\u094d\\u0930\\u0936\\u093e\\u0902\\u0924 \\u0921\\u0947\\u0932\\u093e\\u0907\\u091f \\u0938\\u092e\\u092f", "-7:00" }, 2980 { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u0932\\u0949\\u0938 \\u090f\\u0902\\u091c\\u093f\\u0932\\u094d\\u0938 \\u0938\\u092e\\u092f", "America/Los_Angeles" }, 2981 { "hi", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u0909\\u0924\\u094d\\u0924\\u0930\\u0940 \\u0905\\u092e\\u0947\\u0930\\u093f\\u0915\\u0940 \\u092a\\u094d\\u0930\\u0936\\u093e\\u0902\\u0924 \\u0938\\u092e\\u092f", "America/Los_Angeles" }, 2982 2983 { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2984 { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2985 { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2986 { "hi", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u0905\\u0930\\u094D\\u091C\\u0947\\u0902\\u091F\\u0940\\u0928\\u093E \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "-3:00" }, 2987 { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2988 { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2989 { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2990 { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u0905\\u0930\\u094D\\u091C\\u0947\\u0902\\u091F\\u0940\\u0928\\u093E \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "-3:00" }, 2991 { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u092C\\u094D\\u092F\\u0942\\u0928\\u0938 \\u0906\\u092F\\u0930\\u0938 \\u0938\\u092E\\u092F", "America/Buenos_Aires" }, 2992 { "hi", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u0905\\u0930\\u094D\\u091C\\u0947\\u0902\\u091F\\u0940\\u0928\\u093E \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "America/Buenos_Aires" }, 2993 2994 { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2995 { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 2996 { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 2997 { "hi", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u0905\\u0930\\u094D\\u091C\\u0947\\u0902\\u091F\\u0940\\u0928\\u093E \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "-3:00" }, 2998 { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 2999 { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3000 { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3001 { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u0905\\u0930\\u094D\\u091C\\u0947\\u0902\\u091F\\u0940\\u0928\\u093E \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "-3:00" }, 3002 { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u092C\\u094D\\u092F\\u0942\\u0928\\u0938 \\u0906\\u092F\\u0930\\u0938 \\u0938\\u092E\\u092F", "America/Buenos_Aires" }, 3003 { "hi", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u0905\\u0930\\u094D\\u091C\\u0947\\u0902\\u091F\\u0940\\u0928\\u093E \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "America/Buenos_Aires" }, 3004 3005 { "hi", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" }, 3006 { "hi", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" }, 3007 { "hi", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" }, 3008 { "hi", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u092e\\u093e\\u0928\\u0915 \\u0938\\u092e\\u092f", "-5:00" }, 3009 { "hi", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" }, 3010 { "hi", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" }, 3011 { "hi", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" }, 3012 { "hi", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0921\\u0947\\u0932\\u093e\\u0907\\u091f \\u0938\\u092e\\u092f", "-4:00" }, 3013 { "hi", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0938\\u092E\\u092F", "America/Havana" }, 3014 { "hi", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u0915\\u094d\\u092f\\u0942\\u092c\\u093e \\u0938\\u092e\\u092f", "America/Havana" }, 3015 3016 { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 3017 { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, 3018 { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, 3019 { "hi", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094d\\u200d\\u091f\\u094d\\u0930\\u0947\\u0932\\u093f\\u092f\\u093e\\u0908 \\u092a\\u0942\\u0930\\u094d\\u0935\\u0940 \\u0921\\u0947\\u0932\\u093e\\u0907\\u091f \\u0938\\u092e\\u092f", "+11:00" }, 3020 { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 3021 { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, 3022 { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, 3023 { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094d\\u200d\\u091f\\u094d\\u0930\\u0947\\u0932\\u093f\\u092f\\u093e\\u0908 \\u092a\\u0942\\u0930\\u094d\\u0935\\u0940 \\u092e\\u093e\\u0928\\u0915 \\u0938\\u092e\\u092f", "+10:00" }, 3024 { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u0938\\u093F\\u0921\\u0928\\u0940 \\u0938\\u092E\\u092F", "Australia/Sydney" }, 3025 { "hi", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u092a\\u0942\\u0930\\u094d\\u0935\\u0940 \\u0911\\u0938\\u094d\\u091f\\u094d\\u0930\\u0947\\u0932\\u093f\\u092f\\u093e \\u0938\\u092e\\u092f", "Australia/Sydney" }, 3026 3027 { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 3028 { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, 3029 { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, 3030 { "hi", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094d\\u200d\\u091f\\u094d\\u0930\\u0947\\u0932\\u093f\\u092f\\u093e\\u0908 \\u092a\\u0942\\u0930\\u094d\\u0935\\u0940 \\u0921\\u0947\\u0932\\u093e\\u0907\\u091f \\u0938\\u092e\\u092f", "+11:00" }, 3031 { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 3032 { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, 3033 { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, 3034 { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u0911\\u0938\\u094d\\u200d\\u091f\\u094d\\u0930\\u0947\\u0932\\u093f\\u092f\\u093e\\u0908 \\u092a\\u0942\\u0930\\u094d\\u0935\\u0940 \\u092e\\u093e\\u0928\\u0915 \\u0938\\u092e\\u092f", "+10:00" }, 3035 { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u0938\\u093F\\u0921\\u0928\\u0940 \\u0938\\u092E\\u092F", "Australia/Sydney" }, 3036 { "hi", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u092a\\u0942\\u0930\\u094d\\u0935\\u0940 \\u0911\\u0938\\u094d\\u091f\\u094d\\u0930\\u0947\\u0932\\u093f\\u092f\\u093e \\u0938\\u092e\\u092f", "Australia/Sydney" }, 3037 3038 { "hi", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" }, 3039 { "hi", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" }, 3040 { "hi", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" }, 3041 { "hi", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u0917\\u094d\\u0930\\u0940\\u0928\\u0935\\u093f\\u091a \\u092e\\u0940\\u0928 \\u091f\\u093e\\u0907\\u092e", "+0:00" }, 3042 { "hi", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" }, 3043 { "hi", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" }, 3044 { "hi", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" }, 3045 { "hi", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u092c\\u094d\\u0930\\u093f\\u091f\\u093f\\u0936 \\u0917\\u094d\\u0930\\u0940\\u0937\\u094d\\u092e\\u0915\\u093e\\u0932\\u0940\\u0928 \\u0938\\u092e\\u092f", "+1:00" }, 3046 { "hi", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u092f\\u0942\\u0928\\u093e\\u0907\\u091f\\u0947\\u0921 \\u0915\\u093f\\u0902\\u0917\\u0921\\u092e \\u0938\\u092e\\u092f", "Europe/London" }, 3047 { "hi", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u092f\\u0942\\u0928\\u093e\\u0907\\u091f\\u0947\\u0921 \\u0915\\u093f\\u0902\\u0917\\u0921\\u092e \\u0938\\u092e\\u092f", "Europe/London" }, 3048 3049 { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3050 { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3051 { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3052 { "hi", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 3053 { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3054 { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3055 { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3056 { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 3057 { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" }, 3058 { "hi", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" }, 3059 3060 { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" }, 3061 { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, 3062 { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "IST", "+5:30" }, 3063 { "hi", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "+5:30" }, 3064 { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" }, 3065 { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, 3066 { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "IST", "+05:30" }, 3067 { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "+5:30" }, 3068 { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "IST", "Asia/Calcutta" }, 3069 { "hi", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u092D\\u093E\\u0930\\u0924\\u0940\\u092F \\u092E\\u093E\\u0928\\u0915 \\u0938\\u092E\\u092F", "Asia/Calcutta" }, 3070 3071 // ========== 3072 3073 { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, 3074 { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-08:00", "-8:00" }, 3075 { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-8", "America/Los_Angeles" }, 3076 { "bg", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u0421\\u0435\\u0432\\u0435\\u0440\\u043d\\u043e\\u0430\\u043c\\u0435\\u0440\\u0438\\u043a\\u0430\\u043d\\u0441\\u043a\\u043e \\u0442\\u0438\\u0445\\u043e\\u043e\\u043a\\u0435\\u0430\\u043d\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Los_Angeles" }, 3077 { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" }, 3078 { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-07:00", "-7:00" }, 3079 { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-7", "America/Los_Angeles" }, 3080 { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u0421\\u0435\\u0432\\u0435\\u0440\\u043d\\u043e\\u0430\\u043c\\u0435\\u0440\\u0438\\u043a\\u0430\\u043d\\u0441\\u043a\\u043e \\u0442\\u0438\\u0445\\u043e\\u043e\\u043a\\u0435\\u0430\\u043d\\u0441\\u043a\\u043e \\u043b\\u044f\\u0442\\u043d\\u043e \\u0447\\u0430\\u0441\\u043e\\u0432\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Los_Angeles" }, 3081 // icu bg.txt has exemplar city for this time zone 3082 { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u041B\\u043E\\u0441 \\u0410\\u043D\\u0434\\u0436\\u0435\\u043B\\u0438\\u0441", "America/Los_Angeles" }, 3083 { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u0421\\u0435\\u0432\\u0435\\u0440\\u043d\\u043e\\u0430\\u043c\\u0435\\u0440\\u0438\\u043a\\u0430\\u043d\\u0441\\u043a\\u043e \\u0442\\u0438\\u0445\\u043e\\u043e\\u043a\\u0435\\u0430\\u043d\\u0441\\u043a\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Los_Angeles" }, 3084 { "bg", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "\\u041B\\u043E\\u0441 \\u0410\\u043D\\u0434\\u0436\\u0435\\u043B\\u0438\\u0441", "America/Los_Angeles" }, 3085 3086 { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3087 { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, 3088 { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, 3089 { "bg", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" }, 3090 { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3091 { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, 3092 { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, 3093 { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" }, 3094 { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u0411\\u0443\\u0435\\u043D\\u043E\\u0441 \\u0410\\u0439\\u0440\\u0435\\u0441", "America/Buenos_Aires" }, 3095 { "bg", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Buenos_Aires" }, 3096 3097 { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3098 { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, 3099 { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, 3100 { "bg", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" }, 3101 { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3102 { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, 3103 { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, 3104 { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-3:00" }, 3105 // icu bg.txt does not have info for this time zone 3106 { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u0411\\u0443\\u0435\\u043D\\u043E\\u0441 \\u0410\\u0439\\u0440\\u0435\\u0441", "America/Buenos_Aires" }, 3107 { "bg", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u0410\\u0440\\u0436\\u0435\\u043D\\u0442\\u0438\\u043D\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "America/Buenos_Aires" }, 3108 3109 { "bg", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" }, 3110 { "bg", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-05:00", "-5:00" }, 3111 { "bg", "America/Havana", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-5", "-5:00" }, 3112 { "bg", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u041a\\u0443\\u0431\\u0438\\u043d\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043d\\u0434\\u0430\\u0440\\u0442\\u043d\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-5:00" }, 3113 { "bg", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" }, 3114 { "bg", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-04:00", "-4:00" }, 3115 { "bg", "America/Havana", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-4", "-4:00" }, 3116 { "bg", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u041a\\u0443\\u0431\\u0438\\u043d\\u0441\\u043a\\u043e \\u043b\\u044f\\u0442\\u043d\\u043e \\u0447\\u0430\\u0441\\u043e\\u0432\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "-4:00" }, 3117 { "bg", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u041a\\u0443\\u0431\\u0430", "America/Havana" }, 3118 { "bg", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u041a\\u0443\\u0431\\u0438\\u043d\\u0441\\u043a\\u043e \\u0432\\u0440\\u0435\\u043C\\u0435", "America/Havana" }, 3119 3120 { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 3121 { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11:00", "+11:00" }, 3122 { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11", "+11:00" }, 3123 { "bg", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u0410\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u044F \\u2013 \\u0438\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E \\u043B\\u044F\\u0442\\u043D\\u043E \\u0447\\u0430\\u0441\\u043E\\u0432\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "+11:00" }, 3124 { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 3125 { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10:00", "+10:00" }, 3126 { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10", "+10:00" }, 3127 { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u0410\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u044F \\u2013 \\u0438\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E \\u0441\\u0442\\u0430\\u043D\\u0434\\u0430\\u0440\\u0442\\u043D\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "+10:00" }, 3128 { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u0421\\u0438\\u0434\\u043D\\u0438", "Australia/Sydney" }, 3129 { "bg", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u0410\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u044F \\u2013 \\u0438\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "Australia/Sydney" }, 3130 3131 { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 3132 { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11:00", "+11:00" }, 3133 { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+11", "+11:00" }, 3134 { "bg", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u0410\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u044F \\u2013 \\u0438\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E \\u043B\\u044F\\u0442\\u043D\\u043E \\u0447\\u0430\\u0441\\u043E\\u0432\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "+11:00" }, 3135 { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 3136 { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10:00", "+10:00" }, 3137 { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+10", "+10:00" }, 3138 { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u0410\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u044F \\u2013 \\u0438\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E \\u0441\\u0442\\u0430\\u043D\\u0434\\u0430\\u0440\\u0442\\u043D\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "+10:00" }, 3139 { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u0421\\u0438\\u0434\\u043D\\u0438", "Australia/Sydney" }, 3140 { "bg", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u0410\\u0432\\u0441\\u0442\\u0440\\u0430\\u043B\\u0438\\u044F \\u2013 \\u0438\\u0437\\u0442\\u043E\\u0447\\u043D\\u043E \\u0432\\u0440\\u0435\\u043C\\u0435", "Australia/Sydney" }, 3141 3142 { "bg", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" }, 3143 { "bg", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" }, 3144 { "bg", "Europe/London", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447", "+0:00" }, 3145 { "bg", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u0421\\u0440\\u0435\\u0434\\u043d\\u043e \\u0433\\u0440\\u0438\\u043d\\u0443\\u0438\\u0447\\u043a\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "+0:00" }, 3146 { "bg", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" }, 3147 { "bg", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+01:00", "+1:00" }, 3148 { "bg", "Europe/London", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+1", "+1:00" }, 3149 { "bg", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u0411\\u0440\\u0438\\u0442\\u0430\\u043d\\u0441\\u043a\\u043e \\u043b\\u044f\\u0442\\u043d\\u043e \\u0447\\u0430\\u0441\\u043e\\u0432\\u043e \\u0432\\u0440\\u0435\\u043c\\u0435", "+1:00" }, 3150 { "bg", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u041E\\u0431\\u0435\\u0434\\u0438\\u043D\\u0435\\u043D\\u043E\\u0442\\u043E \\u043A\\u0440\\u0430\\u043B\\u0441\\u0442\\u0432\\u043E", "Europe/London" }, 3151 { "bg", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u041E\\u0431\\u0435\\u0434\\u0438\\u043D\\u0435\\u043D\\u043E\\u0442\\u043E \\u043A\\u0440\\u0430\\u043B\\u0441\\u0442\\u0432\\u043E", "Europe/London" }, 3152 3153 { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3154 { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, 3155 { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, 3156 { "bg", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, 3157 { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3158 { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, 3159 { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, 3160 { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, 3161 { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-3", "-3:00" }, 3162 { "bg", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447-03:00", "-3:00" }, 3163 3164 // JB#5150 3165 { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" }, 3166 { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+05:30", "+5:30" }, 3167 { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+5:30", "+5:30" }, 3168 { "bg", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u0418\\u043d\\u0434\\u0438\\u0439\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043D\\u0434\\u0430\\u0440\\u0442\\u043D\\u043E \\u0432\\u0440\\u0435\\u043c\\u0435", "+5:30" }, 3169 { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" }, 3170 { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+05:30", "+5:30" }, 3171 { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "\\u0413\\u0440\\u0438\\u043D\\u0443\\u0438\\u0447+5:30", "+05:30" }, 3172 { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u0418\\u043d\\u0434\\u0438\\u0439\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043D\\u0434\\u0430\\u0440\\u0442\\u043D\\u043E \\u0432\\u0440\\u0435\\u043c\\u0435", "+5:30" }, 3173 { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u0418\\u043D\\u0434\\u0438\\u044F", "Asia/Calcutta" }, 3174 { "bg", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u0418\\u043d\\u0434\\u0438\\u0439\\u0441\\u043a\\u043e \\u0441\\u0442\\u0430\\u043D\\u0434\\u0430\\u0440\\u0442\\u043D\\u043E \\u0432\\u0440\\u0435\\u043c\\u0435", "Asia/Calcutta" }, 3175 // ========== 3176 3177 { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, 3178 { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" }, 3179 { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "America/Los_Angeles" }, 3180 { "ja", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "\\u30a2\\u30e1\\u30ea\\u30ab\\u592a\\u5e73\\u6d0b\\u6a19\\u6e96\\u6642", "America/Los_Angeles" }, 3181 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-700" }, 3182 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" }, 3183 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "America/Los_Angeles" }, 3184 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "\\u30a2\\u30e1\\u30ea\\u30ab\\u592a\\u5e73\\u6d0b\\u590f\\u6642\\u9593", "America/Los_Angeles" }, 3185 // icu ja.txt has exemplar city for this time zone 3186 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "\\u30ED\\u30B5\\u30F3\\u30BC\\u30EB\\u30B9\\u6642\\u9593", "America/Los_Angeles" }, 3187 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "\\u30A2\\u30E1\\u30EA\\u30AB\\u592A\\u5e73\\u6D0B\\u6642\\u9593", "America/Los_Angeles" }, 3188 { "ja", "America/Los_Angeles", "2004-07-15T00:00:00Z", "VVVV", "\\u30ED\\u30B5\\u30F3\\u30BC\\u30EB\\u30B9\\u6642\\u9593", "America/Los_Angeles" }, 3189 3190 { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3191 { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3192 { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3193 { "ja", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" }, 3194 { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3195 { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3196 { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3197 { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" }, 3198 // icu ja.txt does not have info for this time zone 3199 { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u30D6\\u30A8\\u30CE\\u30B9\\u30A2\\u30A4\\u30EC\\u30B9\\u6642\\u9593", "America/Buenos_Aires" }, 3200 { "ja", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "America/Buenos_Aires" }, 3201 3202 { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3203 { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3204 { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3205 { "ja", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" }, 3206 { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3207 { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3208 { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3209 { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "-3:00" }, 3210 { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "\\u30D6\\u30A8\\u30CE\\u30B9\\u30A2\\u30A4\\u30EC\\u30B9\\u6642\\u9593", "America/Buenos_Aires" }, 3211 { "ja", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "\\u30A2\\u30EB\\u30BC\\u30F3\\u30C1\\u30F3\\u6A19\\u6E96\\u6642", "America/Buenos_Aires" }, 3212 3213 { "ja", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" }, 3214 { "ja", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" }, 3215 { "ja", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" }, 3216 { "ja", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "\\u30AD\\u30E5\\u30FC\\u30D0\\u6A19\\u6E96\\u6642", "-5:00" }, 3217 { "ja", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" }, 3218 { "ja", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" }, 3219 { "ja", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" }, 3220 { "ja", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "\\u30AD\\u30E5\\u30FC\\u30D0\\u590F\\u6642\\u9593", "-4:00" }, 3221 { "ja", "America/Havana", "2004-07-15T00:00:00Z", "v", "\\u30ad\\u30e5\\u30fc\\u30d0\\u6642\\u9593", "America/Havana" }, 3222 { "ja", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "\\u30ad\\u30e5\\u30fc\\u30d0\\u6642\\u9593", "America/Havana" }, 3223 3224 { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 3225 { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, 3226 { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, 3227 { "ja", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u590F\\u6642\\u9593", "+11:00" }, 3228 { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 3229 { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, 3230 { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, 3231 { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6A19\\u6E96\\u6642", "+10:00" }, 3232 // icu ja.txt does not have info for this time zone 3233 { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "\\u30B7\\u30C9\\u30CB\\u30FC\\u6642\\u9593", "Australia/Sydney" }, 3234 { "ja", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6642\\u9593", "Australia/Sydney" }, 3235 3236 { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 3237 { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, 3238 { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, 3239 { "ja", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u590F\\u6642\\u9593", "+11:00" }, 3240 { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 3241 { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, 3242 { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, 3243 { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6A19\\u6E96\\u6642", "+10:00" }, 3244 { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "\\u30B7\\u30C9\\u30CB\\u30FC\\u6642\\u9593", "Australia/Sydney" }, 3245 { "ja", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "\\u30AA\\u30FC\\u30B9\\u30C8\\u30E9\\u30EA\\u30A2\\u6771\\u90E8\\u6642\\u9593", "Australia/Sydney" }, 3246 3247 { "ja", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" }, 3248 { "ja", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" }, 3249 { "ja", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" }, 3250 { "ja", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "\\u30B0\\u30EA\\u30CB\\u30C3\\u30B8\\u6A19\\u6E96\\u6642", "+0:00" }, 3251 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" }, 3252 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" }, 3253 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" }, 3254 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "\\u82f1\\u56fd\\u590f\\u6642\\u9593", "+1:00" }, 3255 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "v", "\\u30a4\\u30ae\\u30ea\\u30b9\\u6642\\u9593", "Europe/London" }, 3256 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "\\u30a4\\u30ae\\u30ea\\u30b9\\u6642\\u9593", "Europe/London" }, 3257 { "ja", "Europe/London", "2004-07-15T00:00:00Z", "VVVV", "\\u30a4\\u30ae\\u30ea\\u30b9\\u6642\\u9593", "Europe/London" }, 3258 3259 { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3260 { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3261 { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3262 { "ja", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 3263 { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3264 { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3265 { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3266 { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 3267 { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" }, 3268 { "ja", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" }, 3269 3270 // JB#5150 3271 { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" }, 3272 { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, 3273 { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" }, 3274 { "ja", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "\\u30A4\\u30F3\\u30C9\\u6A19\\u6E96\\u6642", "+5:30" }, 3275 { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" }, 3276 { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, 3277 { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" }, 3278 { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "\\u30A4\\u30F3\\u30C9\\u6A19\\u6E96\\u6642", "+5:30" }, 3279 { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "\\u30A4\\u30F3\\u30C9\\u6642\\u9593", "Asia/Calcutta" }, 3280 { "ja", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "\\u30A4\\u30F3\\u30C9\\u6A19\\u6E96\\u6642", "Asia/Calcutta" }, 3281 3282 // ========== 3283 3284 { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "Z", "-0800", "-8:00" }, 3285 { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-08:00", "-8:00" }, 3286 { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "z", "GMT-8", "-8:00" }, 3287 { "ti", "America/Los_Angeles", "2004-01-15T00:00:00Z", "zzzz", "GMT-08:00", "-8:00" }, 3288 { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "Z", "-0700", "-7:00" }, 3289 { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-07:00", "-7:00" }, 3290 { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "z", "GMT-7", "-7:00" }, 3291 { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "zzzz", "GMT-07:00", "-7:00" }, 3292 { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "v", "Los Angeles", "America/Los_Angeles" }, 3293 { "ti", "America/Los_Angeles", "2004-07-15T00:00:00Z", "vvvv", "Los Angeles", "America/Los_Angeles" }, 3294 3295 { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3296 { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3297 { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3298 { "ti", "America/Argentina/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 3299 { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3300 { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3301 { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3302 { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 3303 { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires", "America/Buenos_Aires" }, 3304 { "ti", "America/Argentina/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Buenos Aires", "America/Buenos_Aires" }, 3305 3306 { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3307 { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3308 { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3309 { "ti", "America/Buenos_Aires", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 3310 { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3311 { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3312 { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3313 { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 3314 { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "v", "Buenos Aires", "America/Buenos_Aires" }, 3315 { "ti", "America/Buenos_Aires", "2004-07-15T00:00:00Z", "vvvv", "Buenos Aires", "America/Buenos_Aires" }, 3316 3317 { "ti", "America/Havana", "2004-01-15T00:00:00Z", "Z", "-0500", "-5:00" }, 3318 { "ti", "America/Havana", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-05:00", "-5:00" }, 3319 { "ti", "America/Havana", "2004-01-15T00:00:00Z", "z", "GMT-5", "-5:00" }, 3320 { "ti", "America/Havana", "2004-01-15T00:00:00Z", "zzzz", "GMT-05:00", "-5:00" }, 3321 { "ti", "America/Havana", "2004-07-15T00:00:00Z", "Z", "-0400", "-4:00" }, 3322 { "ti", "America/Havana", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-04:00", "-4:00" }, 3323 { "ti", "America/Havana", "2004-07-15T00:00:00Z", "z", "GMT-4", "-4:00" }, 3324 { "ti", "America/Havana", "2004-07-15T00:00:00Z", "zzzz", "GMT-04:00", "-4:00" }, 3325 { "ti", "America/Havana", "2004-07-15T00:00:00Z", "v", "CU", "America/Havana" }, 3326 { "ti", "America/Havana", "2004-07-15T00:00:00Z", "vvvv", "CU", "America/Havana" }, 3327 3328 { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 3329 { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, 3330 { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, 3331 { "ti", "Australia/ACT", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" }, 3332 { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 3333 { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, 3334 { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, 3335 { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" }, 3336 { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "v", "Sydney", "Australia/Sydney" }, 3337 { "ti", "Australia/ACT", "2004-07-15T00:00:00Z", "vvvv", "Sydney", "Australia/Sydney" }, 3338 3339 { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "Z", "+1100", "+11:00" }, 3340 { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+11:00", "+11:00" }, 3341 { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "z", "GMT+11", "+11:00" }, 3342 { "ti", "Australia/Sydney", "2004-01-15T00:00:00Z", "zzzz", "GMT+11:00", "+11:00" }, 3343 { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "Z", "+1000", "+10:00" }, 3344 { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+10:00", "+10:00" }, 3345 { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "z", "GMT+10", "+10:00" }, 3346 { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "zzzz", "GMT+10:00", "+10:00" }, 3347 { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "v", "Sydney", "Australia/Sydney" }, 3348 { "ti", "Australia/Sydney", "2004-07-15T00:00:00Z", "vvvv", "Sydney", "Australia/Sydney" }, 3349 3350 { "ti", "Europe/London", "2004-01-15T00:00:00Z", "Z", "+0000", "+0:00" }, 3351 { "ti", "Europe/London", "2004-01-15T00:00:00Z", "ZZZZ", "GMT", "+0:00" }, 3352 { "ti", "Europe/London", "2004-01-15T00:00:00Z", "z", "GMT", "+0:00" }, 3353 { "ti", "Europe/London", "2004-01-15T00:00:00Z", "zzzz", "GMT", "+0:00" }, 3354 { "ti", "Europe/London", "2004-07-15T00:00:00Z", "Z", "+0100", "+1:00" }, 3355 { "ti", "Europe/London", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+01:00", "+1:00" }, 3356 { "ti", "Europe/London", "2004-07-15T00:00:00Z", "z", "GMT+1", "+1:00" }, 3357 { "ti", "Europe/London", "2004-07-15T00:00:00Z", "zzzz", "GMT+01:00", "+1:00" }, 3358 { "ti", "Europe/London", "2004-07-15T00:00:00Z", "v", "GB", "Europe/London" }, 3359 { "ti", "Europe/London", "2004-07-15T00:00:00Z", "vvvv", "GB", "Europe/London" }, 3360 3361 { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3362 { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3363 { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3364 { "ti", "Etc/GMT+3", "2004-01-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 3365 { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "Z", "-0300", "-3:00" }, 3366 { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "ZZZZ", "GMT-03:00", "-3:00" }, 3367 { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "z", "GMT-3", "-3:00" }, 3368 { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "zzzz", "GMT-03:00", "-3:00" }, 3369 { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "v", "GMT-3", "-3:00" }, 3370 { "ti", "Etc/GMT+3", "2004-07-15T00:00:00Z", "vvvv", "GMT-03:00", "-3:00" }, 3371 3372 // JB#5150 3373 { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "Z", "+0530", "+5:30" }, 3374 { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, 3375 { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "z", "GMT+5:30", "+5:30" }, 3376 { "ti", "Asia/Calcutta", "2004-01-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" }, 3377 { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "Z", "+0530", "+5:30" }, 3378 { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "ZZZZ", "GMT+05:30", "+5:30" }, 3379 { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "z", "GMT+5:30", "+05:30" }, 3380 { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "zzzz", "GMT+05:30", "+5:30" }, 3381 { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "v", "IN", "Alna/Calcutta" }, 3382 { "ti", "Asia/Calcutta", "2004-07-15T00:00:00Z", "vvvv", "IN", "Asia/Calcutta" }, 3383 3384 // Ticket#8589 Partial location name to use country name if the zone is the golden 3385 // zone for the time zone's country. 3386 { "en_MX", "America/Chicago", "1995-07-15T00:00:00Z", "vvvv", "Central Time (United States)", "America/Chicago"}, 3387 3388 // Tests proper handling of time zones that should have empty sets when inherited from the parent. 3389 // For example, en_GB understands CET as Central European Time, but en_HK, which inherits from en_GB 3390 // does not 3391 { "en_GB", "Europe/Paris", "2004-01-15T00:00:00Z", "zzzz", "Central European Standard Time", "+1:00"}, 3392 { "en_GB", "Europe/Paris", "2004-07-15T00:00:00Z", "zzzz", "Central European Summer Time", "+2:00"}, 3393 { "en_GB", "Europe/Paris", "2004-01-15T00:00:00Z", "z", "CET", "+1:00"}, 3394 { "en_GB", "Europe/Paris", "2004-07-15T00:00:00Z", "z", "CEST", "+2:00"}, 3395 { "en_HK", "Europe/Paris", "2004-01-15T00:00:00Z", "zzzz", "Central European Standard Time", "+1:00"}, 3396 { "en_HK", "Europe/Paris", "2004-07-15T00:00:00Z", "zzzz", "Central European Summer Time", "+2:00"}, 3397 { "en_HK", "Europe/Paris", "2004-01-15T00:00:00Z", "z", "GMT+1", "+1:00"}, 3398 { "en_HK", "Europe/Paris", "2004-07-15T00:00:00Z", "z", "GMT+2", "+2:00"}, 3399 3400 { NULL, NULL, NULL, NULL, NULL, NULL }, 3401 }; 3402 3403 UErrorCode status = U_ZERO_ERROR; 3404 Calendar *cal = GregorianCalendar::createInstance(status); 3405 if (failure(status, "GregorianCalendar::createInstance", TRUE)) return; 3406 SimpleDateFormat testfmt(UnicodeString("yyyy-MM-dd'T'HH:mm:ss'Z'"), status); 3407 if (failure(status, "SimpleDateFormat constructor", TRUE)) return; 3408 testfmt.setTimeZone(*TimeZone::getGMT()); 3409 3410 for (int i = 0; fallbackTests[i][0]; i++) { 3411 const char **testLine = fallbackTests[i]; 3412 UnicodeString info[5]; 3413 for ( int j = 0 ; j < 5 ; j++ ) { 3414 info[j] = UnicodeString(testLine[j], -1, US_INV); 3415 } 3416 info[4] = info[4].unescape(); 3417 logln("%s;%s;%s;%s", testLine[0], testLine[1], testLine[2], testLine[3]); 3418 3419 TimeZone *tz = TimeZone::createTimeZone(info[1]); 3420 3421 UDate d = testfmt.parse(testLine[2], status); 3422 cal->setTime(d, status); 3423 if (U_FAILURE(status)) { 3424 errln(UnicodeString("Failed to set date: ") + testLine[2]); 3425 } 3426 3427 SimpleDateFormat fmt(info[3], Locale(testLine[0]),status); 3428 ASSERT_OK(status); 3429 cal->adoptTimeZone(tz); 3430 UnicodeString result; 3431 FieldPosition pos(FieldPosition::DONT_CARE); 3432 fmt.format(*cal,result,pos); 3433 if (result != info[4]) { 3434 errln(info[0] + ";" + info[1] + ";" + info[2] + ";" + info[3] + " expected: '" + 3435 info[4] + "' but got: '" + result + "'"); 3436 } 3437 } 3438 delete cal; 3439 } 3440 3441 void DateFormatTest::TestRoundtripWithCalendar(void) { 3442 UErrorCode status = U_ZERO_ERROR; 3443 3444 TimeZone *tz = TimeZone::createTimeZone("Europe/Paris"); 3445 TimeZone *gmt = TimeZone::createTimeZone("Etc/GMT"); 3446 3447 Calendar *calendars[] = { 3448 Calendar::createInstance(*tz, Locale("und@calendar=gregorian"), status), 3449 Calendar::createInstance(*tz, Locale("und@calendar=buddhist"), status), 3450 // Calendar::createInstance(*tz, Locale("und@calendar=hebrew"), status), 3451 Calendar::createInstance(*tz, Locale("und@calendar=islamic"), status), 3452 Calendar::createInstance(*tz, Locale("und@calendar=japanese"), status), 3453 NULL 3454 }; 3455 if (U_FAILURE(status)) { 3456 dataerrln("Failed to initialize calendars: %s", u_errorName(status)); 3457 for (int i = 0; calendars[i] != NULL; i++) { 3458 delete calendars[i]; 3459 } 3460 return; 3461 } 3462 3463 //FIXME The formatters commented out below are currently failing because of 3464 // the calendar calculation problem reported by #6691 3465 3466 // The order of test formatters must match the order of calendars above. 3467 DateFormat *formatters[] = { 3468 DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("en_US")), //calendar=gregorian 3469 DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("th_TH")), //calendar=buddhist 3470 // DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("he_IL@calendar=hebrew")), 3471 DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("ar_EG@calendar=islamic")), 3472 // DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, Locale("ja_JP@calendar=japanese")), 3473 NULL 3474 }; 3475 3476 UDate d = Calendar::getNow(); 3477 UnicodeString buf; 3478 FieldPosition fpos; 3479 ParsePosition ppos; 3480 3481 for (int i = 0; formatters[i] != NULL; i++) { 3482 buf.remove(); 3483 fpos.setBeginIndex(0); 3484 fpos.setEndIndex(0); 3485 calendars[i]->setTime(d, status); 3486 3487 // Normal case output - the given calendar matches the calendar 3488 // used by the formatter 3489 formatters[i]->format(*calendars[i], buf, fpos); 3490 UnicodeString refStr(buf); 3491 3492 for (int j = 0; calendars[j] != NULL; j++) { 3493 if (j == i) { 3494 continue; 3495 } 3496 buf.remove(); 3497 fpos.setBeginIndex(0); 3498 fpos.setEndIndex(0); 3499 calendars[j]->setTime(d, status); 3500 3501 // Even the different calendar type is specified, 3502 // we should get the same result. 3503 formatters[i]->format(*calendars[j], buf, fpos); 3504 if (refStr != buf) { 3505 errln((UnicodeString)"FAIL: Different format result with a different calendar for the same time -" 3506 + "\n Reference calendar type=" + calendars[i]->getType() 3507 + "\n Another calendar type=" + calendars[j]->getType() 3508 + "\n Expected result=" + refStr 3509 + "\n Actual result=" + buf); 3510 } 3511 } 3512 3513 calendars[i]->setTimeZone(*gmt); 3514 calendars[i]->clear(); 3515 ppos.setErrorIndex(-1); 3516 ppos.setIndex(0); 3517 3518 // Normal case parse result - the given calendar matches the calendar 3519 // used by the formatter 3520 formatters[i]->parse(refStr, *calendars[i], ppos); 3521 3522 for (int j = 0; calendars[j] != NULL; j++) { 3523 if (j == i) { 3524 continue; 3525 } 3526 calendars[j]->setTimeZone(*gmt); 3527 calendars[j]->clear(); 3528 ppos.setErrorIndex(-1); 3529 ppos.setIndex(0); 3530 3531 // Even the different calendar type is specified, 3532 // we should get the same time and time zone. 3533 formatters[i]->parse(refStr, *calendars[j], ppos); 3534 if (calendars[i]->getTime(status) != calendars[j]->getTime(status) 3535 || calendars[i]->getTimeZone() != calendars[j]->getTimeZone()) { 3536 UnicodeString tzid; 3537 errln((UnicodeString)"FAIL: Different parse result with a different calendar for the same string -" 3538 + "\n Reference calendar type=" + calendars[i]->getType() 3539 + "\n Another calendar type=" + calendars[j]->getType() 3540 + "\n Date string=" + refStr 3541 + "\n Expected time=" + calendars[i]->getTime(status) 3542 + "\n Expected time zone=" + calendars[i]->getTimeZone().getID(tzid) 3543 + "\n Actual time=" + calendars[j]->getTime(status) 3544 + "\n Actual time zone=" + calendars[j]->getTimeZone().getID(tzid)); 3545 } 3546 } 3547 if (U_FAILURE(status)) { 3548 errln((UnicodeString)"FAIL: " + u_errorName(status)); 3549 break; 3550 } 3551 } 3552 3553 delete tz; 3554 delete gmt; 3555 for (int i = 0; calendars[i] != NULL; i++) { 3556 delete calendars[i]; 3557 } 3558 for (int i = 0; formatters[i] != NULL; i++) { 3559 delete formatters[i]; 3560 } 3561 } 3562 3563 /* 3564 void DateFormatTest::TestRelativeError(void) 3565 { 3566 UErrorCode status; 3567 Locale en("en"); 3568 3569 DateFormat *en_reltime_reldate = DateFormat::createDateTimeInstance(DateFormat::kFullRelative,DateFormat::kFullRelative,en); 3570 if(en_reltime_reldate == NULL) { 3571 logln("PASS: rel date/rel time failed"); 3572 } else { 3573 errln("FAIL: rel date/rel time created, should have failed."); 3574 delete en_reltime_reldate; 3575 } 3576 } 3577 3578 void DateFormatTest::TestRelativeOther(void) 3579 { 3580 logln("Nothing in this test. When we get more data from CLDR, put in some tests of -2, +2, etc. "); 3581 } 3582 */ 3583 3584 void DateFormatTest::Test6338(void) 3585 { 3586 UErrorCode status = U_ZERO_ERROR; 3587 3588 SimpleDateFormat *fmt1 = new SimpleDateFormat(UnicodeString("y-M-d"), Locale("ar"), status); 3589 if (failure(status, "new SimpleDateFormat", TRUE)) return; 3590 3591 UDate dt1 = date(2008-1900, UCAL_JUNE, 10, 12, 00); 3592 UnicodeString str1; 3593 str1 = fmt1->format(dt1, str1); 3594 logln(str1); 3595 3596 UDate dt11 = fmt1->parse(str1, status); 3597 failure(status, "fmt->parse"); 3598 3599 UnicodeString str11; 3600 str11 = fmt1->format(dt11, str11); 3601 logln(str11); 3602 3603 if (str1 != str11) { 3604 errln((UnicodeString)"FAIL: Different dates str1:" + str1 3605 + " str2:" + str11); 3606 } 3607 delete fmt1; 3608 3609 ///////////////// 3610 3611 status = U_ZERO_ERROR; 3612 SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("y M d"), Locale("ar"), status); 3613 failure(status, "new SimpleDateFormat"); 3614 3615 UDate dt2 = date(2008-1900, UCAL_JUNE, 10, 12, 00); 3616 UnicodeString str2; 3617 str2 = fmt2->format(dt2, str2); 3618 logln(str2); 3619 3620 UDate dt22 = fmt2->parse(str2, status); 3621 failure(status, "fmt->parse"); 3622 3623 UnicodeString str22; 3624 str22 = fmt2->format(dt22, str22); 3625 logln(str22); 3626 3627 if (str2 != str22) { 3628 errln((UnicodeString)"FAIL: Different dates str1:" + str2 3629 + " str2:" + str22); 3630 } 3631 delete fmt2; 3632 3633 ///////////////// 3634 3635 status = U_ZERO_ERROR; 3636 SimpleDateFormat *fmt3 = new SimpleDateFormat(UnicodeString("y-M-d"), Locale("en-us"), status); 3637 failure(status, "new SimpleDateFormat"); 3638 3639 UDate dt3 = date(2008-1900, UCAL_JUNE, 10, 12, 00); 3640 UnicodeString str3; 3641 str3 = fmt3->format(dt3, str3); 3642 logln(str3); 3643 3644 UDate dt33 = fmt3->parse(str3, status); 3645 failure(status, "fmt->parse"); 3646 3647 UnicodeString str33; 3648 str33 = fmt3->format(dt33, str33); 3649 logln(str33); 3650 3651 if (str3 != str33) { 3652 errln((UnicodeString)"FAIL: Different dates str1:" + str3 3653 + " str2:" + str33); 3654 } 3655 delete fmt3; 3656 3657 ///////////////// 3658 3659 status = U_ZERO_ERROR; 3660 SimpleDateFormat *fmt4 = new SimpleDateFormat(UnicodeString("y M d"), Locale("en-us"), status); 3661 failure(status, "new SimpleDateFormat"); 3662 3663 UDate dt4 = date(2008-1900, UCAL_JUNE, 10, 12, 00); 3664 UnicodeString str4; 3665 str4 = fmt4->format(dt4, str4); 3666 logln(str4); 3667 3668 UDate dt44 = fmt4->parse(str4, status); 3669 failure(status, "fmt->parse"); 3670 3671 UnicodeString str44; 3672 str44 = fmt4->format(dt44, str44); 3673 logln(str44); 3674 3675 if (str4 != str44) { 3676 errln((UnicodeString)"FAIL: Different dates str1:" + str4 3677 + " str2:" + str44); 3678 } 3679 delete fmt4; 3680 3681 } 3682 3683 void DateFormatTest::Test6726(void) 3684 { 3685 // status 3686 // UErrorCode status = U_ZERO_ERROR; 3687 3688 // fmtf, fmtl, fmtm, fmts; 3689 UnicodeString strf, strl, strm, strs; 3690 UDate dt = date(2008-1900, UCAL_JUNE, 10, 12, 00); 3691 3692 Locale loc("ja"); 3693 DateFormat* fmtf = DateFormat::createDateTimeInstance(DateFormat::FULL, DateFormat::FULL, loc); 3694 DateFormat* fmtl = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::FULL, loc); 3695 DateFormat* fmtm = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL, loc); 3696 DateFormat* fmts = DateFormat::createDateTimeInstance(DateFormat::SHORT, DateFormat::FULL, loc); 3697 if (fmtf == NULL || fmtl == NULL || fmtm == NULL || fmts == NULL) { 3698 dataerrln("Unable to create DateFormat. got NULL."); 3699 /* It may not be true that if one is NULL all is NULL. Just to be safe. */ 3700 delete fmtf; 3701 delete fmtl; 3702 delete fmtm; 3703 delete fmts; 3704 3705 return; 3706 } 3707 strf = fmtf->format(dt, strf); 3708 strl = fmtl->format(dt, strl); 3709 strm = fmtm->format(dt, strm); 3710 strs = fmts->format(dt, strs); 3711 3712 3713 logln("strm.charAt(10)=%04X wanted 0x20\n", strm.charAt(10)); 3714 if (strm.charAt(10) != UChar(0x0020)) { 3715 errln((UnicodeString)"FAIL: Improper formatted date: " + strm ); 3716 } 3717 logln("strs.charAt(10)=%04X wanted 0x20\n", strs.charAt(8)); 3718 if (strs.charAt(10) != UChar(0x0020)) { 3719 errln((UnicodeString)"FAIL: Improper formatted date: " + strs); 3720 } 3721 3722 delete fmtf; 3723 delete fmtl; 3724 delete fmtm; 3725 delete fmts; 3726 3727 return; 3728 } 3729 3730 /** 3731 * Test DateFormat's parsing of default GMT variants. See ticket#6135 3732 */ 3733 void DateFormatTest::TestGMTParsing() { 3734 const char* DATA[] = { 3735 "HH:mm:ss Z", 3736 3737 // pattern, input, expected output (in quotes) 3738 "HH:mm:ss Z", "10:20:30 GMT+03:00", "10:20:30 +0300", 3739 "HH:mm:ss Z", "10:20:30 UT-02:00", "10:20:30 -0200", 3740 "HH:mm:ss Z", "10:20:30 GMT", "10:20:30 +0000", 3741 "HH:mm:ss vvvv", "10:20:30 UT+10:00", "10:20:30 +1000", 3742 "HH:mm:ss zzzz", "10:20:30 UTC", "10:20:30 +0000", // standalone "UTC" 3743 "ZZZZ HH:mm:ss", "UT 10:20:30", "10:20:30 +0000", 3744 "z HH:mm:ss", "UT+0130 10:20:30", "10:20:30 +0130", 3745 "z HH:mm:ss", "UTC+0130 10:20:30", "10:20:30 +0130", 3746 // Note: GMT-1100 no longer works because of the introduction of the short 3747 // localized GMT support. Previous implementation support this level of 3748 // leniency (no separator char in localized GMT format), but the new 3749 // implementation handles GMT-11 as the legitimate short localized GMT format 3750 // and stop at there. Otherwise, roundtrip would be broken. 3751 //"HH mm Z ss", "10 20 GMT-1100 30", "10:20:30 -1100", 3752 "HH mm Z ss", "10 20 GMT-11 30", "10:20:30 -1100", 3753 "HH:mm:ssZZZZZ", "14:25:45Z", "14:25:45 +0000", 3754 "HH:mm:ssZZZZZ", "15:00:00-08:00", "15:00:00 -0800", 3755 }; 3756 const int32_t DATA_len = UPRV_LENGTHOF(DATA); 3757 expectParse(DATA, DATA_len, Locale("en")); 3758 } 3759 3760 // Test case for localized GMT format parsing 3761 // with no delimitters in offset format (Chinese locale) 3762 void DateFormatTest::Test6880() { 3763 UErrorCode status = U_ZERO_ERROR; 3764 UDate d1, d2, dp1, dp2, dexp1, dexp2; 3765 UnicodeString s1, s2; 3766 3767 TimeZone *tz = TimeZone::createTimeZone("Asia/Shanghai"); 3768 GregorianCalendar gcal(*tz, status); 3769 if (failure(status, "construct GregorianCalendar", TRUE)) return; 3770 3771 gcal.clear(); 3772 gcal.set(1900, UCAL_JULY, 1, 12, 00); // offset 8:05:43 3773 d1 = gcal.getTime(status); 3774 3775 gcal.clear(); 3776 gcal.set(1950, UCAL_JULY, 1, 12, 00); // offset 8:00 3777 d2 = gcal.getTime(status); 3778 3779 gcal.clear(); 3780 gcal.set(1970, UCAL_JANUARY, 1, 12, 00); 3781 dexp2 = gcal.getTime(status); 3782 dexp1 = dexp2 - (5*60 + 43)*1000; // subtract 5m43s 3783 3784 if (U_FAILURE(status)) { 3785 errln("FAIL: Gregorian calendar error"); 3786 } 3787 3788 DateFormat *fmt = DateFormat::createTimeInstance(DateFormat::kFull, Locale("zh")); 3789 if (fmt == NULL) { 3790 dataerrln("Unable to create DateFormat. Got NULL."); 3791 return; 3792 } 3793 fmt->adoptTimeZone(tz); 3794 3795 fmt->format(d1, s1); 3796 fmt->format(d2, s2); 3797 3798 dp1 = fmt->parse(s1, status); 3799 dp2 = fmt->parse(s2, status); 3800 3801 if (U_FAILURE(status)) { 3802 errln("FAIL: Parse failure"); 3803 } 3804 3805 if (dp1 != dexp1) { 3806 errln("FAIL: Failed to parse " + s1 + " parsed: " + dp1 + " expected: " + dexp1); 3807 } 3808 if (dp2 != dexp2) { 3809 errln("FAIL: Failed to parse " + s2 + " parsed: " + dp2 + " expected: " + dexp2); 3810 } 3811 3812 delete fmt; 3813 } 3814 3815 typedef struct { 3816 const char * localeStr; 3817 UBool lenient; 3818 UBool expectFail; 3819 UnicodeString datePattern; 3820 UnicodeString dateString; 3821 } NumAsStringItem; 3822 3823 void DateFormatTest::TestNumberAsStringParsing() 3824 { 3825 const NumAsStringItem items[] = { 3826 // loc lenient fail? datePattern dateString 3827 { "", FALSE, TRUE, UnicodeString("y MMMM d HH:mm:ss"), UnicodeString("2009 7 14 08:43:57") }, 3828 { "", TRUE, FALSE, UnicodeString("y MMMM d HH:mm:ss"), UnicodeString("2009 7 14 08:43:57") }, 3829 { "en", FALSE, FALSE, UnicodeString("MMM d, y"), UnicodeString("Jul 14, 2009") }, 3830 { "en", TRUE, FALSE, UnicodeString("MMM d, y"), UnicodeString("Jul 14, 2009") }, 3831 { "en", FALSE, TRUE, UnicodeString("MMM d, y"), UnicodeString("7 14, 2009") }, 3832 { "en", TRUE, FALSE, UnicodeString("MMM d, y"), UnicodeString("7 14, 2009") }, 3833 { "ja", FALSE, FALSE, UnicodeString("yyyy/MM/dd"), UnicodeString("2009/07/14") }, 3834 { "ja", TRUE, FALSE, UnicodeString("yyyy/MM/dd"), UnicodeString("2009/07/14") }, 3835 //{ "ja", FALSE, FALSE, UnicodeString("yyyy/MMMMM/d"), UnicodeString("2009/7/14") }, // #8860 covers test failure 3836 { "ja", TRUE, FALSE, UnicodeString("yyyy/MMMMM/d"), UnicodeString("2009/7/14") }, 3837 { "ja", FALSE, FALSE, CharsToUnicodeString("y\\u5E74M\\u6708d\\u65E5"), CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5") }, 3838 { "ja", TRUE, FALSE, CharsToUnicodeString("y\\u5E74M\\u6708d\\u65E5"), CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5") }, 3839 { "ja", FALSE, FALSE, CharsToUnicodeString("y\\u5E74MMMd\\u65E5"), CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5") }, 3840 { "ja", TRUE, FALSE, CharsToUnicodeString("y\\u5E74MMMd\\u65E5"), CharsToUnicodeString("2009\\u5E747\\u670814\\u65E5") }, // #8820 fixes test failure 3841 { "ko", FALSE, FALSE, UnicodeString("yyyy. M. d."), UnicodeString("2009. 7. 14.") }, 3842 { "ko", TRUE, FALSE, UnicodeString("yyyy. M. d."), UnicodeString("2009. 7. 14.") }, 3843 { "ko", FALSE, FALSE, UnicodeString("yyyy. MMMMM d."), CharsToUnicodeString("2009. 7\\uC6D4 14.") }, 3844 { "ko", TRUE, FALSE, UnicodeString("yyyy. MMMMM d."), CharsToUnicodeString("2009. 7\\uC6D4 14.") }, // #8820 fixes test failure 3845 { "ko", FALSE, FALSE, CharsToUnicodeString("y\\uB144 M\\uC6D4 d\\uC77C"), CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") }, 3846 { "ko", TRUE, FALSE, CharsToUnicodeString("y\\uB144 M\\uC6D4 d\\uC77C"), CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") }, 3847 { "ko", FALSE, FALSE, CharsToUnicodeString("y\\uB144 MMM d\\uC77C"), CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") }, 3848 { "ko", TRUE, FALSE, CharsToUnicodeString("y\\uB144 MMM d\\uC77C"), CharsToUnicodeString("2009\\uB144 7\\uC6D4 14\\uC77C") }, // #8820 fixes test failure 3849 { NULL, FALSE, FALSE, UnicodeString(""), UnicodeString("") } 3850 }; 3851 const NumAsStringItem * itemPtr; 3852 for (itemPtr = items; itemPtr->localeStr != NULL; itemPtr++ ) { 3853 Locale locale = Locale::createFromName(itemPtr->localeStr); 3854 UErrorCode status = U_ZERO_ERROR; 3855 SimpleDateFormat *formatter = new SimpleDateFormat(itemPtr->datePattern, locale, status); 3856 if (formatter == NULL || U_FAILURE(status)) { 3857 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status)); 3858 return; 3859 } 3860 3861 formatter->setLenient(itemPtr->lenient); 3862 formatter->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->lenient, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->lenient, status); 3863 UDate date1 = formatter->parse(itemPtr->dateString, status); 3864 if (U_FAILURE(status)) { 3865 if (!itemPtr->expectFail) { 3866 errln("FAIL, err when expected success: Locale \"" + UnicodeString(itemPtr->localeStr) + "\", lenient " + itemPtr->lenient + 3867 ": using pattern \"" + itemPtr->datePattern + "\", could not parse \"" + itemPtr->dateString + "\"; err: " + u_errorName(status) ); 3868 } 3869 } else if (itemPtr->expectFail) { 3870 errln("FAIL, expected err but got none: Locale \"" + UnicodeString(itemPtr->localeStr) + "\", lenient " + itemPtr->lenient + 3871 ": using pattern \"" + itemPtr->datePattern + "\", did parse \"" + itemPtr->dateString + "\"." ); 3872 } else if (!itemPtr->lenient) { 3873 UnicodeString formatted; 3874 formatter->format(date1, formatted); 3875 if (formatted != itemPtr->dateString) { 3876 errln("FAIL, mismatch formatting parsed date: Locale \"" + UnicodeString(itemPtr->localeStr) + "\", lenient " + itemPtr->lenient + 3877 ": using pattern \"" + itemPtr->datePattern + "\", did parse \"" + itemPtr->dateString + "\", formatted result \"" + formatted + "\"."); 3878 } 3879 } 3880 3881 delete formatter; 3882 } 3883 } 3884 3885 void DateFormatTest::TestISOEra() { 3886 3887 const char* data[] = { 3888 // input, output 3889 "BC 4004-10-23T07:00:00Z", "BC 4004-10-23T07:00:00Z", 3890 "AD 4004-10-23T07:00:00Z", "AD 4004-10-23T07:00:00Z", 3891 "-4004-10-23T07:00:00Z" , "BC 4005-10-23T07:00:00Z", 3892 "4004-10-23T07:00:00Z" , "AD 4004-10-23T07:00:00Z", 3893 }; 3894 3895 int32_t numData = 8; 3896 3897 UErrorCode status = U_ZERO_ERROR; 3898 3899 // create formatter 3900 SimpleDateFormat *fmt1 = new SimpleDateFormat(UnicodeString("GGG yyyy-MM-dd'T'HH:mm:ss'Z"), status); 3901 failure(status, "new SimpleDateFormat", TRUE); 3902 if (status == U_MISSING_RESOURCE_ERROR) { 3903 if (fmt1 != NULL) { 3904 delete fmt1; 3905 } 3906 return; 3907 } 3908 for(int i=0; i < numData; i+=2) { 3909 // create input string 3910 UnicodeString in = data[i]; 3911 3912 // parse string to date 3913 UDate dt1 = fmt1->parse(in, status); 3914 failure(status, "fmt->parse", TRUE); 3915 3916 // format date back to string 3917 UnicodeString out; 3918 out = fmt1->format(dt1, out); 3919 logln(out); 3920 3921 // check that roundtrip worked as expected 3922 UnicodeString expected = data[i+1]; 3923 if (out != expected) { 3924 dataerrln((UnicodeString)"FAIL: " + in + " -> " + out + " expected -> " + expected); 3925 } 3926 } 3927 3928 delete fmt1; 3929 } 3930 void DateFormatTest::TestFormalChineseDate() { 3931 3932 UErrorCode status = U_ZERO_ERROR; 3933 UnicodeString pattern ("y\\u5e74M\\u6708d\\u65e5", -1, US_INV ); 3934 pattern = pattern.unescape(); 3935 UnicodeString override ("y=hanidec;M=hans;d=hans", -1, US_INV ); 3936 3937 // create formatter 3938 SimpleDateFormat *sdf = new SimpleDateFormat(pattern,override,Locale::getChina(),status); 3939 if (failure(status, "new SimpleDateFormat with override", TRUE)) { 3940 return; 3941 } 3942 3943 UDate thedate = date(2009-1900, UCAL_JULY, 28); 3944 FieldPosition pos(FieldPosition::DONT_CARE); 3945 UnicodeString result; 3946 sdf->format(thedate,result,pos); 3947 3948 UnicodeString expected = "\\u4e8c\\u3007\\u3007\\u4e5d\\u5e74\\u4e03\\u6708\\u4e8c\\u5341\\u516b\\u65e5"; 3949 expected = expected.unescape(); 3950 if (result != expected) { 3951 dataerrln((UnicodeString)"FAIL: -> " + result + " expected -> " + expected); 3952 } 3953 3954 UDate parsedate = sdf->parse(expected,status); 3955 if ( parsedate != thedate ) { 3956 UnicodeString pat1 ("yyyy-MM-dd'T'HH:mm:ss'Z'", -1, US_INV ); 3957 SimpleDateFormat *usf = new SimpleDateFormat(pat1,Locale::getEnglish(),status); 3958 UnicodeString parsedres,expres; 3959 usf->format(parsedate,parsedres,pos); 3960 usf->format(thedate,expres,pos); 3961 dataerrln((UnicodeString)"FAIL: parsed -> " + parsedres + " expected -> " + expres); 3962 delete usf; 3963 } 3964 delete sdf; 3965 } 3966 3967 // Test case for #8675 3968 // Incorrect parse offset with stand alone GMT string on 2nd or later iteration. 3969 void DateFormatTest::TestStandAloneGMTParse() { 3970 UErrorCode status = U_ZERO_ERROR; 3971 SimpleDateFormat *sdf = new SimpleDateFormat("ZZZZ", Locale(""), status); 3972 3973 if (U_SUCCESS(status)) { 3974 3975 UnicodeString inText("GMT$$$"); 3976 for (int32_t i = 0; i < 10; i++) { 3977 ParsePosition pos(0); 3978 sdf->parse(inText, pos); 3979 if (pos.getIndex() != 3) { 3980 errln((UnicodeString)"FAIL: Incorrect output parse position: actual=" + pos.getIndex() + " expected=3"); 3981 } 3982 } 3983 3984 delete sdf; 3985 } else { 3986 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status)); 3987 } 3988 } 3989 3990 void DateFormatTest::TestParsePosition() { 3991 const char* TestData[][4] = { 3992 // {<pattern>, <lead>, <date string>, <trail>} 3993 {"yyyy-MM-dd HH:mm:ssZ", "", "2010-01-10 12:30:00+0500", ""}, 3994 {"yyyy-MM-dd HH:mm:ss ZZZZ", "", "2010-01-10 12:30:00 GMT+05:00", ""}, 3995 {"Z HH:mm:ss", "", "-0100 13:20:30", ""}, 3996 {"y-M-d Z", "", "2011-8-25 -0400", " Foo"}, 3997 {"y/M/d H:mm:ss z", "", "2011/7/1 12:34:00 PDT", ""}, 3998 {"y/M/d H:mm:ss z", "+123", "2011/7/1 12:34:00 PDT", " PST"}, 3999 {"vvvv a h:mm:ss", "", "Pacific Time AM 10:21:45", ""}, 4000 {"HH:mm v M/d", "111", "14:15 PT 8/10", " 12345"}, 4001 {"'time zone:' VVVV 'date:' yyyy-MM-dd", "xxxx", "time zone: Los Angeles Time date: 2010-02-25", "xxxx"}, 4002 {"yG", "", "2012AD", ""}, 4003 {"yG", "", "2012", "x"}, 4004 {0, 0, 0, 0}, 4005 }; 4006 4007 for (int32_t i = 0; TestData[i][0]; i++) { 4008 UErrorCode status = U_ZERO_ERROR; 4009 SimpleDateFormat *sdf = new SimpleDateFormat(UnicodeString(TestData[i][0]), status); 4010 if (failure(status, "new SimpleDateFormat", TRUE)) return; 4011 4012 int32_t startPos, resPos; 4013 4014 // lead text 4015 UnicodeString input(TestData[i][1]); 4016 startPos = input.length(); 4017 4018 // date string 4019 input += TestData[i][2]; 4020 resPos = input.length(); 4021 4022 // trail text 4023 input += TestData[i][3]; 4024 4025 ParsePosition pos(startPos); 4026 //UDate d = sdf->parse(input, pos); 4027 (void)sdf->parse(input, pos); 4028 4029 if (pos.getIndex() != resPos) { 4030 errln(UnicodeString("FAIL: Parsing [") + input + "] with pattern [" + TestData[i][0] + "] returns position - " 4031 + pos.getIndex() + ", expected - " + resPos); 4032 } 4033 4034 delete sdf; 4035 } 4036 } 4037 4038 4039 typedef struct { 4040 int32_t era; 4041 int32_t year; 4042 int32_t month; // 1-based 4043 int32_t isLeapMonth; 4044 int32_t day; 4045 } ChineseCalTestDate; 4046 4047 #define NUM_TEST_DATES 3 4048 4049 typedef struct { 4050 const char * locale; 4051 int32_t style; // <0 => custom 4052 UnicodeString dateString[NUM_TEST_DATES]; 4053 } MonthPatternItem; 4054 4055 void DateFormatTest::TestMonthPatterns() 4056 { 4057 const ChineseCalTestDate dates[NUM_TEST_DATES] = { 4058 // era yr mo lp da 4059 { 78, 29, 4, 0, 2 }, // (in chinese era 78) gregorian 2012-4-22 4060 { 78, 29, 4, 1, 2 }, // (in chinese era 78) gregorian 2012-5-22 4061 { 78, 29, 5, 0, 2 }, // (in chinese era 78) gregorian 2012-6-20 4062 }; 4063 4064 const MonthPatternItem items[] = { 4065 // locale date style; expected formats for the 3 dates above 4066 { "root@calendar=chinese", DateFormat::kLong, { UnicodeString("2012(ren-chen) M04 2"), UnicodeString("2012(ren-chen) M04bis 2"), UnicodeString("2012(ren-chen) M05 2") } }, 4067 { "root@calendar=chinese", DateFormat::kShort, { UnicodeString("2012-04-02"), UnicodeString("2012-04bis-02"), UnicodeString("2012-05-02") } }, 4068 { "root@calendar=chinese", -1, { UnicodeString("29-4-2"), UnicodeString("29-4bis-2"), UnicodeString("29-5-2") } }, 4069 { "root@calendar=chinese", -2, { UnicodeString("78x29-4-2"), UnicodeString("78x29-4bis-2"), UnicodeString("78x29-5-2") } }, 4070 { "root@calendar=chinese", -3, { UnicodeString("ren-chen-4-2"), UnicodeString("ren-chen-4bis-2"), UnicodeString("ren-chen-5-2") } }, 4071 { "root@calendar=chinese", -4, { UnicodeString("ren-chen M04 2"), UnicodeString("ren-chen M04bis 2"), UnicodeString("ren-chen M05 2") } }, 4072 { "en@calendar=gregorian", -3, { UnicodeString("2012-4-22"), UnicodeString("2012-5-22"), UnicodeString("2012-6-20") } }, 4073 { "en@calendar=chinese", DateFormat::kLong, { UnicodeString("Fourth Month 2, 2012(ren-chen)"), UnicodeString("Fourth Monthbis 2, 2012(ren-chen)"), UnicodeString("Fifth Month 2, 2012(ren-chen)") } }, 4074 { "en@calendar=chinese", DateFormat::kShort, { UnicodeString("4/2/2012"), UnicodeString("4bis/2/2012"), UnicodeString("5/2/2012") } }, 4075 { "zh@calendar=chinese", DateFormat::kLong, { CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u56DB\\u6708\\u521D\\u4E8C"), 4076 CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u95F0\\u56DB\\u6708\\u521D\\u4E8C"), 4077 CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u4E94\\u6708\\u521D\\u4E8C") } }, 4078 { "zh@calendar=chinese", DateFormat::kShort, { CharsToUnicodeString("2012/4/2"), 4079 CharsToUnicodeString("2012/\\u95F04/2"), 4080 CharsToUnicodeString("2012/5/2") } }, 4081 { "zh@calendar=chinese", -3, { CharsToUnicodeString("\\u58EC\\u8FB0-4-2"), 4082 CharsToUnicodeString("\\u58EC\\u8FB0-\\u95F04-2"), 4083 CharsToUnicodeString("\\u58EC\\u8FB0-5-2") } }, 4084 { "zh@calendar=chinese", -4, { CharsToUnicodeString("\\u58EC\\u8FB0 \\u56DB\\u6708 2"), 4085 CharsToUnicodeString("\\u58EC\\u8FB0 \\u95F0\\u56DB\\u6708 2"), 4086 CharsToUnicodeString("\\u58EC\\u8FB0 \\u4E94\\u6708 2") } }, 4087 { "zh_Hant@calendar=chinese", DateFormat::kLong, { CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u56DB\\u6708\\u521D\\u4E8C"), 4088 CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u958F\\u56DB\\u6708\\u521D\\u4E8C"), 4089 CharsToUnicodeString("2012\\u58EC\\u8FB0\\u5E74\\u4E94\\u6708\\u521D\\u4E8C") } }, 4090 { "zh_Hant@calendar=chinese", DateFormat::kShort, { CharsToUnicodeString("2012/4/2"), 4091 CharsToUnicodeString("2012/\\u958F4/2"), 4092 CharsToUnicodeString("2012/5/2") } }, 4093 { "fr@calendar=chinese", DateFormat::kLong, { CharsToUnicodeString("2 s\\u00ECyu\\u00E8 ren-chen"), 4094 CharsToUnicodeString("2 s\\u00ECyu\\u00E8bis ren-chen"), 4095 CharsToUnicodeString("2 w\\u01D4yu\\u00E8 ren-chen") } }, 4096 { "fr@calendar=chinese", DateFormat::kShort, { UnicodeString("2/4/29"), UnicodeString("2/4bis/29"), UnicodeString("2/5/29") } }, 4097 { "en@calendar=dangi", DateFormat::kLong, { UnicodeString("Third Monthbis 2, 2012(ren-chen)"), UnicodeString("Fourth Month 2, 2012(ren-chen)"), UnicodeString("Fifth Month 1, 2012(ren-chen)") } }, 4098 { "en@calendar=dangi", DateFormat::kShort, { UnicodeString("3bis/2/2012"), UnicodeString("4/2/2012"), UnicodeString("5/1/2012") } }, 4099 { "en@calendar=dangi", -2, { UnicodeString("78x29-3bis-2"), UnicodeString("78x29-4-2"), UnicodeString("78x29-5-1") } }, 4100 { "ko@calendar=dangi", DateFormat::kLong, { CharsToUnicodeString("\\uC784\\uC9C4\\uB144 \\uC7243\\uC6D4 2\\uC77C"), 4101 CharsToUnicodeString("\\uC784\\uC9C4\\uB144 4\\uC6D4 2\\uC77C"), 4102 CharsToUnicodeString("\\uC784\\uC9C4\\uB144 5\\uC6D4 1\\uC77C") } }, 4103 { "ko@calendar=dangi", DateFormat::kShort, { CharsToUnicodeString("29. \\uC7243. 2."), 4104 CharsToUnicodeString("29. 4. 2."), 4105 CharsToUnicodeString("29. 5. 1.") } }, 4106 // terminator 4107 { NULL, 0, { UnicodeString(""), UnicodeString(""), UnicodeString("") } } 4108 }; 4109 4110 //. style: -1 -2 -3 -4 4111 const UnicodeString customPatterns[] = { "y-Ml-d", "G'x'y-Ml-d", "U-M-d", "U MMM d" }; // like old root pattern, using 'l' 4112 4113 UErrorCode status = U_ZERO_ERROR; 4114 Locale rootChineseCalLocale = Locale::createFromName("root@calendar=chinese"); 4115 Calendar * rootChineseCalendar = Calendar::createInstance(rootChineseCalLocale, status); 4116 if (U_SUCCESS(status)) { 4117 const MonthPatternItem * itemPtr; 4118 for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) { 4119 Locale locale = Locale::createFromName(itemPtr->locale); 4120 DateFormat * dmft = (itemPtr->style >= 0)? 4121 DateFormat::createDateInstance((DateFormat::EStyle)itemPtr->style, locale): 4122 new SimpleDateFormat(customPatterns[-itemPtr->style - 1], locale, status); 4123 if ( dmft != NULL ) { 4124 if (U_SUCCESS(status)) { 4125 const ChineseCalTestDate * datePtr = dates; 4126 int32_t idate; 4127 for (idate = 0; idate < NUM_TEST_DATES; idate++, datePtr++) { 4128 rootChineseCalendar->clear(); 4129 rootChineseCalendar->set(UCAL_ERA, datePtr->era); 4130 rootChineseCalendar->set(datePtr->year, datePtr->month-1, datePtr->day); 4131 rootChineseCalendar->set(UCAL_IS_LEAP_MONTH, datePtr->isLeapMonth); 4132 UnicodeString result; 4133 FieldPosition fpos(FieldPosition::DONT_CARE); 4134 dmft->format(*rootChineseCalendar, result, fpos); 4135 if ( result.compare(itemPtr->dateString[idate]) != 0 ) { 4136 errln( UnicodeString("FAIL: Chinese calendar format for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style + 4137 ", expected \"" + itemPtr->dateString[idate] + "\", got \"" + result + "\""); 4138 } else { 4139 // formatted OK, try parse 4140 ParsePosition ppos(0); 4141 // ensure we are really parsing the fields we should be 4142 rootChineseCalendar->set(UCAL_YEAR, 1); 4143 rootChineseCalendar->set(UCAL_MONTH, 0); 4144 rootChineseCalendar->set(UCAL_IS_LEAP_MONTH, 0); 4145 rootChineseCalendar->set(UCAL_DATE, 1); 4146 // 4147 dmft->parse(result, *rootChineseCalendar, ppos); 4148 int32_t year = rootChineseCalendar->get(UCAL_YEAR, status); 4149 int32_t month = rootChineseCalendar->get(UCAL_MONTH, status) + 1; 4150 int32_t isLeapMonth = rootChineseCalendar->get(UCAL_IS_LEAP_MONTH, status); 4151 int32_t day = rootChineseCalendar->get(UCAL_DATE, status); 4152 if ( ppos.getIndex() < result.length() || year != datePtr->year || month != datePtr->month || isLeapMonth != datePtr->isLeapMonth || day != datePtr->day ) { 4153 errln( UnicodeString("FAIL: Chinese calendar parse for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style + 4154 ", string \"" + result + "\", expected " + datePtr->year +"-"+datePtr->month+"("+datePtr->isLeapMonth+")-"+datePtr->day + ", got pos " + 4155 ppos.getIndex() + " " + year +"-"+month+"("+isLeapMonth+")-"+day); 4156 } 4157 } 4158 } 4159 } else { 4160 dataerrln("Error creating SimpleDateFormat for Chinese calendar- %s", u_errorName(status)); 4161 } 4162 delete dmft; 4163 } else { 4164 dataerrln("FAIL: Unable to create DateFormat for Chinese calendar- %s", u_errorName(status)); 4165 } 4166 } 4167 delete rootChineseCalendar; 4168 } else { 4169 errln(UnicodeString("FAIL: Unable to create Calendar for root@calendar=chinese")); 4170 } 4171 } 4172 4173 typedef struct { 4174 const char * locale; 4175 UnicodeString pattern; 4176 UDisplayContext capitalizationContext; 4177 UnicodeString expectedFormat; 4178 } TestContextItem; 4179 4180 void DateFormatTest::TestContext() 4181 { 4182 const UDate july022008 = 1215000001979.0; 4183 const TestContextItem items[] = { 4184 //locale pattern capitalizationContext expected formatted date 4185 { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_NONE, UnicodeString("juillet 2008") }, 4186 #if !UCONFIG_NO_BREAK_ITERATION 4187 { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, UnicodeString("juillet 2008") }, 4188 { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, UnicodeString("Juillet 2008") }, 4189 { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, UnicodeString("juillet 2008") }, 4190 { "fr", UnicodeString("MMMM y"), UDISPCTX_CAPITALIZATION_FOR_STANDALONE, UnicodeString("Juillet 2008") }, 4191 #endif 4192 { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_NONE, CharsToUnicodeString("\\u010Dervenec 2008") }, 4193 #if !UCONFIG_NO_BREAK_ITERATION 4194 { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, CharsToUnicodeString("\\u010Dervenec 2008") }, 4195 { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, CharsToUnicodeString("\\u010Cervenec 2008") }, 4196 { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, CharsToUnicodeString("\\u010Cervenec 2008") }, 4197 { "cs", UnicodeString("LLLL y"), UDISPCTX_CAPITALIZATION_FOR_STANDALONE, CharsToUnicodeString("\\u010Dervenec 2008") }, 4198 #endif 4199 // terminator 4200 { NULL, UnicodeString(""), (UDisplayContext)0, UnicodeString("") } 4201 }; 4202 UErrorCode status = U_ZERO_ERROR; 4203 Calendar* cal = Calendar::createInstance(status); 4204 if (U_FAILURE(status)) { 4205 dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale.")); 4206 } else { 4207 cal->setTime(july022008, status); 4208 const TestContextItem * itemPtr; 4209 for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) { 4210 Locale locale = Locale::createFromName(itemPtr->locale); 4211 status = U_ZERO_ERROR; 4212 SimpleDateFormat * sdmft = new SimpleDateFormat(itemPtr->pattern, locale, status); 4213 if (U_FAILURE(status)) { 4214 dataerrln(UnicodeString("FAIL: Unable to create SimpleDateFormat for specified pattern with locale ") + UnicodeString(itemPtr->locale)); 4215 } else { 4216 sdmft->setContext(itemPtr->capitalizationContext, status); 4217 UnicodeString result; 4218 FieldPosition pos(FieldPosition::DONT_CARE); 4219 sdmft->format(*cal, result, pos); 4220 if (result.compare(itemPtr->expectedFormat) != 0) { 4221 errln(UnicodeString("FAIL: format for locale ") + UnicodeString(itemPtr->locale) + 4222 ", status " + (int)status + 4223 ", capitalizationContext " + (int)itemPtr->capitalizationContext + 4224 ", expected " + itemPtr->expectedFormat + ", got " + result); 4225 } 4226 } 4227 if (sdmft) { 4228 delete sdmft; 4229 } 4230 } 4231 } 4232 if (cal) { 4233 delete cal; 4234 } 4235 } 4236 4237 // test item for a particular locale + calendar and date format 4238 typedef struct { 4239 int32_t era; 4240 int32_t year; 4241 int32_t month; 4242 int32_t day; 4243 int32_t hour; 4244 int32_t minute; 4245 UnicodeString formattedDate; 4246 } CalAndFmtTestItem; 4247 4248 // test item giving locale + calendar, date format, and CalAndFmtTestItems 4249 typedef struct { 4250 const char * locale; // with calendar 4251 DateFormat::EStyle style; 4252 UnicodeString pattern; // ignored unless style == DateFormat::kNone 4253 const CalAndFmtTestItem *caftItems; 4254 } TestNonGregoItem; 4255 4256 void DateFormatTest::TestNonGregoFmtParse() 4257 { 4258 // test items for he@calendar=hebrew, long date format 4259 const CalAndFmtTestItem cafti_he_hebrew_long[] = { 4260 { 0, 4999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05D3\\u05F3\\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") }, 4261 { 0, 5100, 0, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05E7\\u05F3") }, 4262 { 0, 5774, 5, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05D0\\u05D3\\u05E8 \\u05D0\\u05F3 \\u05EA\\u05E9\\u05E2\\u05F4\\u05D3") }, 4263 { 0, 5999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") }, 4264 { 0, 6100, 0, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05D5\\u05F3\\u05E7\\u05F3") }, 4265 { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator 4266 }; 4267 const CalAndFmtTestItem cafti_zh_chinese_custU[] = { 4268 { 78, 31, 0, 1, 12, 0, CharsToUnicodeString("2014\\u7532\\u5348\\u5E74\\u6B63\\u67081") }, 4269 { 77, 31, 0, 1, 12, 0, CharsToUnicodeString("1954\\u7532\\u5348\\u5E74\\u6B63\\u67081") }, 4270 { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator 4271 }; 4272 const CalAndFmtTestItem cafti_zh_chinese_custNoU[] = { 4273 { 78, 31, 0, 1, 12, 0, CharsToUnicodeString("2014\\u5E74\\u6B63\\u67081") }, 4274 { 77, 31, 0, 1, 12, 0, CharsToUnicodeString("1954\\u5E74\\u6B63\\u67081") }, 4275 { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator 4276 }; 4277 const CalAndFmtTestItem cafti_ja_japanese_custGy[] = { 4278 {235, 26, 2, 5, 12, 0, CharsToUnicodeString("2014(\\u5E73\\u621026)\\u5E743\\u67085\\u65E5") }, 4279 {234, 60, 2, 5, 12, 0, CharsToUnicodeString("1985(\\u662D\\u548C60)\\u5E743\\u67085\\u65E5") }, 4280 { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator 4281 }; 4282 const CalAndFmtTestItem cafti_ja_japanese_custNoGy[] = { 4283 {235, 26, 2, 5, 12, 0, CharsToUnicodeString("2014\\u5E743\\u67085\\u65E5") }, 4284 {234, 60, 2, 5, 12, 0, CharsToUnicodeString("1985\\u5E743\\u67085\\u65E5") }, 4285 { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator 4286 }; 4287 const CalAndFmtTestItem cafti_en_islamic_cust[] = { 4288 { 0, 1384, 0, 1, 12, 0, UnicodeString("1 Muh. 1384 AH, 1964") }, 4289 { 0, 1436, 0, 1, 12, 0, UnicodeString("1 Muh. 1436 AH, 2014") }, 4290 { 0, 1487, 0, 1, 12, 0, UnicodeString("1 Muh. 1487 AH, 2064") }, 4291 { 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator 4292 }; 4293 // overal test items 4294 const TestNonGregoItem items[] = { 4295 { "he@calendar=hebrew", DateFormat::kLong, UnicodeString(""), cafti_he_hebrew_long }, 4296 { "zh@calendar=chinese", DateFormat::kNone, CharsToUnicodeString("rU\\u5E74MMMd"), cafti_zh_chinese_custU }, 4297 { "zh@calendar=chinese", DateFormat::kNone, CharsToUnicodeString("r\\u5E74MMMd"), cafti_zh_chinese_custNoU }, 4298 { "ja@calendar=japanese", DateFormat::kNone, CharsToUnicodeString("r(Gy)\\u5E74M\\u6708d\\u65E5"), cafti_ja_japanese_custGy }, 4299 { "ja@calendar=japanese", DateFormat::kNone, CharsToUnicodeString("r\\u5E74M\\u6708d\\u65E5"), cafti_ja_japanese_custNoGy }, 4300 { "en@calendar=islamic", DateFormat::kNone, UnicodeString("d MMM y G, r"), cafti_en_islamic_cust }, 4301 { NULL, DateFormat::kNone, UnicodeString(""), NULL } // terminator 4302 }; 4303 const TestNonGregoItem * itemPtr; 4304 for (itemPtr = items; itemPtr->locale != NULL; itemPtr++) { 4305 Locale locale = Locale::createFromName(itemPtr->locale); 4306 DateFormat * dfmt = NULL; 4307 UErrorCode status = U_ZERO_ERROR; 4308 if (itemPtr->style != DateFormat::kNone) { 4309 dfmt = DateFormat::createDateInstance(itemPtr->style, locale); 4310 } else { 4311 dfmt = new SimpleDateFormat(itemPtr->pattern, locale, status); 4312 } 4313 if (U_FAILURE(status)) { 4314 dataerrln("new SimpleDateFormat fails for locale %s", itemPtr->locale); 4315 } else if (dfmt == NULL) { 4316 dataerrln("DateFormat::createDateInstance fails for locale %s", itemPtr->locale); 4317 } else { 4318 Calendar * cal = (dfmt->getCalendar())->clone(); 4319 if (cal == NULL) { 4320 dataerrln("(DateFormat::getCalendar)->clone() fails for locale %s", itemPtr->locale); 4321 } else { 4322 const CalAndFmtTestItem * caftItemPtr; 4323 for (caftItemPtr = itemPtr->caftItems; caftItemPtr->year != 0; caftItemPtr++) { 4324 cal->clear(); 4325 cal->set(UCAL_ERA, caftItemPtr->era); 4326 cal->set(UCAL_YEAR, caftItemPtr->year); 4327 cal->set(UCAL_MONTH, caftItemPtr->month); 4328 cal->set(UCAL_DATE, caftItemPtr->day); 4329 cal->set(UCAL_HOUR_OF_DAY, caftItemPtr->hour); 4330 cal->set(UCAL_MINUTE, caftItemPtr->minute); 4331 UnicodeString result; 4332 FieldPosition fpos(FieldPosition::DONT_CARE); 4333 dfmt->format(*cal, result, fpos); 4334 if ( result.compare(caftItemPtr->formattedDate) != 0 ) { 4335 errln( UnicodeString("FAIL: date format for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style + 4336 ", expected \"" + caftItemPtr->formattedDate + "\", got \"" + result + "\""); 4337 } else { 4338 // formatted OK, try parse 4339 ParsePosition ppos(0); 4340 dfmt->parse(result, *cal, ppos); 4341 status = U_ZERO_ERROR; 4342 int32_t era = cal->get(UCAL_ERA, status); 4343 int32_t year = cal->get(UCAL_YEAR, status); 4344 int32_t month = cal->get(UCAL_MONTH, status); 4345 int32_t day = cal->get(UCAL_DATE, status); 4346 if ( U_FAILURE(status) || ppos.getIndex() < result.length() || era != caftItemPtr->era || 4347 year != caftItemPtr->year || month != caftItemPtr->month || day != caftItemPtr->day ) { 4348 errln( UnicodeString("FAIL: date parse for locale ") + UnicodeString(itemPtr->locale) + 4349 ", style " + itemPtr->style + ", string \"" + result + "\", expected " + 4350 caftItemPtr->era +":"+caftItemPtr->year +"-"+caftItemPtr->month+"-"+caftItemPtr->day + ", got pos " + 4351 ppos.getIndex() + " " + year +"-"+month+"-"+day + " status " + UnicodeString(u_errorName(status)) ); 4352 } 4353 } 4354 } 4355 delete cal; 4356 } 4357 delete dfmt; 4358 } 4359 } 4360 } 4361 4362 typedef struct { 4363 const char* localeID; 4364 DateFormat::EStyle style; 4365 UnicodeString expectPattern; 4366 UnicodeString expectFormat; 4367 } TestFmtWithNumSysItem; 4368 enum { kBBufMax = 128 }; 4369 void DateFormatTest::TestFormatsWithNumberSystems() 4370 { 4371 LocalPointer<TimeZone> zone(TimeZone::createTimeZone(UnicodeString("UTC"))); 4372 const UDate date = 1451556000000.0; // for UTC: grego 31-Dec-2015 10 AM, hebrew 19 tevet 5776, chinese yi-wei 11mo 21day 4373 const TestFmtWithNumSysItem items[] = { 4374 { "haw@calendar=gregorian", DateFormat::kShort, UnicodeString("d/M/yy"), UnicodeString("31/xii/15") }, 4375 { "he@calendar=hebrew", DateFormat::kLong, CharsToUnicodeString("d \\u05D1MMMM y"), CharsToUnicodeString("\\u05D9\\u05F4\\u05D8 \\u05D1\\u05D8\\u05D1\\u05EA \\u05EA\\u05E9\\u05E2\\u05F4\\u05D5") }, 4376 { "zh@calendar=chinese", DateFormat::kLong, CharsToUnicodeString("rU\\u5E74MMMd"), CharsToUnicodeString("2015\\u4E59\\u672A\\u5E74\\u5341\\u4E00\\u6708\\u5EFF\\u4E00") }, 4377 { "zh_Hant@calendar=chinese", DateFormat::kLong, CharsToUnicodeString("rU\\u5E74MMMd"), CharsToUnicodeString("2015\\u4E59\\u672A\\u5E74\\u51AC\\u6708\\u5EFF\\u4E00") }, 4378 { "ja@calendar=chinese", DateFormat::kLong, CharsToUnicodeString("U\\u5E74MMMd\\u65E5"), CharsToUnicodeString("\\u4E59\\u672A\\u5E74\\u5341\\u4E00\\u6708\\u4E8C\\u4E00\\u65E5") }, 4379 { NULL, DateFormat::kNone, UnicodeString(""), UnicodeString("") }, 4380 }; 4381 const TestFmtWithNumSysItem * itemPtr; 4382 for (itemPtr = items; itemPtr->localeID != NULL; itemPtr++) { 4383 char bExpected[kBBufMax]; 4384 char bResult[kBBufMax]; 4385 UErrorCode status = U_ZERO_ERROR; 4386 Locale locale = Locale::createFromName(itemPtr->localeID); 4387 LocalPointer<Calendar> cal(Calendar::createInstance(zone.orphan(), locale, status)); 4388 if (U_FAILURE(status)) { 4389 dataerrln("Calendar::createInstance fails for locale %s, status %s", itemPtr->localeID, u_errorName(status)); 4390 continue; 4391 } 4392 cal->setTime(date, status); 4393 if (U_FAILURE(status)) { 4394 dataerrln("Calendar::setTime fails for locale %s, date %.1f, status %s", itemPtr->localeID, date, u_errorName(status)); 4395 continue; 4396 } 4397 LocalPointer<SimpleDateFormat> sdfmt(static_cast<SimpleDateFormat *>(DateFormat::createDateInstance(itemPtr->style, locale))); 4398 if (sdfmt.isNull()) { 4399 dataerrln("DateFormat::createDateInstance fails for locale %s", itemPtr->localeID); 4400 continue; 4401 } 4402 UnicodeString getFormat; 4403 sdfmt->format(*(cal.getAlias()), getFormat, NULL, status); 4404 if (U_FAILURE(status)) { 4405 errln("DateFormat::format fails for locale %s, status %s", itemPtr->localeID, u_errorName(status)); 4406 continue; 4407 } 4408 if (getFormat.compare(itemPtr->expectFormat) != 0) { 4409 itemPtr->expectFormat.extract(0, itemPtr->expectFormat.length(), bExpected, kBBufMax); 4410 getFormat.extract(0, getFormat.length(), bResult, kBBufMax); 4411 errln("DateFormat::format for locale %s, expected \"%s\", got \"%s\"", itemPtr->localeID, bExpected, bResult); 4412 } 4413 UnicodeString getPattern; 4414 sdfmt->toPattern(getPattern); 4415 if (getPattern.compare(itemPtr->expectPattern) != 0) { 4416 itemPtr->expectPattern.extract(0, itemPtr->expectPattern.length(), bExpected, kBBufMax); 4417 getPattern.extract(0, getPattern.length(), bResult, kBBufMax); 4418 errln("DateFormat::toPattern() for locale %s, expected \"%s\", got \"%s\"", itemPtr->localeID, bExpected, bResult); 4419 } 4420 } 4421 } 4422 4423 static const UDate TEST_DATE = 1326585600000.; // 2012-jan-15 4424 4425 void DateFormatTest::TestDotAndAtLeniency() { 4426 // Test for date/time parsing regression with CLDR 22.1/ICU 50 pattern strings. 4427 // For details see http://bugs.icu-project.org/trac/ticket/9789 4428 static const char *locales[] = { "en", "fr" }; 4429 for (int32_t i = 0; i < UPRV_LENGTHOF(locales); ++i) { 4430 Locale locale(locales[i]); 4431 4432 for (DateFormat::EStyle dateStyle = DateFormat::FULL; dateStyle <= DateFormat::SHORT; 4433 dateStyle = static_cast<DateFormat::EStyle>(dateStyle + 1)) { 4434 LocalPointer<DateFormat> dateFormat(DateFormat::createDateInstance(dateStyle, locale)); 4435 4436 for (DateFormat::EStyle timeStyle = DateFormat::FULL; timeStyle <= DateFormat::SHORT; 4437 timeStyle = static_cast<DateFormat::EStyle>(timeStyle + 1)) { 4438 LocalPointer<DateFormat> format(DateFormat::createDateTimeInstance(dateStyle, timeStyle, locale)); 4439 LocalPointer<DateFormat> timeFormat(DateFormat::createTimeInstance(timeStyle, locale)); 4440 UnicodeString formattedString; 4441 if (format.isNull()) { 4442 dataerrln("Unable to create DateFormat"); 4443 continue; 4444 } 4445 format->format(TEST_DATE, formattedString); 4446 4447 if (!showParse(*format, formattedString)) { 4448 errln(UnicodeString(" with date-time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle); 4449 } 4450 4451 UnicodeString ds, ts; 4452 formattedString = dateFormat->format(TEST_DATE, ds) + " " + timeFormat->format(TEST_DATE, ts); 4453 if (!showParse(*format, formattedString)) { 4454 errln(UnicodeString(" with date sp sp time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle); 4455 } 4456 if (formattedString.indexOf("n ") >= 0) { // will add "." after the end of text ending in 'n', like Jan. 4457 UnicodeString plusDot(formattedString); 4458 plusDot.findAndReplace("n ", "n. ").append("."); 4459 if (!showParse(*format, plusDot)) { 4460 errln(UnicodeString(" with date plus-dot time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle); 4461 } 4462 } 4463 if (formattedString.indexOf(". ") >= 0) { // will subtract "." at the end of strings. 4464 UnicodeString minusDot(formattedString); 4465 minusDot.findAndReplace(". ", " "); 4466 if (!showParse(*format, minusDot)) { 4467 errln(UnicodeString(" with date minus-dot time: dateStyle=") + dateStyle + " timeStyle=" + timeStyle); 4468 } 4469 } 4470 } 4471 } 4472 } 4473 } 4474 4475 UBool DateFormatTest::showParse(DateFormat &format, const UnicodeString &formattedString) { 4476 ParsePosition parsePosition; 4477 UDate parsed = format.parse(formattedString, parsePosition); 4478 UBool ok = TEST_DATE == parsed && parsePosition.getIndex() == formattedString.length(); 4479 UnicodeString pattern; 4480 static_cast<SimpleDateFormat &>(format).toPattern(pattern); 4481 if (ok) { 4482 logln(pattern + " parsed: " + formattedString); 4483 } else { 4484 errln(pattern + " fails to parse: " + formattedString); 4485 } 4486 return ok; 4487 } 4488 4489 4490 typedef struct { 4491 const char * locale; 4492 UBool leniency; 4493 UnicodeString parseString; 4494 UnicodeString pattern; 4495 UnicodeString expectedResult; // empty string indicates expected error 4496 } TestDateFormatLeniencyItem; 4497 4498 void DateFormatTest::TestDateFormatLeniency() { 4499 // For details see http://bugs.icu-project.org/trac/ticket/10261 4500 4501 const UDate july022008 = 1215000001979.0; 4502 const TestDateFormatLeniencyItem items[] = { 4503 //locale leniency parse String pattern expected result 4504 { "en", true, UnicodeString("2008-07 02"), UnicodeString("yyyy-LLLL dd"), UnicodeString("2008-July 02") }, 4505 { "en", false, UnicodeString("2008-07 02"), UnicodeString("yyyy-LLLL dd"), UnicodeString("") }, 4506 { "en", true, UnicodeString("2008-Jan 02"), UnicodeString("yyyy-LLL. dd"), UnicodeString("2008-Jan. 02") }, 4507 { "en", false, UnicodeString("2008-Jan 02"), UnicodeString("yyyy-LLL. dd"), UnicodeString("") }, 4508 { "en", true, UnicodeString("2008-Jan--02"), UnicodeString("yyyy-MMM' -- 'dd"), UnicodeString("2008-Jan -- 02") }, 4509 { "en", false, UnicodeString("2008-Jan--02"), UnicodeString("yyyy-MMM' -- 'dd"), UnicodeString("") }, 4510 // terminator 4511 { NULL, true, UnicodeString(""), UnicodeString(""), UnicodeString("") } 4512 }; 4513 UErrorCode status = U_ZERO_ERROR; 4514 LocalPointer<Calendar> cal(Calendar::createInstance(status)); 4515 if (U_FAILURE(status)) { 4516 dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale.")); 4517 return; 4518 } 4519 cal->setTime(july022008, status); 4520 const TestDateFormatLeniencyItem * itemPtr; 4521 LocalPointer<SimpleDateFormat> sdmft; 4522 for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) { 4523 4524 Locale locale = Locale::createFromName(itemPtr->locale); 4525 status = U_ZERO_ERROR; 4526 ParsePosition pos(0); 4527 sdmft.adoptInsteadAndCheckErrorCode(new SimpleDateFormat(itemPtr->pattern, locale, status), status); 4528 if (U_FAILURE(status)) { 4529 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status)); 4530 continue; 4531 } 4532 sdmft->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->leniency, status). 4533 setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->leniency, status). 4534 setBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, itemPtr->leniency, status); 4535 UDate d = sdmft->parse(itemPtr->parseString, pos); 4536 4537 if(itemPtr->expectedResult.length() == 0) { 4538 if(pos.getErrorIndex() != -1) { 4539 continue; 4540 } else { 4541 errln("error: unexpected parse success - " + itemPtr->parseString + 4542 " - pattern " + itemPtr->pattern + 4543 " - error index " + pos.getErrorIndex() + 4544 " - leniency " + itemPtr->leniency); 4545 continue; 4546 } 4547 } 4548 if(pos.getErrorIndex() != -1) { 4549 errln("error: parse error for string - " + itemPtr->parseString + 4550 " - pattern " + itemPtr->pattern + 4551 " - idx " + pos.getIndex() + 4552 " - error index "+pos.getErrorIndex() + 4553 " - leniency " + itemPtr->leniency); 4554 continue; 4555 } 4556 4557 UnicodeString formatResult(""); 4558 sdmft->format(d, formatResult); 4559 if(formatResult.compare(itemPtr->expectedResult) != 0) { 4560 errln("error: unexpected format result. pattern["+itemPtr->pattern+"] expected[" + itemPtr->expectedResult + "] but result was[" + formatResult + "]"); 4561 continue; 4562 } else { 4563 logln("formatted results match! - " + formatResult); 4564 } 4565 4566 } 4567 } 4568 4569 4570 typedef struct { 4571 UBool leniency; 4572 UnicodeString parseString; 4573 UnicodeString pattern; 4574 UnicodeString expectedResult; // empty string indicates expected error 4575 } TestMultiPatternMatchItem; 4576 4577 void DateFormatTest::TestParseMultiPatternMatch() { 4578 // For details see http://bugs.icu-project.org/trac/ticket/10336 4579 const TestMultiPatternMatchItem items[] = { 4580 // leniency parse String pattern expected result 4581 {true, UnicodeString("2013-Sep 13"), UnicodeString("yyyy-MMM dd"), UnicodeString("2013-Sep 13")}, 4582 {true, UnicodeString("2013-September 14"), UnicodeString("yyyy-MMM dd"), UnicodeString("2013-Sep 14")}, 4583 {false, UnicodeString("2013-September 15"), UnicodeString("yyyy-MMM dd"), UnicodeString("")}, 4584 {false, UnicodeString("2013-September 16"), UnicodeString("yyyy-MMMM dd"), UnicodeString("2013-September 16")}, 4585 {true, UnicodeString("2013-Sep 17"), UnicodeString("yyyy-LLL dd"), UnicodeString("2013-Sep 17")}, 4586 {true, UnicodeString("2013-September 18"), UnicodeString("yyyy-LLL dd"), UnicodeString("2013-Sep 18")}, 4587 {false, UnicodeString("2013-September 19"), UnicodeString("yyyy-LLL dd"), UnicodeString("")}, 4588 {false, UnicodeString("2013-September 20"), UnicodeString("yyyy-LLLL dd"), UnicodeString("2013-September 20")}, 4589 {true, UnicodeString("2013 Sat Sep 21"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("2013 Sat Sep 21")}, 4590 {true, UnicodeString("2013 Sunday Sep 22"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("2013 Sun Sep 22")}, 4591 {false, UnicodeString("2013 Monday Sep 23"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("")}, 4592 {false, UnicodeString("2013 Tuesday Sep 24"), UnicodeString("yyyy EEEE MMM dd"), UnicodeString("2013 Tuesday Sep 24")}, 4593 {true, UnicodeString("2013 Wed Sep 25"), UnicodeString("yyyy eee MMM dd"), UnicodeString("2013 Wed Sep 25")}, 4594 {true, UnicodeString("2013 Thu Sep 26"), UnicodeString("yyyy eee MMM dd"), UnicodeString("2013 Thu Sep 26")}, 4595 {false, UnicodeString("2013 Friday Sep 27"), UnicodeString("yyyy eee MMM dd"), UnicodeString("")}, 4596 {false, UnicodeString("2013 Saturday Sep 28"), UnicodeString("yyyy eeee MMM dd"), UnicodeString("2013 Saturday Sep 28")}, 4597 {true, UnicodeString("2013 Sun Sep 29"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("2013 Sun Sep 29")}, 4598 {true, UnicodeString("2013 Monday Sep 30"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("2013 Mon Sep 30")}, 4599 {false, UnicodeString("2013 Sunday Oct 13"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("")}, 4600 {false, UnicodeString("2013 Monday Oct 14"), UnicodeString("yyyy cccc MMM dd"), UnicodeString("2013 Monday Oct 14")}, 4601 {true, UnicodeString("2013 Oct 15 Q4"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 15 Q4")}, 4602 {true, UnicodeString("2013 Oct 16 4th quarter"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 16 Q4")}, 4603 {false, UnicodeString("2013 Oct 17 4th quarter"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("")}, 4604 {false, UnicodeString("2013 Oct 18 Q4"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 18 Q4")}, 4605 {true, UnicodeString("2013 Oct 19 Q4"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 19 4th quarter")}, 4606 {true, UnicodeString("2013 Oct 20 4th quarter"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 20 4th quarter")}, 4607 {false, UnicodeString("2013 Oct 21 Q4"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("")}, 4608 {false, UnicodeString("2013 Oct 22 4th quarter"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 22 4th quarter")}, 4609 {false, UnicodeString("--end--"), UnicodeString(""), UnicodeString("")}, 4610 }; 4611 4612 UErrorCode status = U_ZERO_ERROR; 4613 LocalPointer<Calendar> cal(Calendar::createInstance(status)); 4614 if (U_FAILURE(status)) { 4615 dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale.")); 4616 return; 4617 } 4618 const TestMultiPatternMatchItem * itemPtr; 4619 DateFormat* sdmft = DateFormat::createDateInstance(); 4620 if (sdmft == NULL) { 4621 dataerrln(UnicodeString("FAIL: Unable to create DateFormat")); 4622 return; 4623 } 4624 for (itemPtr = items; itemPtr->parseString != "--end--"; itemPtr++ ) { 4625 status = U_ZERO_ERROR; 4626 ParsePosition pos(0); 4627 ((SimpleDateFormat*) sdmft)->applyPattern(itemPtr->pattern); 4628 if (U_FAILURE(status)) { 4629 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status)); 4630 continue; 4631 } 4632 sdmft->setBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, itemPtr->leniency, status); 4633 UDate d = sdmft->parse(itemPtr->parseString, pos); 4634 4635 if(itemPtr->expectedResult.length() == 0) { 4636 if(pos.getErrorIndex() != -1) { 4637 continue; 4638 } else { 4639 errln("error: unexpected parse success - " + itemPtr->parseString + 4640 " - error index " + pos.getErrorIndex() + 4641 " - leniency " + itemPtr->leniency); 4642 continue; 4643 } 4644 } 4645 if(pos.getErrorIndex() != -1) { 4646 errln("error: parse error for string - " +itemPtr->parseString + " -- idx["+pos.getIndex()+"] errIdx["+pos.getErrorIndex()+"]"); 4647 continue; 4648 } 4649 4650 UnicodeString formatResult(""); 4651 sdmft->format(d, formatResult); 4652 if(formatResult.compare(itemPtr->expectedResult) != 0) { 4653 errln("error: unexpected format result. expected[" + itemPtr->expectedResult + "] but result was[" + formatResult + "]"); 4654 } else { 4655 logln("formatted results match! - " + formatResult); 4656 } 4657 } 4658 delete sdmft; 4659 } 4660 4661 void DateFormatTest::TestParseLeniencyAPIs() { 4662 UErrorCode status = U_ZERO_ERROR; 4663 LocalPointer<DateFormat> dateFormat(DateFormat::createDateInstance()); 4664 DateFormat *fmt = dateFormat.getAlias(); 4665 if (fmt == NULL) { 4666 dataerrln("Failed calling dateFormat.getAlias()"); 4667 return; 4668 } 4669 4670 assertTrue("isLenient default", fmt->isLenient()); 4671 assertTrue("isCalendarLenient default", fmt->isCalendarLenient()); 4672 assertTrue("ALLOW_WHITESPACE default", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)); 4673 assertTrue("ALLOW_NUMERIC default", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)); 4674 assertTrue("PARTIAL_MATCH default", fmt->getBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, status)); 4675 assertTrue("MULTIPLE_PATTERNS default", fmt->getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status)); 4676 4677 // Set calendar to strict 4678 fmt->setCalendarLenient(FALSE); 4679 4680 assertFalse("isLeninent after setCalendarLenient(FALSE)", fmt->isLenient()); 4681 assertFalse("isCalendarLenient after setCalendarLenient(FALSE)", fmt->isCalendarLenient()); 4682 assertTrue("ALLOW_WHITESPACE after setCalendarLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)); 4683 assertTrue("ALLOW_NUMERIC after setCalendarLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)); 4684 4685 // Set to strict 4686 fmt->setLenient(FALSE); 4687 4688 assertFalse("isLeninent after setLenient(FALSE)", fmt->isLenient()); 4689 assertFalse("isCalendarLenient after setLenient(FALSE)", fmt->isCalendarLenient()); 4690 assertFalse("ALLOW_WHITESPACE after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)); 4691 assertFalse("ALLOW_NUMERIC after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)); 4692 // These two boolean attributes are NOT affected according to the API specification 4693 assertTrue("PARTIAL_MATCH after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, status)); 4694 assertTrue("MULTIPLE_PATTERNS after setLenient(FALSE)", fmt->getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status)); 4695 4696 // Allow white space leniency 4697 fmt->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, TRUE, status); 4698 4699 assertFalse("isLeninent after ALLOW_WHITESPACE/TRUE", fmt->isLenient()); 4700 assertFalse("isCalendarLenient after ALLOW_WHITESPACE/TRUE", fmt->isCalendarLenient()); 4701 assertTrue("ALLOW_WHITESPACE after ALLOW_WHITESPACE/TRUE", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)); 4702 assertFalse("ALLOW_NUMERIC after ALLOW_WHITESPACE/TRUE", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)); 4703 4704 // Set to lenient 4705 fmt->setLenient(TRUE); 4706 4707 assertTrue("isLenient after setLenient(TRUE)", fmt->isLenient()); 4708 assertTrue("isCalendarLenient after setLenient(TRUE)", fmt->isCalendarLenient()); 4709 assertTrue("ALLOW_WHITESPACE after setLenient(TRUE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)); 4710 assertTrue("ALLOW_NUMERIC after setLenient(TRUE)", fmt->getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)); 4711 } 4712 4713 void DateFormatTest::TestNumberFormatOverride() { 4714 UErrorCode status = U_ZERO_ERROR; 4715 UnicodeString fields = (UnicodeString) "M"; 4716 4717 LocalPointer<SimpleDateFormat> fmt; 4718 fmt.adoptInsteadAndCheckErrorCode(new SimpleDateFormat((UnicodeString)"MM d", status), status); 4719 if (!assertSuccess("SimpleDateFormat with pattern MM d", status)) { 4720 return; 4721 } 4722 4723 4724 for(int i=0; i<3; i++){ 4725 NumberFormat* check_nf = NumberFormat::createInstance(Locale("en_US"), status); 4726 assertSuccess("NumberFormat en_US", status); 4727 fmt->adoptNumberFormat(fields, check_nf, status); 4728 assertSuccess("adoptNumberFormat check_nf", status); 4729 4730 const NumberFormat* get_nf = fmt->getNumberFormatForField((UChar)0x004D /*'M'*/); 4731 if (get_nf != check_nf) errln("FAIL: getter and setter do not work"); 4732 } 4733 NumberFormat* check_nf = NumberFormat::createInstance(Locale("en_US"), status); 4734 assertSuccess("NumberFormat en_US", status); 4735 fmt->adoptNumberFormat(check_nf); // make sure using the same NF will not crash 4736 4737 const char * DATA [][2] = { 4738 { "", "\\u521D\\u516D \\u5341\\u4E94"}, 4739 { "M", "\\u521D\\u516D 15"}, 4740 { "Mo", "\\u521D\\u516D 15"}, 4741 { "Md", "\\u521D\\u516D \\u5341\\u4E94"}, 4742 { "MdMMd", "\\u521D\\u516D \\u5341\\u4E94"}, 4743 { "mixed", "\\u521D\\u516D \\u5341\\u4E94"} 4744 }; 4745 4746 UDate test_date = date(97, 6 - 1, 15); 4747 4748 for(int i=0; i < UPRV_LENGTHOF(DATA); i++){ 4749 fields = DATA[i][0]; 4750 4751 LocalPointer<SimpleDateFormat> fmt; 4752 fmt.adoptInsteadAndCheckErrorCode(new SimpleDateFormat((UnicodeString)"MM d", status), status); 4753 assertSuccess("SimpleDateFormat with pattern MM d", status); 4754 NumberFormat* overrideNF = NumberFormat::createInstance(Locale::createFromName("zh@numbers=hanidays"),status); 4755 assertSuccess("NumberFormat zh@numbers=hanidays", status); 4756 4757 if (fields == (UnicodeString) "") { // use the one w/o fields 4758 fmt->adoptNumberFormat(overrideNF); 4759 } else if (fields == (UnicodeString) "mixed") { // set 1 field at first but then full override, both(M & d) should be override 4760 NumberFormat* singleOverrideNF = NumberFormat::createInstance(Locale::createFromName("en@numbers=hebr"),status); 4761 assertSuccess("NumberFormat en@numbers=hebr", status); 4762 4763 fields = (UnicodeString) "M"; 4764 fmt->adoptNumberFormat(fields, singleOverrideNF, status); 4765 assertSuccess("adoptNumberFormat singleOverrideNF", status); 4766 4767 fmt->adoptNumberFormat(overrideNF); 4768 } else if (fields == (UnicodeString) "Mo"){ // o is invlid field 4769 fmt->adoptNumberFormat(fields, overrideNF, status); 4770 if(status == U_INVALID_FORMAT_ERROR) { 4771 status = U_ZERO_ERROR; 4772 continue; 4773 } 4774 } else { 4775 fmt->adoptNumberFormat(fields, overrideNF, status); 4776 assertSuccess("adoptNumberFormat overrideNF", status); 4777 } 4778 4779 UnicodeString result; 4780 FieldPosition pos(FieldPosition::DONT_CARE); 4781 fmt->format(test_date,result, pos); 4782 4783 UnicodeString expected = ((UnicodeString)DATA[i][1]).unescape();; 4784 4785 if (result != expected) 4786 errln("FAIL: Expected " + expected + " get: " + result); 4787 } 4788 } 4789 4790 void DateFormatTest::TestCreateInstanceForSkeleton() { 4791 UErrorCode status = U_ZERO_ERROR; 4792 LocalPointer<DateFormat> fmt(DateFormat::createInstanceForSkeleton( 4793 "yMMMMd", "en", status)); 4794 if (!assertSuccess("Create with pattern yMMMMd", status)) { 4795 return; 4796 } 4797 UnicodeString result; 4798 FieldPosition pos(FieldPosition::DONT_CARE); 4799 fmt->format(date(98, 5-1, 25), result, pos); 4800 assertEquals("format yMMMMd", "May 25, 1998", result); 4801 fmt.adoptInstead(DateFormat::createInstanceForSkeleton( 4802 "yMd", "en", status)); 4803 if (!assertSuccess("Create with pattern yMd", status)) { 4804 return; 4805 } 4806 result.remove(); 4807 fmt->format(date(98, 5-1, 25), result, pos); 4808 assertEquals("format yMd", "5/25/1998", result); 4809 } 4810 4811 void DateFormatTest::TestCreateInstanceForSkeletonDefault() { 4812 UErrorCode status = U_ZERO_ERROR; 4813 Locale savedLocale; 4814 Locale::setDefault(Locale::getUS(), status); 4815 LocalPointer<DateFormat> fmt(DateFormat::createInstanceForSkeleton( 4816 "yMMMd", status)); 4817 Locale::setDefault(savedLocale, status); 4818 if (!assertSuccess("Create with pattern yMMMd", status)) { 4819 return; 4820 } 4821 UnicodeString result; 4822 FieldPosition pos(FieldPosition::DONT_CARE); 4823 fmt->format(date(98, 5-1, 25), result, pos); 4824 assertEquals("format yMMMd", "May 25, 1998", result); 4825 } 4826 4827 void DateFormatTest::TestCreateInstanceForSkeletonWithCalendar() { 4828 UErrorCode status = U_ZERO_ERROR; 4829 LocalPointer<DateFormat> fmt( 4830 DateFormat::createInstanceForSkeleton( 4831 Calendar::createInstance( 4832 TimeZone::createTimeZone("GMT-3:00"), 4833 status), 4834 "yMdHm", "en", status)); 4835 if (!assertSuccess("Create with pattern yMMMMd", status)) { 4836 return; 4837 } 4838 UnicodeString result; 4839 FieldPosition pos(FieldPosition::DONT_CARE); 4840 4841 LocalPointer<Calendar> cal(Calendar::createInstance( 4842 TimeZone::createTimeZone("GMT-7:00"), 4843 status)); 4844 if (!assertSuccess("Creating GMT-7 time zone failed", status)) { 4845 return; 4846 } 4847 cal->clear(); 4848 cal->set(1998, 5-1, 25, 0, 0, 0); 4849 4850 // date format time zone should be 4 hours ahead. 4851 fmt->format(cal->getTime(status), result, pos); 4852 assertEquals("format yMdHm", "5/25/1998, 04:00", result); 4853 assertSuccess("", status); 4854 } 4855 4856 void DateFormatTest::TestDFSCreateForLocaleNonGregorianLocale() { 4857 UErrorCode status = U_ZERO_ERROR; 4858 Locale fa("fa"); 4859 LocalPointer<DateFormatSymbols> sym( 4860 DateFormatSymbols::createForLocale(fa, status)); 4861 if (!assertSuccess("", status)) { 4862 return; 4863 } 4864 4865 // Android: All locales default to Gregorian calendar: 4866 int32_t count; 4867 const UnicodeString *months = sym->getShortMonths(count); 4868 4869 // First persian month. 4870 UnicodeString expected("\\u0698\\u0627\\u0646\\u0648\\u06CC\\u0647\\u0654"); // Android-changed 4871 assertEquals("", expected.unescape(), months[0]); 4872 } 4873 4874 void DateFormatTest::TestDFSCreateForLocaleWithCalendarInLocale() { 4875 UErrorCode status = U_ZERO_ERROR; 4876 Locale en_heb("en@calendar=hebrew"); 4877 LocalPointer<DateFormatSymbols> sym( 4878 DateFormatSymbols::createForLocale(en_heb, status)); 4879 if (!assertSuccess("", status)) { 4880 return; 4881 } 4882 4883 // We should get the months of the hebrew calendar, not the gregorian 4884 // calendar. 4885 int32_t count; 4886 const UnicodeString *months = sym->getShortMonths(count); 4887 4888 // First hebrew month. 4889 UnicodeString expected("Tishri"); 4890 assertEquals("", expected, months[0]); 4891 } 4892 4893 void DateFormatTest::TestChangeCalendar() { 4894 UErrorCode status = U_ZERO_ERROR; 4895 Locale en("en"); 4896 Locale en_heb("en@calendar=hebrew"); 4897 LocalPointer<DateFormat> fmt( 4898 DateFormat::createInstanceForSkeleton("yMMMd", en, status)); 4899 if (!assertSuccess("", status)) { 4900 return; 4901 } 4902 fmt->adoptCalendar(Calendar::createInstance(en_heb, status)); 4903 if (!assertSuccess("", status)) { 4904 return; 4905 } 4906 UnicodeString result; 4907 FieldPosition pos(FieldPosition::DONT_CARE); 4908 fmt->format(date(98, 5-1, 25), result, pos); 4909 assertEquals("format yMMMd", "Iyar 29, 5758", result); 4910 } 4911 4912 void DateFormatTest::TestPatternFromSkeleton() { 4913 static const struct { 4914 const Locale& locale; 4915 const char* const skeleton; 4916 const char* const pattern; 4917 } TESTDATA[] = { 4918 // Ticket #11985 4919 {Locale::getEnglish(), "jjmm", "h:mm a"}, 4920 {Locale::getEnglish(), "JJmm", "hh:mm"}, 4921 {Locale::getGerman(), "jjmm", "HH:mm"}, 4922 {Locale::getGerman(), "JJmm", "HH:mm"} 4923 }; 4924 4925 for (size_t i = 0; i < UPRV_LENGTHOF(TESTDATA); i++) { 4926 UErrorCode status = U_ZERO_ERROR; 4927 LocalPointer<DateFormat> fmt( 4928 DateFormat::createInstanceForSkeleton( 4929 TESTDATA[i].skeleton, TESTDATA[i].locale, status)); 4930 if (!assertSuccess("createInstanceForSkeleton", status)) { 4931 return; 4932 } 4933 UnicodeString pattern; 4934 static_cast<const SimpleDateFormat*>(fmt.getAlias())->toPattern(pattern); 4935 assertEquals("Format pattern", TESTDATA[i].pattern, pattern); 4936 } 4937 } 4938 4939 void DateFormatTest::TestAmPmMidnightNoon() { 4940 // Some times on 2015-11-13 (UTC+0). 4941 UDate k000000 = 1447372800000.0; 4942 UDate k000030 = 1447372830000.0; 4943 UDate k003000 = 1447374600000.0; 4944 UDate k060000 = 1447394400000.0; 4945 UDate k120000 = 1447416000000.0; 4946 UDate k180000 = 1447437600000.0; 4947 4948 UErrorCode errorCode = U_ZERO_ERROR; 4949 SimpleDateFormat sdf(UnicodeString(), errorCode); 4950 if (U_FAILURE(errorCode)) { 4951 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode)); 4952 return; 4953 } 4954 const TimeZone *tz = TimeZone::getGMT(); 4955 sdf.setTimeZone(*tz); 4956 UnicodeString out; 4957 4958 // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day. 4959 // For ICU 57 output of "midnight" is temporarily suppressed. 4960 4961 // Short. 4962 sdf.applyPattern(UnicodeString("hh:mm:ss bbb")); 4963 4964 // assertEquals("hh:mm:ss bbb | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove())); 4965 assertEquals("hh:mm:ss bbb | 00:00:00", "12:00:00 AM", sdf.format(k000000, out.remove())); 4966 assertEquals("hh:mm:ss bbb | 00:00:30", "12:00:30 AM", sdf.format(k000030, out.remove())); 4967 assertEquals("hh:mm:ss bbb | 00:30:00", "12:30:00 AM", sdf.format(k003000, out.remove())); 4968 assertEquals("hh:mm:ss bbb | 06:00:00", "06:00:00 AM", sdf.format(k060000, out.remove())); 4969 assertEquals("hh:mm:ss bbb | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove())); 4970 assertEquals("hh:mm:ss bbb | 18:00:00", "06:00:00 PM", sdf.format(k180000, out.remove())); 4971 4972 sdf.applyPattern(UnicodeString("hh:mm bbb")); 4973 4974 // assertEquals("hh:mm bbb | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove())); 4975 assertEquals("hh:mm bbb | 00:00:00", "12:00 AM", sdf.format(k000000, out.remove())); 4976 // assertEquals("hh:mm bbb | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove())); 4977 assertEquals("hh:mm bbb | 00:00:30", "12:00 AM", sdf.format(k000030, out.remove())); 4978 assertEquals("hh:mm bbb | 00:30:00", "12:30 AM", sdf.format(k003000, out.remove())); 4979 4980 sdf.applyPattern(UnicodeString("hh bbb")); 4981 4982 // assertEquals("hh bbb | 00:00:00", "12 midnight", sdf.format(k000000, out.remove())); 4983 assertEquals("hh bbb | 00:00:00", "12 AM", sdf.format(k000000, out.remove())); 4984 // assertEquals("hh bbb | 00:00:30", "12 midnight", sdf.format(k000030, out.remove())); 4985 assertEquals("hh bbb | 00:00:30", "12 AM", sdf.format(k000030, out.remove())); 4986 // assertEquals("hh bbb | 00:30:00", "12 midnight", sdf.format(k003000, out.remove())); 4987 assertEquals("hh bbb | 00:30:00", "12 AM", sdf.format(k003000, out.remove())); 4988 4989 // Wide. 4990 sdf.applyPattern(UnicodeString("hh:mm:ss bbbb")); 4991 4992 // assertEquals("hh:mm:ss bbbb | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove())); 4993 assertEquals("hh:mm:ss bbbb | 00:00:00", "12:00:00 AM", sdf.format(k000000, out.remove())); 4994 assertEquals("hh:mm:ss bbbb | 00:00:30", "12:00:30 AM", sdf.format(k000030, out.remove())); 4995 assertEquals("hh:mm:ss bbbb | 00:30:00", "12:30:00 AM", sdf.format(k003000, out.remove())); 4996 assertEquals("hh:mm:ss bbbb | 06:00:00", "06:00:00 AM", sdf.format(k060000, out.remove())); 4997 assertEquals("hh:mm:ss bbbb | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove())); 4998 assertEquals("hh:mm:ss bbbb | 18:00:00", "06:00:00 PM", sdf.format(k180000, out.remove())); 4999 5000 sdf.applyPattern(UnicodeString("hh:mm bbbb")); 5001 5002 // assertEquals("hh:mm bbbb | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove())); 5003 assertEquals("hh:mm bbbb | 00:00:00", "12:00 AM", sdf.format(k000000, out.remove())); 5004 // assertEquals("hh:mm bbbb | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove())); 5005 assertEquals("hh:mm bbbb | 00:00:30", "12:00 AM", sdf.format(k000030, out.remove())); 5006 assertEquals("hh:mm bbbb | 00:30:00", "12:30 AM", sdf.format(k003000, out.remove())); 5007 5008 sdf.applyPattern(UnicodeString("hh bbbb")); 5009 5010 // assertEquals("hh bbbb | 00:00:00", "12 midnight", sdf.format(k000000, out.remove())); 5011 assertEquals("hh bbbb | 00:00:00", "12 AM", sdf.format(k000000, out.remove())); 5012 // assertEquals("hh bbbb | 00:00:30", "12 midnight", sdf.format(k000030, out.remove())); 5013 assertEquals("hh bbbb | 00:00:30", "12 AM", sdf.format(k000030, out.remove())); 5014 // assertEquals("hh bbbb | 00:30:00", "12 midnight", sdf.format(k003000, out.remove())); 5015 assertEquals("hh bbbb | 00:30:00", "12 AM", sdf.format(k003000, out.remove())); 5016 5017 // Narrow. 5018 sdf.applyPattern(UnicodeString("hh:mm:ss bbbbb")); 5019 5020 // assertEquals("hh:mm:ss bbbbb | 00:00:00", "12:00:00 mi", sdf.format(k000000, out.remove())); 5021 assertEquals("hh:mm:ss bbbbb | 00:00:00", "12:00:00 a", sdf.format(k000000, out.remove())); 5022 assertEquals("hh:mm:ss bbbbb | 00:00:30", "12:00:30 a", sdf.format(k000030, out.remove())); 5023 assertEquals("hh:mm:ss bbbbb | 00:30:00", "12:30:00 a", sdf.format(k003000, out.remove())); 5024 assertEquals("hh:mm:ss bbbbb | 06:00:00", "06:00:00 a", sdf.format(k060000, out.remove())); 5025 assertEquals("hh:mm:ss bbbbb | 12:00:00", "12:00:00 n", sdf.format(k120000, out.remove())); 5026 assertEquals("hh:mm:ss bbbbb | 18:00:00", "06:00:00 p", sdf.format(k180000, out.remove())); 5027 5028 sdf.applyPattern(UnicodeString("hh:mm bbbbb")); 5029 5030 // assertEquals("hh:mm bbbbb | 00:00:00", "12:00 mi", sdf.format(k000000, out.remove())); 5031 assertEquals("hh:mm bbbbb | 00:00:00", "12:00 a", sdf.format(k000000, out.remove())); 5032 // assertEquals("hh:mm bbbbb | 00:00:30", "12:00 mi", sdf.format(k000030, out.remove())); 5033 assertEquals("hh:mm bbbbb | 00:00:30", "12:00 a", sdf.format(k000030, out.remove())); 5034 assertEquals("hh:mm bbbbb | 00:30:00", "12:30 a", sdf.format(k003000, out.remove())); 5035 5036 sdf.applyPattern(UnicodeString("hh bbbbb")); 5037 5038 // assertEquals("hh bbbbb | 00:00:00", "12 mi", sdf.format(k000000, out.remove())); 5039 assertEquals("hh bbbbb | 00:00:00", "12 a", sdf.format(k000000, out.remove())); 5040 // assertEquals("hh bbbbb | 00:00:30", "12 mi", sdf.format(k000030, out.remove())); 5041 assertEquals("hh bbbbb | 00:00:30", "12 a", sdf.format(k000030, out.remove())); 5042 // assertEquals("hh bbbbb | 00:30:00", "12 mi", sdf.format(k003000, out.remove())); 5043 assertEquals("hh bbbbb | 00:30:00", "12 a", sdf.format(k003000, out.remove())); 5044 } 5045 5046 void DateFormatTest::TestFlexibleDayPeriod() { 5047 // Some times on 2015-11-13 (UTC+0). 5048 UDate k000000 = 1447372800000.0; 5049 UDate k000030 = 1447372830000.0; 5050 UDate k003000 = 1447374600000.0; 5051 UDate k060000 = 1447394400000.0; 5052 UDate k120000 = 1447416000000.0; 5053 UDate k180000 = 1447437600000.0; 5054 5055 UErrorCode errorCode = U_ZERO_ERROR; 5056 SimpleDateFormat sdf(UnicodeString(), errorCode); 5057 if (U_FAILURE(errorCode)) { 5058 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode)); 5059 return; 5060 } 5061 const TimeZone *tz = TimeZone::getGMT(); 5062 sdf.setTimeZone(*tz); 5063 UnicodeString out; 5064 5065 // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day. 5066 // For ICU 57 output of "midnight" is temporarily suppressed. 5067 5068 // Short. 5069 sdf.applyPattern(UnicodeString("hh:mm:ss BBB")); 5070 5071 // assertEquals("hh:mm:ss BBB | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove())); 5072 assertEquals("hh:mm:ss BBB | 00:00:00", "12:00:00 at night", sdf.format(k000000, out.remove())); 5073 assertEquals("hh:mm:ss BBB | 00:00:30", "12:00:30 at night", sdf.format(k000030, out.remove())); 5074 assertEquals("hh:mm:ss BBB | 00:30:00", "12:30:00 at night", sdf.format(k003000, out.remove())); 5075 assertEquals("hh:mm:ss BBB | 06:00:00", "06:00:00 in the morning", sdf.format(k060000, out.remove())); 5076 assertEquals("hh:mm:ss BBB | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove())); 5077 assertEquals("hh:mm:ss BBB | 18:00:00", "06:00:00 in the evening", sdf.format(k180000, out.remove())); 5078 5079 sdf.applyPattern(UnicodeString("hh:mm BBB")); 5080 5081 // assertEquals("hh:mm BBB | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove())); 5082 assertEquals("hh:mm BBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove())); 5083 // assertEquals("hh:mm BBB | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove())); 5084 assertEquals("hh:mm BBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove())); 5085 assertEquals("hh:mm BBB | 00:30:00", "12:30 at night", sdf.format(k003000, out.remove())); 5086 5087 sdf.applyPattern(UnicodeString("hh BBB")); 5088 5089 // assertEquals("hh BBB | 00:00:00", "12 midnight", sdf.format(k000000, out.remove())); 5090 assertEquals("hh BBB | 00:00:30", "12 at night", sdf.format(k000030, out.remove())); 5091 // assertEquals("hh BBB | 00:00:30", "12 midnight", sdf.format(k000030, out.remove())); 5092 assertEquals("hh BBB | 00:00:30", "12 at night", sdf.format(k000030, out.remove())); 5093 // assertEquals("hh BBB | 00:30:00", "12 midnight", sdf.format(k003000, out.remove())); 5094 assertEquals("hh BBB | 00:30:00", "12 at night", sdf.format(k003000, out.remove())); 5095 5096 // Wide. 5097 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB")); 5098 5099 // assertEquals("hh:mm:ss BBBB | 00:00:00", "12:00:00 midnight", sdf.format(k000000, out.remove())); 5100 assertEquals("hh:mm:ss BBBB | 00:00:00", "12:00:00 at night", sdf.format(k000000, out.remove())); 5101 assertEquals("hh:mm:ss BBBB | 00:00:30", "12:00:30 at night", sdf.format(k000030, out.remove())); 5102 assertEquals("hh:mm:ss BBBB | 00:30:00", "12:30:00 at night", sdf.format(k003000, out.remove())); 5103 assertEquals("hh:mm:ss BBBB | 06:00:00", "06:00:00 in the morning", sdf.format(k060000, out.remove())); 5104 assertEquals("hh:mm:ss BBBB | 12:00:00", "12:00:00 noon", sdf.format(k120000, out.remove())); 5105 assertEquals("hh:mm:ss BBBB | 18:00:00", "06:00:00 in the evening", sdf.format(k180000, out.remove())); 5106 5107 sdf.applyPattern(UnicodeString("hh:mm BBBB")); 5108 5109 // assertEquals("hh:mm BBBB | 00:00:00", "12:00 midnight", sdf.format(k000000, out.remove())); 5110 assertEquals("hh:mm BBBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove())); 5111 // assertEquals("hh:mm BBBB | 00:00:30", "12:00 midnight", sdf.format(k000030, out.remove())); 5112 assertEquals("hh:mm BBBB | 00:00:30", "12:00 at night", sdf.format(k000030, out.remove())); 5113 assertEquals("hh:mm BBBB | 00:30:00", "12:30 at night", sdf.format(k003000, out.remove())); 5114 5115 sdf.applyPattern(UnicodeString("hh BBBB")); 5116 5117 // assertEquals("hh BBBB | 00:00:00", "12 midnight", sdf.format(k000000, out.remove())); 5118 assertEquals("hh BBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove())); 5119 // assertEquals("hh BBBB | 00:00:30", "12 midnight", sdf.format(k000030, out.remove())); 5120 assertEquals("hh BBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove())); 5121 // assertEquals("hh BBBB | 00:80:00", "12 midnight", sdf.format(k003000, out.remove())); 5122 assertEquals("hh BBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove())); 5123 5124 // Narrow. 5125 sdf.applyPattern(UnicodeString("hh:mm:ss BBBBB")); 5126 5127 // assertEquals("hh:mm:ss BBBBB | 00:00:00", "12:00:00 mi", sdf.format(k000000, out.remove())); 5128 assertEquals("hh:mm:ss BBBBB | 00:00:00", "12:00:00 at night", sdf.format(k000000, out.remove())); 5129 assertEquals("hh:mm:ss BBBBB | 00:00:30", "12:00:30 at night", sdf.format(k000030, out.remove())); 5130 assertEquals("hh:mm:ss BBBBB | 00:30:00", "12:30:00 at night", sdf.format(k003000, out.remove())); 5131 assertEquals("hh:mm:ss BBBBB | 06:00:00", "06:00:00 in the morning", sdf.format(k060000, out.remove())); 5132 assertEquals("hh:mm:ss BBBBB | 12:00:00", "12:00:00 n", sdf.format(k120000, out.remove())); 5133 assertEquals("hh:mm:ss BBBBB | 18:00:00", "06:00:00 in the evening", sdf.format(k180000, out.remove())); 5134 5135 sdf.applyPattern(UnicodeString("hh:mm BBBBB")); 5136 5137 // assertEquals("hh:mm BBBBB | 00:00:00", "12:00 mi", sdf.format(k000000, out.remove())); 5138 assertEquals("hh:mm BBBBB | 00:00:00", "12:00 at night", sdf.format(k000000, out.remove())); 5139 // assertEquals("hh:mm BBBBB | 00:00:30", "12:00 mi", sdf.format(k000030, out.remove())); 5140 assertEquals("hh:mm BBBBB | 00:00:30", "12:00 at night", sdf.format(k000030, out.remove())); 5141 assertEquals("hh:mm BBBBB | 00:30:00", "12:30 at night", sdf.format(k003000, out.remove())); 5142 5143 sdf.applyPattern(UnicodeString("hh BBBBB")); 5144 5145 // assertEquals("hh BBBBB | 00:00:00", "12 mi", sdf.format(k000000, out.remove())); 5146 assertEquals("hh BBBBB | 00:00:00", "12 at night", sdf.format(k000000, out.remove())); 5147 // assertEquals("hh BBBBB | 00:00:30", "12 mi", sdf.format(k000030, out.remove())); 5148 assertEquals("hh BBBBB | 00:00:30", "12 at night", sdf.format(k000030, out.remove())); 5149 // assertEquals("hh BBBBB | 00:30:00", "12 mi", sdf.format(k003000, out.remove())); 5150 assertEquals("hh BBBBB | 00:30:00", "12 at night", sdf.format(k003000, out.remove())); 5151 } 5152 5153 void DateFormatTest::TestDayPeriodWithLocales() { 5154 // Some times on 2015-11-13 (UTC+0). 5155 UDate k000000 = 1447372800000.0; 5156 UDate k010000 = 1447376400000.0; 5157 UDate k120000 = 1447416000000.0; 5158 UDate k220000 = 1447452000000.0; 5159 5160 UErrorCode errorCode = U_ZERO_ERROR; 5161 const TimeZone *tz = TimeZone::getGMT(); 5162 UnicodeString out; 5163 5164 // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day. 5165 // For ICU 57 output of "midnight" and its localized equivalentns is temporarily suppressed. 5166 5167 // Locale de has a word for midnight, but not noon. 5168 SimpleDateFormat sdf(UnicodeString(), Locale::getGermany(), errorCode); 5169 if (U_FAILURE(errorCode)) { 5170 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode)); 5171 return; 5172 } 5173 sdf.setTimeZone(*tz); 5174 5175 sdf.applyPattern(UnicodeString("hh:mm:ss bbbb")); 5176 5177 // assertEquals("hh:mm:ss bbbb | 00:00:00 | de", "12:00:00 Mitternacht", 5178 // sdf.format(k000000, out.remove())); 5179 assertEquals("hh:mm:ss bbbb | 00:00:00 | de", "12:00:00 vorm.", 5180 sdf.format(k000000, out.remove())); 5181 assertEquals("hh:mm:ss bbbb | 12:00:00 | de", "12:00:00 nachm.", 5182 sdf.format(k120000, out.remove())); 5183 5184 // Locale ee has a rule that wraps around midnight (21h - 4h). 5185 sdf = SimpleDateFormat(UnicodeString(), Locale("ee"), errorCode); 5186 sdf.setTimeZone(*tz); 5187 5188 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB")); 5189 5190 assertEquals("hh:mm:ss BBBB | 22:00:00 | ee", UnicodeString("10:00:00 z\\u00E3").unescape(), 5191 sdf.format(k220000, out.remove())); 5192 assertEquals("hh:mm:ss BBBB | 00:00:00 | ee", UnicodeString("12:00:00 z\\u00E3").unescape(), 5193 sdf.format(k000000, out.remove())); 5194 assertEquals("hh:mm:ss BBBB | 01:00:00 | ee", UnicodeString("01:00:00 z\\u00E3").unescape(), 5195 sdf.format(k010000, out.remove())); 5196 5197 // Locale root has rules for AM/PM only. 5198 sdf = SimpleDateFormat(UnicodeString(), Locale("root"), errorCode); 5199 sdf.setTimeZone(*tz); 5200 5201 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB")); 5202 5203 assertEquals("hh:mm:ss BBBB | 00:00:00 | root", "12:00:00 AM", 5204 sdf.format(k000000, out.remove())); 5205 assertEquals("hh:mm:ss BBBB | 12:00:00 | root", "12:00:00 PM", 5206 sdf.format(k120000, out.remove())); 5207 5208 // Empty string should behave exactly as root. 5209 sdf = SimpleDateFormat(UnicodeString(), Locale(""), errorCode); 5210 sdf.setTimeZone(*tz); 5211 5212 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB")); 5213 5214 assertEquals("hh:mm:ss BBBB | 00:00:00 | \"\" (root)", "12:00:00 AM", 5215 sdf.format(k000000, out.remove())); 5216 assertEquals("hh:mm:ss BBBB | 12:00:00 | \"\" (root)", "12:00:00 PM", 5217 sdf.format(k120000, out.remove())); 5218 5219 // Locale en_US should fall back to en. 5220 sdf = SimpleDateFormat(UnicodeString(), Locale("en_US"), errorCode); 5221 sdf.setTimeZone(*tz); 5222 5223 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB")); 5224 5225 // assertEquals("hh:mm:ss BBBB | 00:00:00 | en_US", "12:00:00 midnight", 5226 // sdf.format(k000000, out.remove())); 5227 assertEquals("hh:mm:ss BBBB | 00:00:00 | en_US", "12:00:00 at night", 5228 sdf.format(k000000, out.remove())); 5229 assertEquals("hh:mm:ss BBBB | 01:00:00 | en_US", "01:00:00 at night", 5230 sdf.format(k010000, out.remove())); 5231 assertEquals("hh:mm:ss BBBB | 12:00:00 | en_US", "12:00:00 noon", 5232 sdf.format(k120000, out.remove())); 5233 5234 // Locale es_CO should not fall back to es and should have a 5235 // different string for 1 in the morning. 5236 // (es_CO: "de la manana" (first n has a tilde) vs. es: "de la madrugada") 5237 sdf = SimpleDateFormat(UnicodeString(), Locale("es_CO"), errorCode); 5238 sdf.setTimeZone(*tz); 5239 5240 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB")); 5241 assertEquals("hh:mm:ss BBBB | 01:00:00 | es_CO", UnicodeString("01:00:00 de la ma\\u00F1ana").unescape(), 5242 sdf.format(k010000, out.remove())); 5243 5244 sdf = SimpleDateFormat(UnicodeString(), Locale("es"), errorCode); 5245 sdf.setTimeZone(*tz); 5246 5247 sdf.applyPattern(UnicodeString("hh:mm:ss BBBB")); 5248 assertEquals("hh:mm:ss BBBB | 01:00:00 | es", "01:00:00 de la madrugada", 5249 sdf.format(k010000, out.remove())); 5250 } 5251 5252 void DateFormatTest::TestMinuteSecondFieldsInOddPlaces() { 5253 // Some times on 2015-11-13 (UTC+0). 5254 UDate k000000 = 1447372800000.0; 5255 UDate k000030 = 1447372830000.0; 5256 UDate k003000 = 1447374600000.0; 5257 UDate k060030 = 1447394430000.0; 5258 UDate k063000 = 1447396200000.0; 5259 5260 UErrorCode errorCode = U_ZERO_ERROR; 5261 const TimeZone *tz = TimeZone::getGMT(); 5262 UnicodeString out; 5263 5264 // Note: "midnight" can be ambiguous as to whether it refers to beginning of day or end of day. 5265 // For ICU 57 output of "midnight" is temporarily suppressed. 5266 5267 // Seconds field is not present. 5268 5269 // Apply pattern through constructor to make sure parsePattern() is called during initialization. 5270 SimpleDateFormat sdf(UnicodeString("hh:mm 'ss' bbbb"), errorCode); 5271 if (U_FAILURE(errorCode)) { 5272 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode)); 5273 return; 5274 } 5275 sdf.setTimeZone(*tz); 5276 5277 // assertEquals("hh:mm 'ss' bbbb | 00:00:30", "12:00 ss midnight", 5278 // sdf.format(k000030, out.remove())); 5279 assertEquals("hh:mm 'ss' bbbb | 00:00:30", "12:00 ss AM", 5280 sdf.format(k000030, out.remove())); 5281 assertEquals("hh:mm 'ss' bbbb | 06:00:30", "06:00 ss AM", 5282 sdf.format(k060030, out.remove())); 5283 5284 sdf.applyPattern(UnicodeString("hh:mm 'ss' BBBB")); 5285 5286 // assertEquals("hh:mm 'ss' BBBB | 00:00:30", "12:00 ss midnight", 5287 // sdf.format(k000030, out.remove())); 5288 assertEquals("hh:mm 'ss' BBBB | 00:00:30", "12:00 ss at night", 5289 sdf.format(k000030, out.remove())); 5290 assertEquals("hh:mm 'ss' BBBB | 06:00:30", "06:00 ss in the morning", 5291 sdf.format(k060030, out.remove())); 5292 5293 // Minutes field is not present. 5294 sdf.applyPattern(UnicodeString("hh 'mm ss' bbbb")); 5295 5296 // assertEquals("hh 'mm ss' bbbb | 00:30:00", "12 mm ss midnight", 5297 // sdf.format(k003000, out.remove())); 5298 assertEquals("hh 'mm ss' bbbb | 00:30:00", "12 mm ss AM", 5299 sdf.format(k003000, out.remove())); 5300 assertEquals("hh 'mm ss' bbbb | 06:30:00", "06 mm ss AM", 5301 sdf.format(k063000, out.remove())); 5302 5303 sdf.applyPattern(UnicodeString("hh 'mm ss' BBBB")); 5304 5305 // assertEquals("hh 'mm ss' BBBB | 00:30:00", "12 mm ss midnight", 5306 // sdf.format(k003000, out.remove())); 5307 assertEquals("hh 'mm ss' BBBB | 00:30:00", "12 mm ss at night", 5308 sdf.format(k003000, out.remove())); 5309 assertEquals("hh 'mm ss' BBBB | 06:30:00", "06 mm ss in the morning", 5310 sdf.format(k063000, out.remove())); 5311 5312 // Minutes and seconds fields appear after day periods. 5313 sdf.applyPattern(UnicodeString("bbbb hh:mm:ss")); 5314 5315 // assertEquals("bbbb hh:mm:ss | 00:00:00", "midnight 12:00:00", 5316 // sdf.format(k000000, out.remove())); 5317 assertEquals("bbbb hh:mm:ss | 00:00:00", "AM 12:00:00", 5318 sdf.format(k000000, out.remove())); 5319 assertEquals("bbbb hh:mm:ss | 00:00:30", "AM 12:00:30", 5320 sdf.format(k000030, out.remove())); 5321 assertEquals("bbbb hh:mm:ss | 00:30:00", "AM 12:30:00", 5322 sdf.format(k003000, out.remove())); 5323 5324 sdf.applyPattern(UnicodeString("BBBB hh:mm:ss")); 5325 5326 // assertEquals("BBBB hh:mm:ss | 00:00:00", "midnight 12:00:00", 5327 // sdf.format(k000000, out.remove())); 5328 assertEquals("BBBB hh:mm:ss | 00:00:00", "at night 12:00:00", 5329 sdf.format(k000000, out.remove())); 5330 assertEquals("BBBB hh:mm:ss | 00:00:30", "at night 12:00:30", 5331 sdf.format(k000030, out.remove())); 5332 assertEquals("BBBB hh:mm:ss | 00:30:00", "at night 12:30:00", 5333 sdf.format(k003000, out.remove())); 5334 5335 // Confirm applyPattern() reparses the pattern string. 5336 sdf.applyPattern(UnicodeString("BBBB hh")); 5337 // assertEquals("BBBB hh | 00:00:30", "midnight 12", 5338 // sdf.format(k000030, out.remove())); 5339 assertEquals("BBBB hh | 00:00:30", "at night 12", 5340 sdf.format(k000030, out.remove())); 5341 5342 sdf.applyPattern(UnicodeString("BBBB hh:mm:'ss'")); 5343 // assertEquals("BBBB hh:mm:'ss' | 00:00:30", "midnight 12:00:ss", 5344 // sdf.format(k000030, out.remove())); 5345 assertEquals("BBBB hh | 00:00:30", "at night 12:00:ss", 5346 sdf.format(k000030, out.remove())); 5347 5348 sdf.applyPattern(UnicodeString("BBBB hh:mm:ss")); 5349 assertEquals("BBBB hh:mm:ss | 00:00:30", "at night 12:00:30", 5350 sdf.format(k000030, out.remove())); 5351 } 5352 5353 void DateFormatTest::TestDayPeriodParsing() { 5354 // Some times on 2015-11-13 (UTC+0). 5355 UDate k000000 = 1447372800000.0; 5356 UDate k003700 = 1447375020000.0; 5357 UDate k010000 = 1447376400000.0; 5358 UDate k013000 = 1447378200000.0; 5359 UDate k030000 = 1447383600000.0; 5360 UDate k090000 = 1447405200000.0; 5361 UDate k120000 = 1447416000000.0; 5362 UDate k130000 = 1447419600000.0; 5363 UDate k133700 = 1447421820000.0; 5364 UDate k150000 = 1447426800000.0; 5365 UDate k190000 = 1447441200000.0; 5366 UDate k193000 = 1447443000000.0; 5367 UDate k200000 = 1447444800000.0; 5368 UDate k210000 = 1447448400000.0; 5369 5370 UErrorCode errorCode = U_ZERO_ERROR; 5371 SimpleDateFormat sdf(UnicodeString(), errorCode); 5372 if (U_FAILURE(errorCode)) { 5373 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(errorCode)); 5374 return; 5375 } 5376 const TimeZone *tz = TimeZone::getGMT(); 5377 sdf.setTimeZone(*tz); 5378 UnicodeString out; 5379 5380 // 'B' -- flexible day periods 5381 // A day period on its own parses to the center of that period. 5382 sdf.applyPattern(UnicodeString("yyyy-MM-dd B")); 5383 assertEquals("yyyy-MM-dd B | 2015-11-13 midnight", 5384 k000000, sdf.parse(UnicodeString("2015-11-13 midnight"), errorCode)); 5385 assertEquals("yyyy-MM-dd B | 2015-11-13 noon", 5386 k120000, sdf.parse(UnicodeString("2015-11-13 noon"), errorCode)); 5387 assertEquals("yyyy-MM-dd B | 2015-11-13 in the afternoon", 5388 k150000, sdf.parse(UnicodeString("2015-11-13 in the afternoon"), errorCode)); 5389 assertEquals("yyyy-MM-dd B | 2015-11-13 in the evening", 5390 k193000, sdf.parse(UnicodeString("2015-11-13 in the evening"), errorCode)); 5391 assertEquals("yyyy-MM-dd B | 2015-11-13 at night", 5392 k013000, sdf.parse(UnicodeString("2015-11-13 at night"), errorCode)); 5393 5394 // If time and day period are consistent with each other then time is parsed accordingly. 5395 sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm B")); 5396 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 12:00 midnight", 5397 k000000, sdf.parse(UnicodeString("2015-11-13 12:00 midnight"), errorCode)); 5398 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 12:00 noon", 5399 k120000, sdf.parse(UnicodeString("2015-11-13 12:00 noon"), errorCode)); 5400 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 01:00 at night", 5401 k010000, sdf.parse(UnicodeString("2015-11-13 01:00 at night"), errorCode)); 5402 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 01:00 in the afternoon", 5403 k130000, sdf.parse(UnicodeString("2015-11-13 01:00 in the afternoon"), errorCode)); 5404 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 09:00 in the morning", 5405 k090000, sdf.parse(UnicodeString("2015-11-13 09:00 in the morning"), errorCode)); 5406 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 09:00 at night", 5407 k210000, sdf.parse(UnicodeString("2015-11-13 09:00 at night"), errorCode)); 5408 5409 // If the hour is 13 thru 23 then day period has no effect on time (since time is assumed 5410 // to be in 24-hour format). 5411 sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm B")); 5412 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 midnight", 5413 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 midnight"), errorCode)); 5414 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 noon", 5415 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 noon"), errorCode)); 5416 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 at night", 5417 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 at night"), errorCode)); 5418 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 in the afternoon", 5419 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 in the afternoon"), errorCode)); 5420 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 in the morning", 5421 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 in the morning"), errorCode)); 5422 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 13:37 at night", 5423 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 at night"), errorCode)); 5424 5425 // Hour 0 is synonymous with hour 12 when parsed with 'h'. 5426 // This unfortunately means we have to tolerate "0 noon" as it's synonymous with "12 noon". 5427 sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm B")); 5428 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 00:00 midnight", 5429 k000000, sdf.parse(UnicodeString("2015-11-13 00:00 midnight"), errorCode)); 5430 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 00:00 noon", 5431 k120000, sdf.parse(UnicodeString("2015-11-13 00:00 noon"), errorCode)); 5432 5433 // But when parsed with 'H', 0 indicates a 24-hour time, therefore we disregard the day period. 5434 sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm B")); 5435 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 midnight", 5436 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 midnight"), errorCode)); 5437 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 noon", 5438 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 noon"), errorCode)); 5439 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 at night", 5440 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 at night"), errorCode)); 5441 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 in the afternoon", 5442 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 in the afternoon"), errorCode)); 5443 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 in the morning", 5444 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 in the morning"), errorCode)); 5445 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 00:37 at night", 5446 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 at night"), errorCode)); 5447 5448 // Even when parsed with 'H', hours 1 thru 12 are considered 12-hour time and takes 5449 // day period into account in parsing. 5450 sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm B")); 5451 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 12:00 midnight", 5452 k000000, sdf.parse(UnicodeString("2015-11-13 12:00 midnight"), errorCode)); 5453 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 12:00 noon", 5454 k120000, sdf.parse(UnicodeString("2015-11-13 12:00 noon"), errorCode)); 5455 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 01:00 at night", 5456 k010000, sdf.parse(UnicodeString("2015-11-13 01:00 at night"), errorCode)); 5457 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 01:00 in the afternoon", 5458 k130000, sdf.parse(UnicodeString("2015-11-13 01:00 in the afternoon"), errorCode)); 5459 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 09:00 in the morning", 5460 k090000, sdf.parse(UnicodeString("2015-11-13 09:00 in the morning"), errorCode)); 5461 assertEquals("yyyy-MM-dd HH:mm B | 2015-11-13 09:00 at night", 5462 k210000, sdf.parse(UnicodeString("2015-11-13 09:00 at night"), errorCode)); 5463 5464 // If a 12-hour time and the day period don't agree with each other, time is parsed as close 5465 // to the given day period as possible. 5466 sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm B")); 5467 5468 // AFTERNOON1 is [12, 18), but "7 in the afternoon" parses to 19:00. 5469 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 07:00 in the afternoon", 5470 k190000, sdf.parse(UnicodeString("2015-11-13 07:00 in the afternoon"), errorCode)); 5471 // NIGHT1 is [21, 6), but "8 at night" parses to 20:00. 5472 assertEquals("yyyy-MM-dd hh:mm B | 2015-11-13 08:00 at night", 5473 k200000, sdf.parse(UnicodeString("2015-11-13 08:00 at night"), errorCode)); 5474 5475 // 'b' -- fixed day periods (AM, PM, midnight, noon) 5476 // On their own, "midnight" parses to 00:00 and "noon" parses to 12:00. 5477 // AM and PM are handled by the 'a' parser (which doesn't handle this case well). 5478 sdf.applyPattern(UnicodeString("yyyy-MM-dd b")); 5479 assertEquals("yyyy-MM-dd b | 2015-11-13 midnight", 5480 k000000, sdf.parse(UnicodeString("2015-11-13 midnight"), errorCode)); 5481 assertEquals("yyyy-MM-dd b | 2015-11-13 noon", 5482 k120000, sdf.parse(UnicodeString("2015-11-13 noon"), errorCode)); 5483 5484 // For 12-hour times, AM and PM should be parsed as if with pattern character 'a'. 5485 sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm b")); 5486 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 01:00 AM", 5487 k010000, sdf.parse(UnicodeString("2015-11-13 01:00 AM"), errorCode)); 5488 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 01:00 PM", 5489 k130000, sdf.parse(UnicodeString("2015-11-13 01:00 PM"), errorCode)); 5490 5491 // 12 midnight parses to 00:00, and 12 noon parses to 12:00. 5492 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 12:00 midnight", 5493 k000000, sdf.parse(UnicodeString("2015-11-13 12:00 midnight"), errorCode)); 5494 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 12:00 noon", 5495 k120000, sdf.parse(UnicodeString("2015-11-13 12:00 noon"), errorCode)); 5496 5497 // Hours 13-23 indicate 24-hour time so we disregard "midnight" or "noon". 5498 // Again, AM and PM are handled by the 'a' parser which doesn't handle this case well. 5499 sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm b")); 5500 assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 13:37 midnight", 5501 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 midnight"), errorCode)); 5502 assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 13:37 noon", 5503 k133700, sdf.parse(UnicodeString("2015-11-13 13:37 noon"), errorCode)); 5504 5505 // Hour 0 is synonymous with hour 12 when parsed with 'h'. 5506 // Again, this means we have to tolerate "0 noon" as it's synonymous with "12 noon". 5507 sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm b")); 5508 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 00:00 midnight", 5509 k000000, sdf.parse(UnicodeString("2015-11-13 00:00 midnight"), errorCode)); 5510 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 00:00 noon", 5511 k120000, sdf.parse(UnicodeString("2015-11-13 00:00 noon"), errorCode)); 5512 5513 // With 'H' though 0 indicates a 24-hour time, therefore we disregard the day period. 5514 sdf.applyPattern(UnicodeString("yyyy-MM-dd HH:mm b")); 5515 assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 00:37 midnight", 5516 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 midnight"), errorCode)); 5517 assertEquals("yyyy-MM-dd HH:mm b | 2015-11-13 00:37 noon", 5518 k003700, sdf.parse(UnicodeString("2015-11-13 00:37 noon"), errorCode)); 5519 5520 // If "midnight" or "noon" is parsed with a 12-hour time other than 12:00, choose 5521 // the version that's closer to the period given. 5522 sdf.applyPattern(UnicodeString("yyyy-MM-dd hh:mm b")); 5523 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 03:00 midnight", 5524 k030000, sdf.parse(UnicodeString("2015-11-13 03:00 midnight"), errorCode)); 5525 assertEquals("yyyy-MM-dd hh:mm b | 2015-11-13 03:00 noon", 5526 k150000, sdf.parse(UnicodeString("2015-11-13 03:00 noon"), errorCode)); 5527 } 5528 5529 #endif /* #if !UCONFIG_NO_FORMATTING */ 5530 5531 //eof 5532