1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /******************************************************************** 4 * COPYRIGHT: 5 * Copyright (c) 1997-2016, International Business Machines Corporation and 6 * others. All Rights Reserved. 7 ********************************************************************/ 8 9 #include "unicode/utypes.h" 10 11 #if !UCONFIG_NO_FORMATTING 12 #include "dtfmrgts.h" 13 14 #include "unicode/timezone.h" 15 #include "unicode/gregocal.h" 16 #include "unicode/smpdtfmt.h" 17 #include "unicode/datefmt.h" 18 #include "unicode/simpletz.h" 19 #include "unicode/resbund.h" 20 #include "cmemory.h" 21 22 // ***************************************************************************** 23 // class DateFormatRegressionTest 24 // ***************************************************************************** 25 26 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break; 27 28 void 29 DateFormatRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) 30 { 31 // if (exec) logln((UnicodeString)"TestSuite DateFormatRegressionTest"); 32 switch (index) { 33 CASE(0,Test4029195) 34 CASE(1,Test4052408) 35 CASE(2,Test4056591) 36 CASE(3,Test4059917) 37 CASE(4,Test4060212) 38 CASE(5,Test4061287) 39 CASE(6,Test4065240) 40 CASE(7,Test4071441) 41 CASE(8,Test4073003) 42 CASE(9,Test4089106) 43 CASE(10,Test4100302) 44 CASE(11,Test4101483) 45 CASE(12,Test4103340) 46 CASE(13,Test4103341) 47 CASE(14,Test4104136) 48 CASE(15,Test4104522) 49 CASE(16,Test4106807) 50 CASE(17,Test4108407) 51 CASE(18,Test4134203) 52 CASE(19,Test4151631) 53 CASE(20,Test4151706) 54 CASE(21,Test4162071) 55 CASE(22,Test4182066) 56 CASE(23,Test4210209) 57 CASE(24,Test714) 58 CASE(25,Test1684) 59 CASE(26,Test5554) 60 CASE(27,Test9237) 61 CASE(28,TestParsing) 62 CASE(29,TestT10334) 63 CASE(30,TestT10619) 64 CASE(31,TestT10855) 65 CASE(32,TestT10906) 66 CASE(33,TestT13380) 67 default: name = ""; break; 68 } 69 } 70 71 /** 72 * @bug 4029195 73 */ 74 void DateFormatRegressionTest::Test4029195(void) 75 { 76 UErrorCode status = U_ZERO_ERROR; 77 78 UDate today = Calendar::getNow(); 79 logln((UnicodeString) "today: " + today); 80 81 SimpleDateFormat *sdf = (SimpleDateFormat*) DateFormat::createDateInstance(); 82 if (failure(status, "SimpleDateFormat::createDateInstance")) { 83 return; 84 } 85 UnicodeString pat; 86 if(sdf == NULL){ 87 dataerrln("Error calling DateFormat::createDateTimeInstance"); 88 return; 89 } 90 91 pat = sdf->toPattern(pat); 92 logln("pattern: " + pat); 93 UnicodeString fmtd; 94 95 FieldPosition pos(FieldPosition::DONT_CARE); 96 fmtd = sdf->format(today, fmtd, pos); 97 logln("today: " + fmtd); 98 99 sdf->applyPattern("G yyyy DDD"); 100 UnicodeString todayS; 101 todayS = sdf->format(today, todayS, pos); 102 logln("today: " + todayS); 103 //try { 104 today = sdf->parse(todayS, status); 105 failure(status, "sdf->parse"); 106 logln((UnicodeString)"today date: " + today); 107 /*} catch(Exception e) { 108 logln("Error reparsing date: " + e.getMessage()); 109 }*/ 110 111 //try { 112 UnicodeString rt; 113 rt = sdf->format(sdf->parse(todayS, status), rt, pos); 114 failure(status, "sdf->parse"); 115 logln("round trip: " + rt); 116 if(rt != todayS) 117 errln("Fail: Want " + todayS + " Got " + rt); 118 /*} 119 catch (ParseException e) { 120 errln("Fail: " + e); 121 e.printStackTrace(); 122 }*/ 123 124 delete sdf; 125 } 126 127 /** 128 * @bug 4052408 129 */ 130 void DateFormatRegressionTest::Test4052408(void) 131 { 132 133 DateFormat *fmt = DateFormat::createDateTimeInstance(DateFormat::SHORT, 134 DateFormat::SHORT, Locale::getUS()); 135 if (fmt == NULL) { 136 dataerrln("Error calling DateFormat::createDateTimeInstance"); 137 return; 138 } 139 140 UDate dt = date(97, UCAL_MAY, 3, 8, 55); 141 UnicodeString str; 142 str = fmt->format(dt, str); 143 logln(str); 144 145 if(str != "5/3/97, 8:55 AM") 146 errln("Fail: Test broken; Want 5/3/97 8:55 AM Got " + str); 147 148 UnicodeString expected[] = { 149 (UnicodeString) "", //"ERA_FIELD", 150 (UnicodeString) "97", //"YEAR_FIELD", 151 (UnicodeString) "5", //"MONTH_FIELD", 152 (UnicodeString) "3", //"DATE_FIELD", 153 (UnicodeString) "", //"HOUR_OF_DAY1_FIELD", 154 (UnicodeString) "", //"HOUR_OF_DAY0_FIELD", 155 (UnicodeString) "55", //"MINUTE_FIELD", 156 (UnicodeString) "", //"SECOND_FIELD", 157 (UnicodeString) "", //"MILLISECOND_FIELD", 158 (UnicodeString) "", //"DAY_OF_WEEK_FIELD", 159 (UnicodeString) "", //"DAY_OF_YEAR_FIELD", 160 (UnicodeString) "", //"DAY_OF_WEEK_IN_MONTH_FIELD", 161 (UnicodeString) "", //"WEEK_OF_YEAR_FIELD", 162 (UnicodeString) "", //"WEEK_OF_MONTH_FIELD", 163 (UnicodeString) "AM", //"AM_PM_FIELD", 164 (UnicodeString) "8", //"HOUR1_FIELD", 165 (UnicodeString) "", //"HOUR0_FIELD", 166 (UnicodeString) "" //"TIMEZONE_FIELD" 167 }; 168 169 //Hashtable expected;// = new Hashtable(); 170 //expected.put(new LongKey(DateFormat.MONTH_FIELD), "5"); 171 //expected.put(new LongKey(DateFormat.DATE_FIELD), "3"); 172 //expected.put(new LongKey(DateFormat.YEAR_FIELD), "97"); 173 //expected.put(new LongKey(DateFormat.HOUR1_FIELD), "8"); 174 //expected.put(new LongKey(DateFormat.MINUTE_FIELD), "55"); 175 //expected.put(new LongKey(DateFormat.AM_PM_FIELD), "AM"); 176 177 //StringBuffer buf = new StringBuffer(); 178 UnicodeString fieldNames[] = { 179 (UnicodeString) "ERA_FIELD", 180 (UnicodeString) "YEAR_FIELD", 181 (UnicodeString) "MONTH_FIELD", 182 (UnicodeString) "DATE_FIELD", 183 (UnicodeString) "HOUR_OF_DAY1_FIELD", 184 (UnicodeString) "HOUR_OF_DAY0_FIELD", 185 (UnicodeString) "MINUTE_FIELD", 186 (UnicodeString) "SECOND_FIELD", 187 (UnicodeString) "MILLISECOND_FIELD", 188 (UnicodeString) "DAY_OF_WEEK_FIELD", 189 (UnicodeString) "DAY_OF_YEAR_FIELD", 190 (UnicodeString) "DAY_OF_WEEK_IN_MONTH_FIELD", 191 (UnicodeString) "WEEK_OF_YEAR_FIELD", 192 (UnicodeString) "WEEK_OF_MONTH_FIELD", 193 (UnicodeString) "AM_PM_FIELD", 194 (UnicodeString) "HOUR1_FIELD", 195 (UnicodeString) "HOUR0_FIELD", 196 (UnicodeString) "TIMEZONE_FIELD" 197 }; 198 199 UBool pass = TRUE; 200 for(int i = 0; i <= 17; ++i) { 201 FieldPosition pos(i); 202 UnicodeString buf; 203 fmt->format(dt, buf, pos); 204 //char[] dst = new char[pos.getEndIndex() - pos.getBeginIndex()]; 205 UnicodeString dst; 206 buf.extractBetween(pos.getBeginIndex(), pos.getEndIndex(), dst); 207 UnicodeString str(dst); 208 logln((UnicodeString)"" + i + (UnicodeString)": " + fieldNames[i] + 209 (UnicodeString)", \"" + str + (UnicodeString)"\", " + 210 pos.getBeginIndex() + (UnicodeString)", " + 211 pos.getEndIndex()); 212 UnicodeString exp = expected[i]; 213 if((exp.length() == 0 && str.length() == 0) || str == exp) 214 logln(" ok"); 215 else { 216 errln(UnicodeString(" expected ") + exp); 217 pass = FALSE; 218 } 219 220 } 221 if( ! pass) 222 errln("Fail: FieldPosition not set right by DateFormat"); 223 224 delete fmt; 225 } 226 227 /** 228 * @bug 4056591 229 * Verify the function of the [s|g]et2DigitYearStart() API. 230 */ 231 void DateFormatRegressionTest::Test4056591(void) 232 { 233 UErrorCode status = U_ZERO_ERROR; 234 235 //try { 236 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("yyMMdd"), Locale::getUS(), status); 237 if (failure(status, "new SimpleDateFormat", TRUE)) { 238 delete fmt; 239 return; 240 } 241 UDate start = date(1809-1900, UCAL_DECEMBER, 25); 242 fmt->set2DigitYearStart(start, status); 243 failure(status, "fmt->setTwoDigitStartDate"); 244 if( (fmt->get2DigitYearStart(status) != start) || failure(status, "get2DigitStartDate")) 245 errln("get2DigitYearStart broken"); 246 UDate dates [] = { 247 date(1809-1900, UCAL_DECEMBER, 25), 248 date(1909-1900, UCAL_DECEMBER, 24), 249 date(1809-1900, UCAL_DECEMBER, 26), 250 date(1861-1900, UCAL_DECEMBER, 25), 251 }; 252 253 UnicodeString strings [] = { 254 (UnicodeString) "091225", 255 (UnicodeString) "091224", 256 (UnicodeString) "091226", 257 (UnicodeString) "611225" 258 }; 259 260 /*Object[] DATA = { 261 "091225", new Date(1809-1900, Calendar.DECEMBER, 25), 262 "091224", new Date(1909-1900, Calendar.DECEMBER, 24), 263 "091226", new Date(1809-1900, Calendar.DECEMBER, 26), 264 "611225", new Date(1861-1900, Calendar.DECEMBER, 25), 265 };*/ 266 267 for(int i = 0; i < 4; i++) { 268 UnicodeString s = strings[i]; 269 UDate exp = dates[i]; 270 UDate got = fmt->parse(s, status); 271 failure(status, "fmt->parse"); 272 logln(s + " -> " + got + "; exp " + exp); 273 if(got != exp) 274 errln("set2DigitYearStart broken"); 275 } 276 /*} 277 catch (ParseException e) { 278 errln("Fail: " + e); 279 e.printStackTrace(); 280 }*/ 281 282 delete fmt; 283 } 284 285 /** 286 * @bug 4059917 287 */ 288 void DateFormatRegressionTest::Test4059917(void) 289 { 290 UErrorCode status = U_ZERO_ERROR; 291 292 SimpleDateFormat *fmt; 293 UnicodeString myDate; 294 295 fmt = new SimpleDateFormat( UnicodeString("yyyy/MM/dd"), status ); 296 if (failure(status, "new SimpleDateFormat", TRUE)) return; 297 myDate = "1997/01/01"; 298 aux917( fmt, myDate ); 299 300 delete fmt; 301 fmt = NULL; 302 303 fmt = new SimpleDateFormat( UnicodeString("yyyyMMdd"), status ); 304 if(failure(status, "new SimpleDateFormat")) return; 305 myDate = "19970101"; 306 aux917( fmt, myDate ); 307 308 delete fmt; 309 } 310 311 void DateFormatRegressionTest::aux917( SimpleDateFormat *fmt, UnicodeString& str ) { 312 //try { 313 UnicodeString pat; 314 pat = fmt->toPattern(pat); 315 logln( "==================" ); 316 logln( "testIt: pattern=" + pat + 317 " string=" + str ); 318 319 320 Formattable o; 321 //Object o; 322 ParsePosition pos(0); 323 fmt->parseObject( str, o, pos ); 324 //logln( UnicodeString("Parsed object: ") + o ); 325 326 UErrorCode status = U_ZERO_ERROR; 327 UnicodeString formatted; 328 FieldPosition poss(FieldPosition::DONT_CARE); 329 formatted = fmt->format( o, formatted, poss, status ); 330 failure(status, "fmt->format"); 331 logln( "Formatted string: " + formatted ); 332 if( formatted != str) 333 errln("Fail: Want " + str + " Got " + formatted); 334 /*} 335 catch (ParseException e) { 336 errln("Fail: " + e); 337 e.printStackTrace(); 338 }*/ 339 } 340 341 /** 342 * @bug 4060212 343 */ 344 void DateFormatRegressionTest::Test4060212(void) 345 { 346 UnicodeString dateString = "1995-040.05:01:29"; 347 348 logln( "dateString= " + dateString ); 349 logln("Using yyyy-DDD.hh:mm:ss"); 350 UErrorCode status = U_ZERO_ERROR; 351 SimpleDateFormat *formatter = new SimpleDateFormat(UnicodeString("yyyy-DDD.hh:mm:ss"), status); 352 if (failure(status, "new SimpleDateFormat", TRUE)) return; 353 ParsePosition pos(0); 354 UDate myDate = formatter->parse( dateString, pos ); 355 UnicodeString myString; 356 DateFormat *fmt = DateFormat::createDateTimeInstance( DateFormat::FULL, 357 DateFormat::LONG); 358 if (fmt == NULL) { 359 dataerrln("Error calling DateFormat::createDateTimeInstance"); 360 delete formatter; 361 return; 362 } 363 364 myString = fmt->format( myDate, myString); 365 logln( myString ); 366 367 Calendar *cal = new GregorianCalendar(status); 368 failure(status, "new GregorianCalendar"); 369 cal->setTime(myDate, status); 370 failure(status, "cal->setTime"); 371 if ((cal->get(UCAL_DAY_OF_YEAR, status) != 40) || failure(status, "cal->get")) 372 errln((UnicodeString) "Fail: Got " + cal->get(UCAL_DAY_OF_YEAR, status) + 373 " Want 40"); 374 375 // this is an odd usage of "ddd" and it doesn't 376 // work now that date values are range checked per #3579. 377 logln("Using yyyy-ddd.hh:mm:ss"); 378 delete formatter; 379 formatter = NULL; 380 formatter = new SimpleDateFormat(UnicodeString("yyyy-ddd.hh:mm:ss"), status); 381 if(failure(status, "new SimpleDateFormat")) return; 382 pos.setIndex(0); 383 myDate = formatter->parse( dateString, pos ); 384 myString = fmt->format( myDate, myString ); 385 logln( myString ); 386 cal->setTime(myDate, status); 387 failure(status, "cal->setTime"); 388 if ((cal->get(UCAL_DAY_OF_YEAR, status) != 40) || failure(status, "cal->get")) 389 errln((UnicodeString) "Fail: Got " + cal->get(UCAL_DAY_OF_YEAR, status) + 390 " Want 40"); 391 392 delete formatter; 393 delete fmt; 394 delete cal; 395 } 396 397 /** 398 * @bug 4061287 399 */ 400 void DateFormatRegressionTest::Test4061287(void) 401 { 402 UErrorCode status = U_ZERO_ERROR; 403 404 SimpleDateFormat *df = new SimpleDateFormat(UnicodeString("dd/MM/yyyy"), status); 405 if (U_FAILURE(status)) { 406 dataerrln("Fail new SimpleDateFormat: %s", u_errorName(status)); 407 delete df; 408 return; 409 } 410 failure(status, "new SimpleDateFormat"); 411 //try { 412 logln(UnicodeString("") + df->parse("35/01/1971", status)); 413 failure(status, "df->parse(\"35/01/1971\")"); 414 //logln(df.parse("35/01/1971").toString()); 415 //} 416 /*catch (ParseException e) { 417 errln("Fail: " + e); 418 e.printStackTrace(); 419 }*/ 420 df->setLenient(FALSE); 421 UBool ok = FALSE; 422 //try { 423 logln(UnicodeString("") + df->parse("35/01/1971", status)); 424 if(U_FAILURE(status)) 425 ok = TRUE; 426 //logln(df.parse("35/01/1971").toString()); 427 //} catch (ParseException e) {ok=TRUE;} 428 if(!ok) 429 errln("Fail: Lenient not working"); 430 delete df; 431 } 432 433 /** 434 * @bug 4065240 435 */ 436 void DateFormatRegressionTest::Test4065240(void) 437 { 438 UDate curDate; 439 DateFormat *shortdate, *fulldate; 440 UnicodeString strShortDate, strFullDate; 441 Locale saveLocale = Locale::getDefault(); 442 TimeZone *saveZone = TimeZone::createDefault(); 443 444 UErrorCode status = U_ZERO_ERROR; 445 //try { 446 Locale *curLocale = new Locale("de","DE"); 447 Locale::setDefault(*curLocale, status); 448 failure(status, "Locale::setDefault"); 449 // {sfb} adoptDefault instead of setDefault 450 //TimeZone::setDefault(TimeZone::createTimeZone("EST")); 451 TimeZone::adoptDefault(TimeZone::createTimeZone("EST")); 452 curDate = date(98, 0, 1); 453 shortdate = DateFormat::createDateInstance(DateFormat::SHORT); 454 if (shortdate == NULL){ 455 dataerrln("Error calling DateFormat::createDateInstance"); 456 return; 457 } 458 459 fulldate = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::LONG); 460 if (fulldate == NULL){ 461 dataerrln("Error calling DateFormat::createDateTimeInstance"); 462 return; 463 } 464 strShortDate = "The current date (short form) is "; 465 UnicodeString temp; 466 temp = shortdate->format(curDate, temp); 467 strShortDate += temp; 468 strFullDate = "The current date (long form) is "; 469 UnicodeString temp2; 470 fulldate->format(curDate, temp2); 471 strFullDate += temp2; 472 473 logln(strShortDate); 474 logln(strFullDate); 475 476 // {sfb} What to do with resource bundle stuff????? 477 478 // Check to see if the resource is present; if not, we can't test 479 ResourceBundle *bundle = new ResourceBundle( 480 NULL, *curLocale, status); 481 failure(status, "new ResourceBundle"); 482 //(UnicodeString) "java.text.resources.DateFormatZoneData", curLocale); 483 484 // {sfb} API change to ResourceBundle -- add getLocale() 485 /*if (bundle->getLocale().getLanguage(temp) == UnicodeString("de")) { 486 // UPDATE THIS AS ZONE NAME RESOURCE FOR <EST> in de_DE is updated 487 if (!strFullDate.endsWith(UnicodeString("GMT-05:00"))) 488 errln("Fail: Want GMT-05:00"); 489 } 490 else { 491 logln("*** TEST COULD NOT BE COMPLETED BECAUSE DateFormatZoneData ***"); 492 logln("*** FOR LOCALE de OR de_DE IS MISSING ***"); 493 }*/ 494 //} 495 //finally { 496 Locale::setDefault(saveLocale, status); 497 failure(status, "Locale::setDefault"); 498 TimeZone::setDefault(*saveZone); 499 //} 500 delete shortdate; 501 delete fulldate; 502 delete saveZone; 503 delete curLocale; 504 delete bundle; 505 } 506 507 /* 508 DateFormat.equals is too narrowly defined. As a result, MessageFormat 509 does not work correctly. DateFormat.equals needs to be written so 510 that the Calendar sub-object is not compared using Calendar.equals, 511 but rather compared for equivalency. This may necessitate adding a 512 (package private) method to Calendar to test for equivalency. 513 514 Currently this bug breaks MessageFormat.toPattern 515 */ 516 /** 517 * @bug 4071441 518 */ 519 void DateFormatRegressionTest::Test4071441(void) 520 { 521 DateFormat *fmtA = DateFormat::createInstance(); 522 DateFormat *fmtB = DateFormat::createInstance(); 523 524 if (fmtA == NULL || fmtB == NULL){ 525 dataerrln("Error calling DateFormat::createInstance"); 526 delete fmtA; 527 delete fmtB; 528 return; 529 } 530 531 // {sfb} Is it OK to cast away const here? 532 Calendar *calA = (Calendar*) fmtA->getCalendar(); 533 Calendar *calB = (Calendar*) fmtB->getCalendar(); 534 if(!calA || !calB) { 535 errln("Couldn't get proper calendars, exiting"); 536 delete fmtA; 537 delete fmtB; 538 return; 539 } 540 UDate epoch = date(0, 0, 0); 541 UDate xmas = date(61, UCAL_DECEMBER, 25); 542 543 UErrorCode status = U_ZERO_ERROR; 544 calA->setTime(epoch, status); 545 failure(status, "calA->setTime"); 546 calB->setTime(epoch, status); 547 failure(status, "calB->setTime"); 548 if (*calA != *calB) 549 errln("Fail: Can't complete test; Calendar instances unequal"); 550 if (*fmtA != *fmtB) 551 errln("Fail: DateFormat unequal when Calendars equal"); 552 calB->setTime(xmas, status); 553 failure(status, "calB->setTime"); 554 if (*calA == *calB) 555 errln("Fail: Can't complete test; Calendar instances equal"); 556 if (*fmtA != *fmtB) 557 errln("Fail: DateFormat unequal when Calendars equivalent"); 558 559 logln("DateFormat.equals ok"); 560 561 delete fmtA; 562 delete fmtB; 563 } 564 565 /* The java.text.DateFormat.parse(String) method expects for the 566 US locale a string formatted according to mm/dd/yy and parses it 567 correctly. 568 569 When given a string mm/dd/yyyy [sic] it only parses up to the first 570 two y's, typically resulting in a date in the year 1919. 571 572 Please extend the parsing method(s) to handle strings with 573 four-digit year values (probably also applicable to various 574 other locales. */ 575 /** 576 * @bug 4073003 577 */ 578 void DateFormatRegressionTest::Test4073003(void) 579 { 580 //try { 581 UErrorCode ec = U_ZERO_ERROR; 582 SimpleDateFormat fmt("MM/dd/yy", Locale::getUK(), ec); 583 if (U_FAILURE(ec)) { 584 dataerrln("FAIL: SimpleDateFormat constructor - %s", u_errorName(ec)); 585 return; 586 } 587 UnicodeString tests [] = { 588 (UnicodeString) "12/25/61", 589 (UnicodeString) "12/25/1961", 590 (UnicodeString) "4/3/2010", 591 (UnicodeString) "4/3/10" 592 }; 593 UErrorCode status = U_ZERO_ERROR; 594 for(int i= 0; i < 4; i+=2) { 595 UDate d = fmt.parse(tests[i], status); 596 failure(status, "fmt.parse"); 597 UDate dd = fmt.parse(tests[i+1], status); 598 failure(status, "fmt.parse"); 599 UnicodeString s; 600 s = fmt.format(d, s); 601 UnicodeString ss; 602 ss = fmt.format(dd, ss); 603 if (d != dd) 604 errln((UnicodeString) "Fail: " + d + " != " + dd); 605 if (s != ss) 606 errln((UnicodeString)"Fail: " + s + " != " + ss); 607 logln("Ok: " + s + " " + d); 608 } 609 } 610 611 /** 612 * @bug 4089106 613 */ 614 void DateFormatRegressionTest::Test4089106(void) 615 { 616 TimeZone *def = TimeZone::createDefault(); 617 //try { 618 TimeZone *z = new SimpleTimeZone((int)(1.25 * 3600000), "FAKEZONE"); 619 TimeZone::setDefault(*z); 620 UErrorCode status = U_ZERO_ERROR; 621 SimpleDateFormat *f = new SimpleDateFormat(status); 622 if(U_FAILURE(status)) { 623 dataerrln("Couldn't create SimpleDateFormat, error %s", u_errorName(status)); 624 delete f; 625 delete def; 626 delete z; 627 return; 628 } 629 failure(status, "new SimpleDateFormat"); 630 if (f->getTimeZone()!= *z) 631 errln("Fail: SimpleTimeZone should use TimeZone.getDefault()"); 632 633 //} 634 //finally { 635 TimeZone::setDefault(*def); 636 //} 637 638 delete z; 639 delete f; 640 delete def; 641 } 642 643 /** 644 * @bug 4100302 645 */ 646 647 // {sfb} not applicable in C++?? 648 649 void DateFormatRegressionTest::Test4100302(void) 650 { 651 /* Locale locales [] = { 652 Locale::CANADA, 653 Locale::CANADA_FRENCH, 654 Locale::CHINA, 655 Locale::CHINESE, 656 Locale::ENGLISH, 657 Locale::FRANCE, 658 Locale::FRENCH, 659 Locale::GERMAN, 660 Locale::GERMANY, 661 Locale::ITALIAN, 662 Locale::ITALY, 663 Locale::JAPAN, 664 Locale::JAPANESE, 665 Locale::KOREA, 666 Locale::KOREAN, 667 Locale::PRC, 668 Locale::SIMPLIFIED_CHINESE, 669 Locale::TAIWAN, 670 Locale::TRADITIONAL_CHINESE, 671 Locale::UK, 672 Locale::US 673 }; 674 //try { 675 UBool pass = TRUE; 676 for(int i = 0; i < 21; i++) { 677 678 Format *format = DateFormat::createDateTimeInstance(DateFormat::FULL, 679 DateFormat::FULL, locales[i]); 680 byte[] bytes; 681 682 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 683 ObjectOutputStream oos = new ObjectOutputStream(baos); 684 685 oos.writeObject(format); 686 oos.flush(); 687 688 baos.close(); 689 bytes = baos.toByteArray(); 690 691 ObjectInputStream ois = 692 new ObjectInputStream(new ByteArrayInputStream(bytes)); 693 694 if (!format.equals(ois.readObject())) { 695 pass = FALSE; 696 logln("DateFormat instance for locale " + 697 locales[i] + " is incorrectly serialized/deserialized."); 698 } else { 699 logln("DateFormat instance for locale " + 700 locales[i] + " is OKAY."); 701 } 702 } 703 if (!pass) errln("Fail: DateFormat serialization/equality bug"); 704 } 705 catch (IOException e) { 706 errln("Fail: " + e); 707 e.printStackTrace(); 708 } 709 catch (ClassNotFoundException e) { 710 errln("Fail: " + e); 711 e.printStackTrace(); 712 } 713 */} 714 715 /** 716 * @bug 4101483 717 */ 718 void DateFormatRegressionTest::Test4101483(void) 719 { 720 UErrorCode status = U_ZERO_ERROR; 721 SimpleDateFormat *sdf = new SimpleDateFormat(UnicodeString("z"), Locale::getUS(), status); 722 if (failure(status, "new SimpleDateFormat", TRUE)) return; 723 FieldPosition fp(UDAT_TIMEZONE_FIELD); 724 //Date d = date(9234567890L); 725 UDate d = 9234567890.0; 726 //StringBuffer buf = new StringBuffer(""); 727 UnicodeString buf; 728 sdf->format(d, buf, fp); 729 //logln(sdf.format(d, buf, fp).toString()); 730 logln(dateToString(d) + " => " + buf); 731 logln(UnicodeString("beginIndex = ") + fp.getBeginIndex()); 732 logln(UnicodeString("endIndex = ") + fp.getEndIndex()); 733 if (fp.getBeginIndex() == fp.getEndIndex()) 734 errln("Fail: Empty field"); 735 736 delete sdf; 737 } 738 739 /** 740 * @bug 4103340 741 * @bug 4138203 742 * This bug really only works in Locale.US, since that's what the locale 743 * used for Date.toString() is. Bug 4138203 reports that it fails on Korean 744 * NT; it would actually have failed on any non-US locale. Now it should 745 * work on all locales. 746 */ 747 void DateFormatRegressionTest::Test4103340(void) 748 { 749 UErrorCode status = U_ZERO_ERROR; 750 751 // choose a date that is the FIRST of some month 752 // and some arbitrary time 753 UDate d = date(97, 3, 1, 1, 1, 1); 754 SimpleDateFormat *df = new SimpleDateFormat(UnicodeString("MMMM"), Locale::getUS(), status); 755 if (failure(status, "new SimpleDateFormat", TRUE)) return; 756 757 UnicodeString s; 758 s = dateToString(d, s); 759 UnicodeString s2; 760 FieldPosition pos(FieldPosition::DONT_CARE); 761 s2 = df->format(d, s2, pos); 762 logln("Date=" + s); 763 logln("DF=" + s2); 764 UnicodeString substr; 765 s2.extract(0,2, substr); 766 if (s.indexOf(substr) == -1) 767 errln("Months should match"); 768 769 delete df; 770 } 771 772 /** 773 * @bug 4103341 774 */ 775 void DateFormatRegressionTest::Test4103341(void) 776 { 777 TimeZone *saveZone =TimeZone::createDefault(); 778 //try { 779 780 // {sfb} changed from setDefault to adoptDefault 781 TimeZone::adoptDefault(TimeZone::createTimeZone("CST")); 782 UErrorCode status = U_ZERO_ERROR; 783 SimpleDateFormat *simple = new SimpleDateFormat(UnicodeString("MM/dd/yyyy HH:mm"), status); 784 if(U_FAILURE(status)) { 785 dataerrln("Couldn't create SimpleDateFormat, error %s", u_errorName(status)); 786 delete simple; 787 return; 788 } 789 failure(status, "new SimpleDateFormat"); 790 TimeZone *temp = TimeZone::createDefault(); 791 if(simple->getTimeZone() != *temp) 792 errln("Fail: SimpleDateFormat not using default zone"); 793 //} 794 //finally { 795 TimeZone::adoptDefault(saveZone); 796 //} 797 798 delete temp; 799 delete simple; 800 } 801 802 /** 803 * @bug 4104136 804 */ 805 void DateFormatRegressionTest::Test4104136(void) 806 { 807 UErrorCode status = U_ZERO_ERROR; 808 SimpleDateFormat *sdf = new SimpleDateFormat(status); 809 if(U_FAILURE(status)) { 810 dataerrln("Couldn't create SimpleDateFormat, error %s", u_errorName(status)); 811 delete sdf; 812 return; 813 } 814 if(failure(status, "new SimpleDateFormat")) return; 815 UnicodeString pattern = "'time' hh:mm"; 816 sdf->applyPattern(pattern); 817 logln("pattern: \"" + pattern + "\""); 818 819 UnicodeString strings [] = { 820 (UnicodeString)"time 10:30", 821 (UnicodeString) "time 10:x", 822 (UnicodeString) "time 10x" 823 }; 824 825 ParsePosition ppos [] = { 826 ParsePosition(10), 827 ParsePosition(0), 828 ParsePosition(0) 829 }; 830 831 UDate dates [] = { 832 date(70, UCAL_JANUARY, 1, 10, 30), 833 -1, 834 -1 835 }; 836 837 /*Object[] DATA = { 838 "time 10:30", new ParsePosition(10), new Date(70, Calendar.JANUARY, 1, 10, 30), 839 "time 10:x", new ParsePosition(0), null, 840 "time 10x", new ParsePosition(0), null, 841 };*/ 842 843 for(int i = 0; i < 3; i++) { 844 UnicodeString text = strings[i]; 845 ParsePosition finish = ppos[i]; 846 UDate exp = dates[i]; 847 848 ParsePosition pos(0); 849 UDate d = sdf->parse(text, pos); 850 logln(" text: \"" + text + "\""); 851 logln(" index: %d", pos.getIndex()); 852 logln((UnicodeString) " result: " + d); 853 if(pos.getIndex() != finish.getIndex()) 854 errln(UnicodeString("Fail: Expected pos ") + finish.getIndex()); 855 if (! ((d == 0 && exp == -1) || (d == exp))) 856 errln((UnicodeString) "Fail: Expected result " + exp); 857 } 858 859 delete sdf; 860 } 861 862 /** 863 * @bug 4104522 864 * CANNOT REPRODUCE 865 * According to the bug report, this test should throw a 866 * StringIndexOutOfBoundsException during the second parse. However, 867 * this is not seen. 868 */ 869 void DateFormatRegressionTest::Test4104522(void) 870 { 871 UErrorCode status = U_ZERO_ERROR; 872 873 SimpleDateFormat *sdf = new SimpleDateFormat(status); 874 if(U_FAILURE(status)) { 875 dataerrln("Couldn't create SimpleDateFormat, error %s", u_errorName(status)); 876 delete sdf; 877 return; 878 } 879 failure(status, "new SimpleDateFormat"); 880 UnicodeString pattern = "'time' hh:mm"; 881 sdf->applyPattern(pattern); 882 logln("pattern: \"" + pattern + "\""); 883 884 // works correctly 885 ParsePosition pp(0); 886 UnicodeString text = "time "; 887 UDate dt = sdf->parse(text, pp); 888 logln(" text: \"" + text + "\"" + 889 " date: " + dt); 890 891 // works wrong 892 pp.setIndex(0); 893 text = "time"; 894 dt = sdf->parse(text, pp); 895 logln(" text: \"" + text + "\"" + 896 " date: " + dt); 897 898 delete sdf; 899 } 900 901 /** 902 * @bug 4106807 903 */ 904 void DateFormatRegressionTest::Test4106807(void) 905 { 906 UDate dt; 907 DateFormat *df = DateFormat::createDateTimeInstance(); 908 909 UErrorCode status = U_ZERO_ERROR; 910 SimpleDateFormat *sdfs [] = { 911 new SimpleDateFormat(UnicodeString("yyyyMMddHHmmss"), status), 912 new SimpleDateFormat(UnicodeString("yyyyMMddHHmmss'Z'"), status), 913 new SimpleDateFormat(UnicodeString("yyyyMMddHHmmss''"), status), 914 new SimpleDateFormat(UnicodeString("yyyyMMddHHmmss'a''a'"), status), 915 new SimpleDateFormat(UnicodeString("yyyyMMddHHmmss %"), status) 916 }; 917 if(U_FAILURE(status)) { 918 dataerrln("Couldn't create SimpleDateFormat, error %s", u_errorName(status)); 919 delete sdfs[0]; 920 delete sdfs[1]; 921 delete sdfs[2]; 922 delete sdfs[3]; 923 delete sdfs[4]; 924 return; 925 } 926 927 failure(status, "new SimpleDateFormat"); 928 929 UnicodeString strings [] = { 930 (UnicodeString) "19980211140000", 931 (UnicodeString) "19980211140000", 932 (UnicodeString) "19980211140000", 933 (UnicodeString) "19980211140000a", 934 (UnicodeString) "19980211140000 " 935 }; 936 937 /*Object[] data = { 938 new SimpleDateFormat("yyyyMMddHHmmss"), "19980211140000", 939 new SimpleDateFormat("yyyyMMddHHmmss'Z'"), "19980211140000", 940 new SimpleDateFormat("yyyyMMddHHmmss''"), "19980211140000", 941 new SimpleDateFormat("yyyyMMddHHmmss'a''a'"), "19980211140000a", 942 new SimpleDateFormat("yyyyMMddHHmmss %"), "19980211140000 ", 943 };*/ 944 GregorianCalendar *gc = new GregorianCalendar(status); 945 failure(status, "new GregorianCalendar"); 946 TimeZone *timeZone = TimeZone::createDefault(); 947 948 TimeZone *gmt = timeZone->clone(); 949 950 gmt->setRawOffset(0); 951 952 for(int32_t i = 0; i < 5; i++) { 953 SimpleDateFormat *format = sdfs[i]; 954 UnicodeString dateString = strings[i]; 955 //try { 956 format->setTimeZone(*gmt); 957 dt = format->parse(dateString, status); 958 // {sfb} some of these parses will fail purposely 959 if(U_FAILURE(status)) 960 break; 961 status = U_ZERO_ERROR; 962 UnicodeString fmtd; 963 FieldPosition pos(FieldPosition::DONT_CARE); 964 fmtd = df->format(dt, fmtd, pos); 965 logln(fmtd); 966 //logln(df->format(dt)); 967 gc->setTime(dt, status); 968 failure(status, "gc->getTime"); 969 logln(UnicodeString("") + gc->get(UCAL_ZONE_OFFSET, status)); 970 failure(status, "gc->get"); 971 UnicodeString s; 972 s = format->format(dt, s, pos); 973 logln(s); 974 /*} 975 catch (ParseException e) { 976 logln("No way Jose"); 977 }*/ 978 } 979 980 delete timeZone; 981 delete df; 982 for(int32_t j = 0; j < 5; j++) 983 delete sdfs [j]; 984 delete gc; 985 delete gmt; 986 } 987 988 /* 989 Synopsis: Chinese time zone CTT is not recogonized correctly. 990 Description: Platform Chinese Windows 95 - ** Time zone set to CST ** 991 */ 992 /** 993 * @bug 4108407 994 */ 995 996 // {sfb} what to do with this one ?? 997 void DateFormatRegressionTest::Test4108407(void) 998 { 999 /*long l = System.currentTimeMillis(); 1000 logln("user.timezone = " + System.getProperty("user.timezone", "?")); 1001 logln("Time Zone :" + 1002 DateFormat.getDateInstance().getTimeZone().getID()); 1003 logln("Default format :" + 1004 DateFormat.getDateInstance().format(new Date(l))); 1005 logln("Full format :" + 1006 DateFormat.getDateInstance(DateFormat.FULL).format(new 1007 Date(l))); 1008 logln("*** Set host TZ to CST ***"); 1009 logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");*/ 1010 } 1011 1012 /** 1013 * @bug 4134203 1014 * SimpleDateFormat won't parse "GMT" 1015 */ 1016 void DateFormatRegressionTest::Test4134203(void) 1017 { 1018 UErrorCode status = U_ZERO_ERROR; 1019 UnicodeString dateFormat = "MM/dd/yy HH:mm:ss zzz"; 1020 SimpleDateFormat *fmt = new SimpleDateFormat(dateFormat, status); 1021 if (failure(status, "new SimpleDateFormat", TRUE)) return; 1022 ParsePosition p0(0); 1023 UDate d = fmt->parse("01/22/92 04:52:00 GMT", p0); 1024 logln(dateToString(d)); 1025 if(p0 == ParsePosition(0)) 1026 errln("Fail: failed to parse 'GMT'"); 1027 // In the failure case an exception is thrown by parse(); 1028 // if no exception is thrown, the test passes. 1029 1030 delete fmt; 1031 } 1032 1033 /** 1034 * @bug 4151631 1035 * SimpleDateFormat incorrect handling of 2 single quotes in format() 1036 */ 1037 void DateFormatRegressionTest::Test4151631(void) 1038 { 1039 UnicodeString pattern = "'TO_DATE('''dd'-'MM'-'yyyy HH:mm:ss''' , ''DD-MM-YYYY HH:MI:SS'')'"; 1040 logln("pattern=" + pattern); 1041 UErrorCode status = U_ZERO_ERROR; 1042 SimpleDateFormat *format = new SimpleDateFormat(pattern, Locale::getUS(), status); 1043 if (failure(status, "new SimpleDateFormat", TRUE)) return; 1044 UnicodeString result; 1045 FieldPosition pos(FieldPosition::DONT_CARE); 1046 result = format->format(date(1998-1900, UCAL_JUNE, 30, 13, 30, 0), result, pos); 1047 if (result != "TO_DATE('30-06-1998 13:30:00' , 'DD-MM-YYYY HH:MI:SS')") { 1048 errln("Fail: result=" + result); 1049 } 1050 else { 1051 logln("Pass: result=" + result); 1052 } 1053 1054 delete format; 1055 } 1056 1057 /** 1058 * @bug 4151706 1059 * 'z' at end of date format throws index exception in SimpleDateFormat 1060 * CANNOT REPRODUCE THIS BUG ON 1.2FCS 1061 */ 1062 void DateFormatRegressionTest::Test4151706(void) 1063 { 1064 UnicodeString dateString("Thursday, 31-Dec-98 23:00:00 GMT"); 1065 UErrorCode status = U_ZERO_ERROR; 1066 SimpleDateFormat fmt(UnicodeString("EEEE, dd-MMM-yy HH:mm:ss z"), Locale::getUS(), status); 1067 if (failure(status, "new SimpleDateFormat", TRUE)) return; 1068 //try { 1069 UDate d = fmt.parse(dateString, status); 1070 failure(status, "fmt->parse"); 1071 // {sfb} what about next two lines? 1072 //if (d.getTime() != Date.UTC(1998-1900, Calendar.DECEMBER, 31, 23, 0, 0)) 1073 // errln("Incorrect value: " + d); 1074 /*} catch (Exception e) { 1075 errln("Fail: " + e); 1076 }*/ 1077 UnicodeString temp; 1078 FieldPosition pos(FieldPosition::DONT_CARE); 1079 logln(dateString + " -> " + fmt.format(d, temp, pos)); 1080 } 1081 1082 /** 1083 * @bug 4162071 1084 * Cannot reproduce this bug under 1.2 FCS -- it may be a convoluted duplicate 1085 * of some other bug that has been fixed. 1086 */ 1087 void 1088 DateFormatRegressionTest::Test4162071(void) 1089 { 1090 UnicodeString dateString("Thu, 30-Jul-1999 11:51:14 GMT"); 1091 UnicodeString format("EEE', 'dd-MMM-yyyy HH:mm:ss z"); // RFC 822/1123 1092 UErrorCode status = U_ZERO_ERROR; 1093 SimpleDateFormat df(format, Locale::getUS(), status); 1094 if(U_FAILURE(status)) { 1095 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status)); 1096 return; 1097 } 1098 1099 //try { 1100 UDate x = df.parse(dateString, status); 1101 if(U_SUCCESS(status)) 1102 logln("Parse format \"" + format + "\" ok"); 1103 else 1104 errln("Parse format \"" + format + "\" failed."); 1105 UnicodeString temp; 1106 FieldPosition pos(FieldPosition::DONT_CARE); 1107 logln(dateString + " -> " + df.format(x, temp, pos)); 1108 //} catch (Exception e) { 1109 // errln("Parse format \"" + format + "\" failed."); 1110 //} 1111 } 1112 1113 /** 1114 * DateFormat shouldn't parse year "-1" as a two-digit year (e.g., "-1" -> 1999). 1115 */ 1116 void DateFormatRegressionTest::Test4182066(void) { 1117 UErrorCode status = U_ZERO_ERROR; 1118 SimpleDateFormat fmt("MM/dd/yy", Locale::getUS(), status); 1119 SimpleDateFormat dispFmt("MMM dd yyyy GG", Locale::getUS(), status); 1120 if (U_FAILURE(status)) { 1121 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status)); 1122 return; 1123 } 1124 1125 /* We expect 2-digit year formats to put 2-digit years in the right 1126 * window. Out of range years, that is, anything less than "00" or 1127 * greater than "99", are treated as literal years. So "1/2/3456" 1128 * becomes 3456 AD. Likewise, "1/2/-3" becomes -3 AD == 2 BC. 1129 */ 1130 const char* STRINGS[] = { 1131 "02/29/00", 1132 "01/23/01", 1133 "04/05/-1", 1134 "01/23/-9", 1135 "11/12/1314", 1136 "10/31/1", 1137 "09/12/+1", 1138 "09/12/001", 1139 }; 1140 int32_t STRINGS_COUNT = UPRV_LENGTHOF(STRINGS); 1141 UDate FAIL_DATE = (UDate) 0; 1142 UDate DATES[] = { 1143 date(2000-1900, UCAL_FEBRUARY, 29), 1144 date(2001-1900, UCAL_JANUARY, 23), 1145 date( -1-1900, UCAL_APRIL, 5), 1146 date( -9-1900, UCAL_JANUARY, 23), 1147 date(1314-1900, UCAL_NOVEMBER, 12), 1148 date( 1-1900, UCAL_OCTOBER, 31), 1149 FAIL_DATE, // "+1" isn't recognized by US NumberFormat 1150 date( 1-1900, UCAL_SEPTEMBER,12), 1151 }; 1152 1153 UnicodeString out; 1154 UBool pass = TRUE; 1155 for (int32_t i=0; i<STRINGS_COUNT; ++i) { 1156 UnicodeString str(STRINGS[i]); 1157 UDate expected = DATES[i]; 1158 status = U_ZERO_ERROR; 1159 UDate actual = fmt.parse(str, status); 1160 if (U_FAILURE(status)) { 1161 actual = FAIL_DATE; 1162 } 1163 UnicodeString actStr; 1164 if (actual == FAIL_DATE) { 1165 actStr.append("null"); 1166 } else { 1167 // Yuck: See j25 1168 ((DateFormat*)&dispFmt)->format(actual, actStr); 1169 } 1170 1171 if (expected == actual) { 1172 out.append(str + " => " + actStr + "\n"); 1173 } else { 1174 UnicodeString expStr; 1175 if (expected == FAIL_DATE) { 1176 expStr.append("null"); 1177 } else { 1178 // Yuck: See j25 1179 ((DateFormat*)&dispFmt)->format(expected, expStr); 1180 } 1181 out.append("FAIL: " + str + " => " + actStr 1182 + ", expected " + expStr + "\n"); 1183 pass = FALSE; 1184 } 1185 } 1186 if (pass) { 1187 log(out); 1188 } else { 1189 err(out); 1190 } 1191 } 1192 1193 /** 1194 * j32 {JDK Bug 4210209 4209272} 1195 * DateFormat cannot parse Feb 29 2000 when setLenient(false) 1196 */ 1197 void 1198 DateFormatRegressionTest::Test4210209(void) { 1199 UErrorCode status = U_ZERO_ERROR; 1200 UnicodeString pattern("MMM d, yyyy"); 1201 SimpleDateFormat sfmt(pattern, Locale::getUS(), status); 1202 SimpleDateFormat sdisp("MMM dd yyyy GG", Locale::getUS(), status); 1203 DateFormat& fmt = *(DateFormat*)&sfmt; // Yuck: See j25 1204 DateFormat& disp = *(DateFormat*)&sdisp; // Yuck: See j25 1205 if (U_FAILURE(status)) { 1206 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status)); 1207 return; 1208 } 1209 Calendar* calx = (Calendar*)fmt.getCalendar(); // cast away const! 1210 calx->setLenient(FALSE); 1211 UDate d = date(2000-1900, UCAL_FEBRUARY, 29); 1212 UnicodeString s, ss; 1213 fmt.format(d, s); 1214 logln(disp.format(d, ss.remove()) + " f> " + pattern + 1215 " => \"" + s + "\""); 1216 ParsePosition pos(0); 1217 d = fmt.parse(s, pos); 1218 logln(UnicodeString("\"") + s + "\" p> " + pattern + 1219 " => " + disp.format(d, ss.remove())); 1220 logln(UnicodeString("Parse pos = ") + pos.getIndex() + 1221 ", error pos = " + pos.getErrorIndex()); 1222 if (pos.getErrorIndex() != -1) { 1223 errln(UnicodeString("FAIL: Error index should be -1")); 1224 } 1225 1226 // The underlying bug is in GregorianCalendar. If the following lines 1227 // succeed, the bug is fixed. If the bug isn't fixed, they will throw 1228 // an exception. 1229 GregorianCalendar cal(status); 1230 if (U_FAILURE(status)) { 1231 errln("FAIL: Unable to create Calendar"); 1232 return; 1233 } 1234 cal.clear(); 1235 cal.setLenient(FALSE); 1236 cal.set(2000, UCAL_FEBRUARY, 29); // This should work! 1237 logln(UnicodeString("Attempt to set Calendar to Feb 29 2000: ") + 1238 disp.format(cal.getTime(status), ss.remove())); 1239 if (U_FAILURE(status)) { 1240 errln("FAIL: Unable to set Calendar to Feb 29 2000"); 1241 } 1242 } 1243 1244 void DateFormatRegressionTest::Test714(void) 1245 { 1246 //try { 1247 UDate d(978103543000.); 1248 DateFormat *fmt = DateFormat::createDateTimeInstance(DateFormat::NONE, 1249 DateFormat::MEDIUM, 1250 Locale::getUS()); 1251 if (fmt == NULL) { 1252 dataerrln("Error calling DateFormat::createDateTimeInstance"); 1253 return; 1254 } 1255 1256 UnicodeString s; 1257 UnicodeString tests = 1258 (UnicodeString) "7:25:43 AM" ; 1259 UErrorCode status = U_ZERO_ERROR; 1260 fmt->format (d,s); 1261 if(U_FAILURE(status)) 1262 { 1263 errln((UnicodeString) "Fail, errmsg " + u_errorName(status)); 1264 return; 1265 } 1266 1267 if(s != tests) 1268 { 1269 errln((UnicodeString) "Fail: " + s + " != " + tests); 1270 } 1271 else 1272 { 1273 logln("OK: " + s + " == " + tests); 1274 } 1275 1276 delete fmt; 1277 } 1278 1279 class Test1684Data { 1280 public: 1281 int32_t year; 1282 int32_t month; 1283 int32_t date; 1284 int32_t womyear; 1285 int32_t wommon; 1286 int32_t wom; 1287 int32_t dow; 1288 UnicodeString data; 1289 UnicodeString normalized; 1290 1291 Test1684Data(int32_t xyear, int32_t xmonth, int32_t xdate, 1292 int32_t xwomyear, int32_t xwommon, int32_t xwom, int32_t xdow, 1293 const char *xdata, const char *xnormalized) : 1294 year(xyear), 1295 month(xmonth-1), 1296 date(xdate), 1297 womyear(xwomyear), 1298 wommon(xwommon-1), 1299 wom(xwom), 1300 dow(xdow), 1301 data(xdata,""), 1302 normalized((xnormalized==NULL)?xdata:xnormalized,"") 1303 { } 1304 }; 1305 1306 void DateFormatRegressionTest::Test1684(void) 1307 { 1308 // July 2001 August 2001 January 2002 1309 // Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa 1310 // 1 2 3 4 5 6 7 1 2 3 4 1 2 3 4 5 1311 // 8 9 10 11 12 13 14 5 6 7 8 9 10 11 6 7 8 9 10 11 12 1312 // 15 16 17 18 19 20 21 12 13 14 15 16 17 18 13 14 15 16 17 18 19 1313 // 22 23 24 25 26 27 28 19 20 21 22 23 24 25 20 21 22 23 24 25 26 1314 // 29 30 31 26 27 28 29 30 31 27 28 29 30 31 1315 Test1684Data *tests[] = { 1316 new Test1684Data(2001, 8, 6, 2001,8,2,UCAL_MONDAY, "2001 08 02 Mon", NULL), 1317 new Test1684Data(2001, 8, 7, 2001,8,2,UCAL_TUESDAY, "2001 08 02 Tue", NULL), 1318 new Test1684Data(2001, 8, 5,/*12,*/ 2001,8,2,UCAL_SUNDAY, "2001 08 02 Sun", NULL), 1319 new Test1684Data(2001, 8,6, /*7, 30,*/ 2001,7,6,UCAL_MONDAY, "2001 07 06 Mon", "2001 08 02 Mon"), 1320 new Test1684Data(2001, 8,7, /*7, 31,*/ 2001,7,6,UCAL_TUESDAY, "2001 07 06 Tue", "2001 08 02 Tue"), 1321 new Test1684Data(2001, 8, 5, 2001,7,6,UCAL_SUNDAY, "2001 07 06 Sun", "2001 08 02 Sun"), 1322 new Test1684Data(2001, 7, 30, 2001,8,1,UCAL_MONDAY, "2001 08 01 Mon", "2001 07 05 Mon"), 1323 new Test1684Data(2001, 7, 31, 2001,8,1,UCAL_TUESDAY, "2001 08 01 Tue", "2001 07 05 Tue"), 1324 new Test1684Data(2001, 7,29, /*8, 5,*/ 2001,8,1,UCAL_SUNDAY, "2001 08 01 Sun", "2001 07 05 Sun"), 1325 new Test1684Data(2001, 12, 31, 2001,12,6,UCAL_MONDAY, "2001 12 06 Mon", NULL), 1326 new Test1684Data(2002, 1, 1, 2002,1,1,UCAL_TUESDAY, "2002 01 01 Tue", NULL), 1327 new Test1684Data(2002, 1, 2, 2002,1,1,UCAL_WEDNESDAY, "2002 01 01 Wed", NULL), 1328 new Test1684Data(2002, 1, 3, 2002,1,1,UCAL_THURSDAY, "2002 01 01 Thu", NULL), 1329 new Test1684Data(2002, 1, 4, 2002,1,1,UCAL_FRIDAY, "2002 01 01 Fri", NULL), 1330 new Test1684Data(2002, 1, 5, 2002,1,1,UCAL_SATURDAY, "2002 01 01 Sat", NULL), 1331 new Test1684Data(2001,12,30, /*2002, 1, 6,*/ 2002,1,1,UCAL_SUNDAY, "2002 01 01 Sun", "2001 12 06 Sun") 1332 }; 1333 1334 #define kTest1684Count UPRV_LENGTHOF(tests) 1335 1336 int32_t pass = 0, error = 0, warning = 0; 1337 int32_t i; 1338 1339 UErrorCode status = U_ZERO_ERROR; 1340 UnicodeString pattern("yyyy MM WW EEE",""); 1341 Calendar *cal = new GregorianCalendar(status); 1342 SimpleDateFormat *sdf = new SimpleDateFormat(pattern,status); 1343 if (U_FAILURE(status)) { 1344 dataerrln("Error constructing SimpleDateFormat"); 1345 for(i=0;i<kTest1684Count;i++) { 1346 delete tests[i]; 1347 } 1348 delete cal; 1349 delete sdf; 1350 return; 1351 } 1352 cal->setFirstDayOfWeek(UCAL_SUNDAY); 1353 cal->setMinimalDaysInFirstWeek(1); 1354 1355 sdf->adoptCalendar(cal); 1356 1357 cal = sdf->getCalendar()->clone(); // sdf may have deleted calendar 1358 1359 if(!cal || !sdf || U_FAILURE(status)) { 1360 errln(UnicodeString("Error setting up test: ") + u_errorName(status)); 1361 } 1362 1363 for (i = 0; i < kTest1684Count; ++i) { 1364 Test1684Data &test = *(tests[i]); 1365 logln(UnicodeString("#") + i + UnicodeString("\n-----\nTesting round trip of ") + test.year + 1366 " " + (test.month + 1) + 1367 " " + test.date + 1368 " (written as) " + test.data); 1369 1370 cal->clear(); 1371 cal->set(test.year, test.month, test.date); 1372 UDate ms = cal->getTime(status); 1373 1374 cal->clear(); 1375 cal->set(UCAL_YEAR, test.womyear); 1376 cal->set(UCAL_MONTH, test.wommon); 1377 cal->set(UCAL_WEEK_OF_MONTH, test.wom); 1378 cal->set(UCAL_DAY_OF_WEEK, test.dow); 1379 UDate ms2 = cal->getTime(status); 1380 1381 if (ms2 != ms) { 1382 errln((UnicodeString)"\nError: GregorianUCAL_DOM gave " + ms + 1383 "\n GregorianUCAL_WOM gave " + ms2); 1384 error++; 1385 } else { 1386 pass++; 1387 } 1388 1389 ms2 = sdf->parse(test.data, status); 1390 if(U_FAILURE(status)) { 1391 errln("parse exception: " + UnicodeString(u_errorName(status))); 1392 } 1393 1394 if (ms2!=ms) { 1395 errln((UnicodeString)"\nError: GregorianCalendar gave " + ms + 1396 "\n SimpleDateFormat.parse gave " + ms2); 1397 error++; 1398 } else { 1399 pass++; 1400 } 1401 1402 UnicodeString result; 1403 sdf->format(ms, result); 1404 if (result != test.normalized) { 1405 errln("\nWarning: format of '" + test.data + "' gave" + 1406 "\n '" + result + "'" + 1407 "\n expected '" + test.normalized + "'"); 1408 warning++; 1409 } else { 1410 pass++; 1411 } 1412 1413 UDate ms3; 1414 ms3 = sdf->parse(result, status); 1415 if(U_FAILURE(status)) { 1416 errln("parse exception 2: " + (UnicodeString)u_errorName(status)); 1417 } 1418 1419 if (ms3!=ms) { 1420 error++; 1421 errln((UnicodeString)"\nError: Re-parse of '" + result + "' gave time of " + 1422 "\n " + ms3 + 1423 "\n not " + ms); 1424 } else { 1425 pass++; 1426 } 1427 } 1428 1429 UnicodeString info 1430 = UnicodeString("Passed: ") + pass + ", Warnings: " + warning + ", Errors: " + error; 1431 if (error > 0) { 1432 errln(info); 1433 } else { 1434 logln(info); 1435 } 1436 1437 for(i=0;i<kTest1684Count;i++) { 1438 delete tests[i]; 1439 } 1440 delete cal; 1441 delete sdf; 1442 } 1443 1444 void DateFormatRegressionTest::Test5554(void) 1445 { 1446 UErrorCode status = U_ZERO_ERROR; 1447 UnicodeString pattern("Z",""); 1448 UnicodeString newfoundland("Canada/Newfoundland", ""); 1449 TimeZone *zone = TimeZone::createTimeZone(newfoundland); 1450 Calendar *cal = new GregorianCalendar(zone, status); 1451 SimpleDateFormat *sdf = new SimpleDateFormat(pattern,status); 1452 if (U_FAILURE(status)) { 1453 dataerrln("Error constructing SimpleDateFormat"); 1454 delete cal; 1455 delete sdf; 1456 return; 1457 } 1458 cal->set(2007, 1, 14); 1459 UDate date = cal->getTime(status); 1460 if (U_FAILURE(status)) { 1461 errln("Error getting time to format"); 1462 return; 1463 }; 1464 sdf->adoptCalendar(cal); 1465 UnicodeString result; 1466 UnicodeString correct("-0330", ""); 1467 sdf->format(date, result); 1468 if (result != correct) { 1469 errln("\nError: Newfoundland Z of Jan 14, 2007 gave '" + result + "', expected '" + correct + "'"); 1470 } 1471 delete sdf; 1472 } 1473 1474 void DateFormatRegressionTest::Test9237(void) 1475 { 1476 UErrorCode status = U_ZERO_ERROR; 1477 UnicodeString pattern("VVVV"); 1478 1479 SimpleDateFormat fmt(pattern, status); // default locale 1480 SimpleDateFormat fmtDE(pattern, Locale("de_DE"), status); 1481 if (U_FAILURE(status)) { 1482 dataerrln("Error constructing SimpleDateFormat"); 1483 return; 1484 } 1485 1486 // copy constructor 1487 SimpleDateFormat fmtCopyDE(fmtDE); 1488 UnicodeString resDE, resCopyDE; 1489 1490 fmtDE.format(0.0, resDE); 1491 fmtCopyDE.format(0.0, resCopyDE); 1492 1493 if (resDE != resCopyDE) { 1494 errln(UnicodeString("Error: different result by the copied instance - org:") + resDE + " copy:" + resCopyDE); 1495 } 1496 1497 // test for assignment operator 1498 fmt = fmtDE; 1499 1500 UnicodeString resAssigned; 1501 fmt.format(0.0, resAssigned); 1502 1503 if (resDE != resAssigned) { 1504 errln(UnicodeString("Error: different results by the assigned instance - org:") + resDE + " assigned:" + resAssigned); 1505 } 1506 } 1507 1508 void DateFormatRegressionTest::TestParsing(void) { 1509 UErrorCode status = U_ZERO_ERROR; 1510 UnicodeString pattern("EEE-WW-MMMM-yyyy"); 1511 UnicodeString text("mon-02-march-2011"); 1512 int32_t expectedDay = 7; 1513 1514 SimpleDateFormat format(pattern, status); 1515 if (U_FAILURE(status)) { 1516 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status)); 1517 return; 1518 } 1519 1520 Calendar *cal = new GregorianCalendar(status); 1521 if (cal == NULL || U_FAILURE(status)) { 1522 errln("Unable to create calendar - %s", u_errorName(status)); 1523 return; 1524 } 1525 1526 ParsePosition pos(0); 1527 format.parse(text, *cal, pos); 1528 1529 if (cal->get(UCAL_DAY_OF_MONTH, status) != expectedDay) { 1530 errln("Parsing failed: day of month should be '7' with pattern: \"" + pattern + "\" for text: \"" + text + "\""); 1531 } 1532 1533 delete cal; 1534 } 1535 1536 void DateFormatRegressionTest::TestT10334(void) { 1537 UErrorCode status = U_ZERO_ERROR; 1538 UnicodeString pattern("'--: 'EEE-WW-MMMM-yyyy"); 1539 UnicodeString text("--mon-02-march-2011"); 1540 SimpleDateFormat format(pattern, status); 1541 1542 logln("pattern["+pattern+"] text["+text+"]"); 1543 1544 if (U_FAILURE(status)) { 1545 dataerrln("Fail creating SimpleDateFormat object - %s", u_errorName(status)); 1546 return; 1547 } 1548 1549 format.setBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, FALSE, status); 1550 format.parse(text, status); 1551 if (!U_FAILURE(status)) { 1552 errln("parse partial match did NOT fail in strict mode - %s", u_errorName(status)); 1553 } 1554 1555 status = U_ZERO_ERROR; 1556 format.setBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, TRUE, status); 1557 format.parse(text, status); 1558 if (U_FAILURE(status)) { 1559 errln("parse partial match failure in lenient mode - %s", u_errorName(status)); 1560 } 1561 1562 status = U_ZERO_ERROR; 1563 pattern = UnicodeString("YYYY MM dd"); 1564 text = UnicodeString("2013 12 10"); 1565 format.applyPattern(pattern); 1566 UDate referenceDate = format.parse(text, status); 1567 1568 FieldPosition fp(FieldPosition::DONT_CARE); 1569 UnicodeString formattedString(""); 1570 pattern = UnicodeString("YYYY LL dd ee cc qq QQ"); 1571 format.applyPattern(pattern); 1572 format.format(referenceDate, formattedString, fp, status); 1573 logln("ref date: " + formattedString); 1574 1575 1576 char patternArray[] = "YYYY LLL dd eee ccc qqq QQQ"; 1577 pattern = UnicodeString(patternArray); 1578 text = UnicodeString("2013 12 10 03 3 04 04"); 1579 status = U_ZERO_ERROR; 1580 format.setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, TRUE, status); 1581 format.applyPattern(pattern); 1582 ParsePosition pp(0); 1583 format.parse(text, pp); 1584 if (pp.getErrorIndex() != -1) { 1585 errln("numeric parse error"); 1586 } 1587 1588 status = U_ZERO_ERROR; 1589 format.setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, FALSE, status); 1590 format.parse(text, status); 1591 if (!U_FAILURE(status)) { 1592 errln("numeric parse did NOT fail in strict mode", u_errorName(status)); 1593 } 1594 1595 } 1596 1597 1598 typedef struct { 1599 const char * locale; 1600 UBool leniency; 1601 UnicodeString parseString; 1602 UnicodeString pattern; 1603 UnicodeString expectedResult; // null indicates expected error 1604 } TestDateFormatLeniencyItem; 1605 1606 1607 void DateFormatRegressionTest::TestT10619(void) { 1608 const UDate july022008 = 1215000001979.0; 1609 const TestDateFormatLeniencyItem items[] = { 1610 //locale leniency parse String pattern expected result 1611 { "en", true, UnicodeString("2008-07 02"), UnicodeString("yyyy-LLLL dd"), UnicodeString("2008-July 02") }, 1612 { "en", false, UnicodeString("2008-07 03"), UnicodeString("yyyy-LLLL dd"), UnicodeString("") }, 1613 { "en", true, UnicodeString("2008-Jan. 04"), UnicodeString("yyyy-LLL dd"), UnicodeString("2008-Jan 04") }, 1614 { "en", false, UnicodeString("2008-Jan. 05"), UnicodeString("yyyy-LLL dd"), UnicodeString("") }, 1615 { "en", true, UnicodeString("2008-Jan--06"), UnicodeString("yyyy-MMM -- dd"), UnicodeString("2008-Jan 06") }, 1616 { "en", false, UnicodeString("2008-Jan--07"), UnicodeString("yyyy-MMM -- dd"), UnicodeString("") }, 1617 { "en", true, UnicodeString("6 Jan 08 2008"), UnicodeString("eee MMM dd yyyy"), UnicodeString("Sat Jan 08 2008") }, 1618 { "en", false, UnicodeString("6 Jan 09 2008"), UnicodeString("eee MMM dd yyyy"), UnicodeString("") }, 1619 // terminator 1620 { NULL, true, UnicodeString(""), UnicodeString(""), UnicodeString("") } 1621 }; 1622 UErrorCode status = U_ZERO_ERROR; 1623 Calendar* cal = Calendar::createInstance(status); 1624 if (U_FAILURE(status)) { 1625 dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale.")); 1626 } else { 1627 cal->setTime(july022008, status); 1628 const TestDateFormatLeniencyItem * itemPtr; 1629 for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) { 1630 1631 Locale locale = Locale::createFromName(itemPtr->locale); 1632 status = U_ZERO_ERROR; 1633 ParsePosition pos(0); 1634 SimpleDateFormat * sdmft = new SimpleDateFormat(itemPtr->pattern, locale, status); 1635 if (U_FAILURE(status)) { 1636 dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status)); 1637 continue; 1638 } 1639 logln("parsing " + itemPtr->parseString); 1640 sdmft->setLenient(itemPtr->leniency); 1641 sdmft->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->leniency, status); 1642 sdmft->setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->leniency, status); 1643 sdmft->setBooleanAttribute(UDAT_PARSE_PARTIAL_LITERAL_MATCH, itemPtr->leniency, status); 1644 sdmft->parse(itemPtr->parseString, pos); 1645 1646 delete sdmft; 1647 if(pos.getErrorIndex() > -1) { 1648 if(itemPtr->expectedResult.length() != 0) { 1649 errln("error: unexpected error - " + itemPtr->parseString + " - error index " + pos.getErrorIndex() + 1650 " - leniency " + itemPtr->leniency); 1651 continue; 1652 } else { 1653 continue; 1654 } 1655 } 1656 } 1657 } 1658 delete cal; 1659 1660 } 1661 1662 1663 typedef struct { 1664 UnicodeString text; 1665 UnicodeString pattern; 1666 int initialParsePos; 1667 } T10855Data; 1668 1669 void DateFormatRegressionTest::TestT10855(void) { 1670 // NOTE: these should NOT parse 1671 const T10855Data items[] = { 1672 //parse String pattern initial parse pos 1673 { UnicodeString("September 30, 1998"), UnicodeString("MM-dd-yyyy"), 0}, 1674 { UnicodeString("123-73-1950"), UnicodeString("MM-dd-yyyy"), -1}, 1675 { UnicodeString("12-23-1950"), UnicodeString("MM-dd-yyyy"), -1}, 1676 // terminator 1677 { UnicodeString(""), UnicodeString(""), 0} 1678 }; 1679 UErrorCode status = U_ZERO_ERROR; 1680 1681 int x = 0; 1682 while(items[x].pattern.length() > 0) 1683 { 1684 status = U_ZERO_ERROR; 1685 logln("Date to parse: \""+items[x].text+"\""); 1686 logln("Starting Index: %d", items[x].initialParsePos); 1687 1688 SimpleDateFormat dateFmt(items[x].pattern, status); 1689 if(U_FAILURE(status)) { 1690 errcheckln(status, "Failed dateFmt: %s", u_errorName(status)); 1691 ++x; 1692 continue; 1693 } 1694 status = U_ZERO_ERROR; 1695 1696 dateFmt.setLenient(false); 1697 dateFmt.setTimeZone(*TimeZone::getGMT()); 1698 1699 ParsePosition position(items[x].initialParsePos); 1700 logln("set position is now: %d", position.getIndex()); 1701 UDate d = dateFmt.parse(items[x].text, position); 1702 if (position.getErrorIndex() != -1 || position.getIndex() == items[x].initialParsePos) { 1703 logln("Parse Failed. ErrorIndex is %d - Index is %d", position.getErrorIndex(), position.getIndex()); 1704 } else { 1705 errln("Parse Succeeded...should have failed. Index is %d - ErrorIndex is %d", position.getIndex(), position.getErrorIndex()); 1706 } 1707 logln("Parsed date returns %d\n", d); 1708 1709 ++x; 1710 } 1711 } 1712 1713 void DateFormatRegressionTest::TestT10906(void) { 1714 1715 UErrorCode status = U_ZERO_ERROR; 1716 UnicodeString pattern = "MM-dd-yyyy"; 1717 UnicodeString text = "06-10-2014"; 1718 SimpleDateFormat format(pattern, status); 1719 int32_t errorIdx = 0; 1720 ParsePosition pp(-1); 1721 format.parse(text, pp); 1722 errorIdx = pp.getErrorIndex(); 1723 if (errorIdx == -1) { 1724 errln("failed to report invalid (negative) starting parse position"); 1725 } 1726 } 1727 1728 void DateFormatRegressionTest::TestT13380(void) { 1729 UErrorCode errorCode = U_ZERO_ERROR; 1730 LocalPointer<DateFormat> enFmt(DateFormat::createDateInstance(DateFormat::kShort, Locale("en")), errorCode); 1731 if (U_FAILURE(errorCode)) { 1732 errln("failure creating 'en' DateFormat"); 1733 } 1734 1735 errorCode = U_ZERO_ERROR; 1736 LocalPointer<DateFormat> tgFmt(DateFormat::createDateInstance(DateFormat::kShort, Locale("tg")), errorCode); 1737 if (U_FAILURE(errorCode)) { 1738 errln("failure creating 'tg' DateFormat"); 1739 } 1740 } 1741 1742 #endif /* #if !UCONFIG_NO_FORMATTING */ 1743 1744 //eof 1745