1/* GENERATED SOURCE. DO NOT MODIFY. */ 2// © 2016 and later: Unicode, Inc. and others. 3// License & terms of use: http://www.unicode.org/copyright.html#License 4/* 5 ******************************************************************************* 6 * Copyright (C) 2001-2015, International Business Machines Corporation and * 7 * others. All Rights Reserved. * 8 ******************************************************************************* 9 */ 10 11/** 12 * Port From: ICU4C v1.8.1 : format : DateFormatRegressionTest 13 * Source File: $ICU4CRoot/source/test/intltest/dtfmrgts.cpp 14 **/ 15 16package android.icu.dev.test.format; 17 18import java.io.ByteArrayInputStream; 19import java.io.ByteArrayOutputStream; 20import java.io.IOException; 21import java.io.ObjectInputStream; 22import java.io.ObjectOutputStream; 23import java.io.OptionalDataException; 24import java.text.FieldPosition; 25import java.text.Format; 26import java.text.ParseException; 27import java.text.ParsePosition; 28import java.util.Date; 29import java.util.Locale; 30 31import org.junit.Test; 32 33import android.icu.text.DateFormat; 34import android.icu.text.SimpleDateFormat; 35import android.icu.util.Calendar; 36import android.icu.util.GregorianCalendar; 37import android.icu.util.IslamicCalendar; 38import android.icu.util.JapaneseCalendar; 39import android.icu.util.SimpleTimeZone; 40import android.icu.util.TimeZone; 41import android.icu.util.ULocale; 42 43/** 44 * Performs regression test for DateFormat 45 **/ 46public class DateFormatRegressionTest extends android.icu.dev.test.TestFmwk { 47 /** 48 * @bug 4029195 49 */ 50 @Test 51 public void Test4029195() { 52 Calendar cal = Calendar.getInstance(); 53 Date today = cal.getTime(); 54 logln("today: " + today); 55 SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance(); 56 String pat = sdf.toPattern(); 57 logln("pattern: " + pat); 58 StringBuffer fmtd = new StringBuffer(""); 59 FieldPosition pos = new FieldPosition(0); 60 fmtd = sdf.format(today, fmtd, pos); 61 logln("today: " + fmtd); 62 63 sdf.applyPattern("G yyyy DDD"); 64 StringBuffer todayS = new StringBuffer(""); 65 todayS = sdf.format(today, todayS, pos); 66 logln("today: " + todayS); 67 try { 68 today = sdf.parse(todayS.toString()); 69 logln("today date: " + today); 70 } catch (Exception e) { 71 errln("Error reparsing date: " + e.getMessage()); 72 } 73 74 try { 75 StringBuffer rt = new StringBuffer(""); 76 rt = sdf.format(sdf.parse(todayS.toString()), rt, pos); 77 logln("round trip: " + rt); 78 if (!rt.toString().equals(todayS.toString())) 79 errln("Fail: Want " + todayS + " Got " + rt); 80 } catch (ParseException e) { 81 errln("Fail: " + e); 82 e.printStackTrace(); 83 } 84 } 85 86 /** 87 * @bug 4052408 88 */ 89 @Test 90 public void Test4052408() { 91 92 DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.US); 93 Calendar cal = Calendar.getInstance(); 94 cal.clear(); 95 cal.set(97 + 1900, Calendar.MAY, 3, 8, 55); 96 Date dt = cal.getTime(); 97 String str = fmt.format(dt); 98 logln(str); 99 100 if (!str.equals("5/3/97, 8:55 AM")) 101 errln("Fail: Test broken; Want 5/3/97, 8:55 AM Got " + str); 102 103 String expected[] = { 104 "", //"ERA_FIELD", 105 "97", //"YEAR_FIELD", 106 "5", //"MONTH_FIELD", 107 "3", //"DATE_FIELD", 108 "", //"HOUR_OF_DAY1_FIELD", 109 "", //"HOUR_OF_DAY0_FIELD", 110 "55", //"MINUTE_FIELD", 111 "", //"SECOND_FIELD", 112 "", //"MILLISECOND_FIELD", 113 "", //"DAY_OF_WEEK_FIELD", 114 "", //"DAY_OF_YEAR_FIELD", 115 "", //"DAY_OF_WEEK_IN_MONTH_FIELD", 116 "", //"WEEK_OF_YEAR_FIELD", 117 "", //"WEEK_OF_MONTH_FIELD", 118 "AM", //"AM_PM_FIELD", 119 "8", //"HOUR1_FIELD", 120 "", //"HOUR0_FIELD", 121 "" //"TIMEZONE_FIELD" 122 }; 123 String fieldNames[] = { 124 "ERA_FIELD", 125 "YEAR_FIELD", 126 "MONTH_FIELD", 127 "DATE_FIELD", 128 "HOUR_OF_DAY1_FIELD", 129 "HOUR_OF_DAY0_FIELD", 130 "MINUTE_FIELD", 131 "SECOND_FIELD", 132 "MILLISECOND_FIELD", 133 "DAY_OF_WEEK_FIELD", 134 "DAY_OF_YEAR_FIELD", 135 "DAY_OF_WEEK_IN_MONTH_FIELD", 136 "WEEK_OF_YEAR_FIELD", 137 "WEEK_OF_MONTH_FIELD", 138 "AM_PM_FIELD", 139 "HOUR1_FIELD", 140 "HOUR0_FIELD", 141 "TIMEZONE_FIELD"}; 142 143 boolean pass = true; 144 for (int i = 0; i <= 17; ++i) { 145 FieldPosition pos = new FieldPosition(i); 146 StringBuffer buf = new StringBuffer(""); 147 fmt.format(dt, buf, pos); 148 //char[] dst = new char[pos.getEndIndex() - pos.getBeginIndex()]; 149 String dst = buf.substring(pos.getBeginIndex(), pos.getEndIndex()); 150 str = dst; 151 log(i + ": " + fieldNames[i] + ", \"" + str + "\", " 152 + pos.getBeginIndex() + ", " + pos.getEndIndex()); 153 String exp = expected[i]; 154 if ((exp.length() == 0 && str.length() == 0) || str.equals(exp)) 155 logln(" ok"); 156 else { 157 logln(" expected " + exp); 158 pass = false; 159 } 160 } 161 if (!pass) 162 errln("Fail: FieldPosition not set right by DateFormat"); 163 } 164 165 /** 166 * @bug 4056591 167 * Verify the function of the [s|g]et2DigitYearStart() API. 168 */ 169 @Test 170 public void Test4056591() { 171 172 try { 173 SimpleDateFormat fmt = new SimpleDateFormat("yyMMdd", Locale.US); 174 Calendar cal = Calendar.getInstance(); 175 cal.clear(); 176 cal.set(1809, Calendar.DECEMBER, 25); 177 Date start = cal.getTime(); 178 fmt.set2DigitYearStart(start); 179 if ((fmt.get2DigitYearStart() != start)) 180 errln("get2DigitYearStart broken"); 181 cal.clear(); 182 cal.set(1809, Calendar.DECEMBER, 25); 183 Date d1 = cal.getTime(); 184 cal.clear(); 185 cal.set(1909, Calendar.DECEMBER, 24); 186 Date d2 = cal.getTime(); 187 cal.clear(); 188 cal.set(1809, Calendar.DECEMBER, 26); 189 Date d3 = cal.getTime(); 190 cal.clear(); 191 cal.set(1861, Calendar.DECEMBER, 25); 192 Date d4 = cal.getTime(); 193 194 Date dates[] = {d1, d2, d3, d4}; 195 196 String strings[] = {"091225", "091224", "091226", "611225"}; 197 198 for (int i = 0; i < 4; i++) { 199 String s = strings[i]; 200 Date exp = dates[i]; 201 Date got = fmt.parse(s); 202 logln(s + " . " + got + "; exp " + exp); 203 if (got.getTime() != exp.getTime()) 204 errln("set2DigitYearStart broken"); 205 } 206 } catch (ParseException e) { 207 errln("Fail: " + e); 208 e.printStackTrace(); 209 } 210 } 211 212 /** 213 * @bug 4059917 214 */ 215 @Test 216 public void Test4059917() { 217 SimpleDateFormat fmt; 218 String myDate; 219 fmt = new SimpleDateFormat("yyyy/MM/dd"); 220 myDate = "1997/01/01"; 221 aux917( fmt, myDate ); 222 fmt = new SimpleDateFormat("yyyyMMdd"); 223 myDate = "19970101"; 224 aux917( fmt, myDate ); 225 } 226 227 public void aux917(SimpleDateFormat fmt, String str) { 228 229 String pat = fmt.toPattern(); 230 logln("=================="); 231 logln("testIt: pattern=" + pat + " string=" + str); 232 ParsePosition pos = new ParsePosition(0); 233 Object o = fmt.parseObject(str, pos); 234 //logln( UnicodeString("Parsed object: ") + o ); 235 236 StringBuffer formatted = new StringBuffer(""); 237 FieldPosition poss = new FieldPosition(0); 238 formatted = fmt.format(o, formatted, poss); 239 240 logln("Formatted string: " + formatted); 241 if (!formatted.toString().equals(str)) 242 errln("Fail: Want " + str + " Got " + formatted); 243 } 244 245 /** 246 * @bug 4060212 247 */ 248 @Test 249 public void Test4060212() { 250 String dateString = "1995-040.05:01:29"; 251 logln("dateString= " + dateString); 252 logln("Using yyyy-DDD.hh:mm:ss"); 253 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-DDD.hh:mm:ss"); 254 ParsePosition pos = new ParsePosition(0); 255 Date myDate = formatter.parse(dateString, pos); 256 DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.LONG); 257 String myString = fmt.format(myDate); 258 logln(myString); 259 Calendar cal = new GregorianCalendar(); 260 cal.setTime(myDate); 261 if ((cal.get(Calendar.DAY_OF_YEAR) != 40)) 262 errln("Fail: Got " + cal.get(Calendar.DAY_OF_YEAR) + " Want 40"); 263 264 logln("Using yyyy-ddd.hh:mm:ss"); 265 formatter = new SimpleDateFormat("yyyy-ddd.hh:mm:ss"); 266 pos.setIndex(0); 267 myDate = formatter.parse(dateString, pos); 268 myString = fmt.format(myDate); 269 logln(myString); 270 cal.setTime(myDate); 271 if ((cal.get(Calendar.DAY_OF_YEAR) != 40)) 272 errln("Fail: Got " + cal.get(Calendar.DAY_OF_YEAR) + " Want 40"); 273 } 274 /** 275 * @bug 4061287 276 */ 277 @Test 278 public void Test4061287() { 279 280 SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy"); 281 try { 282 logln(df.parse("35/01/1971").toString()); 283 } catch (ParseException e) { 284 errln("Fail: " + e); 285 e.printStackTrace(); 286 } 287 df.setLenient(false); 288 boolean ok = false; 289 try { 290 logln(df.parse("35/01/1971").toString()); 291 } catch (ParseException e) { 292 ok = true; 293 } 294 if (!ok) 295 errln("Fail: Lenient not working"); 296 } 297 298 /** 299 * @bug 4065240 300 */ 301 @Test 302 public void Test4065240() { 303 Date curDate; 304 DateFormat shortdate, fulldate; 305 String strShortDate, strFullDate; 306 Locale saveLocale = Locale.getDefault(); 307 TimeZone saveZone = TimeZone.getDefault(); 308 309 try { 310 Locale curLocale = new Locale("de", "DE"); 311 Locale.setDefault(curLocale); 312 // {sfb} adoptDefault instead of setDefault 313 //TimeZone.setDefault(TimeZone.createTimeZone("EST")); 314 TimeZone.setDefault(TimeZone.getTimeZone("EST")); 315 Calendar cal = Calendar.getInstance(); 316 cal.clear(); 317 cal.set(98 + 1900, 0, 1); 318 curDate = cal.getTime(); 319 shortdate = DateFormat.getDateInstance(DateFormat.SHORT); 320 fulldate = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG); 321 strShortDate = "The current date (short form) is "; 322 String temp; 323 temp = shortdate.format(curDate); 324 strShortDate += temp; 325 strFullDate = "The current date (long form) is "; 326 String temp2 = fulldate.format(curDate); 327 strFullDate += temp2; 328 329 logln(strShortDate); 330 logln(strFullDate); 331 332 // {sfb} What to do with resource bundle stuff????? 333 334 // Check to see if the resource is present; if not, we can't test 335 //ResourceBundle bundle = //The variable is never used 336 // ICULocaleData.getBundle("DateFormatZoneData", curLocale); 337 338 // {sfb} API change to ResourceBundle -- add getLocale() 339 /*if (bundle.getLocale().getLanguage().equals("de")) { 340 // UPDATE THIS AS ZONE NAME RESOURCE FOR <EST> in de_DE is updated 341 if (!strFullDate.endsWith("GMT-05:00")) 342 errln("Fail: Want GMT-05:00"); 343 } else { 344 logln("*** TEST COULD NOT BE COMPLETED BECAUSE DateFormatZoneData ***"); 345 logln("*** FOR LOCALE de OR de_DE IS MISSING ***"); 346 }*/ 347 } catch (Exception e) { 348 logln(e.getMessage()); 349 } finally { 350 Locale.setDefault(saveLocale); 351 TimeZone.setDefault(saveZone); 352 } 353 354 } 355 356 /* 357 DateFormat.equals is too narrowly defined. As a result, MessageFormat 358 does not work correctly. DateFormat.equals needs to be written so 359 that the Calendar sub-object is not compared using Calendar.equals, 360 but rather compared for equivalency. This may necessitate adding a 361 (package private) method to Calendar to test for equivalency. 362 363 Currently this bug breaks MessageFormat.toPattern 364 */ 365 /** 366 * @bug 4071441 367 */ 368 @Test 369 public void Test4071441() { 370 DateFormat fmtA = DateFormat.getInstance(); 371 DateFormat fmtB = DateFormat.getInstance(); 372 373 // {sfb} Is it OK to cast away const here? 374 Calendar calA = fmtA.getCalendar(); 375 Calendar calB = fmtB.getCalendar(); 376 calA.clear(); 377 calA.set(1900, 0 ,0); 378 calB.clear(); 379 calB.set(1900, 0, 0); 380 if (!calA.equals(calB)) 381 errln("Fail: Can't complete test; Calendar instances unequal"); 382 if (!fmtA.equals(fmtB)) 383 errln("Fail: DateFormat unequal when Calendars equal"); 384 calB.clear(); 385 calB.set(1961, Calendar.DECEMBER, 25); 386 if (calA.equals(calB)) 387 errln("Fail: Can't complete test; Calendar instances equal"); 388 if (!fmtA.equals(fmtB)) 389 errln("Fail: DateFormat unequal when Calendars equivalent"); 390 logln("DateFormat.equals ok"); 391 } 392 393 /* The java.text.DateFormat.parse(String) method expects for the 394 US locale a string formatted according to mm/dd/yy and parses it 395 correctly. 396 397 When given a string mm/dd/yyyy it only parses up to the first 398 two y's, typically resulting in a date in the year 1919. 399 400 Please extend the parsing method(s) to handle strings with 401 four-digit year values (probably also applicable to various 402 other locales. */ 403 /** 404 * @bug 4073003 405 */ 406 @Test 407 public void Test4073003() { 408 try { 409 DateFormat fmt = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US); 410 String tests[] = {"12/25/61", "12/25/1961", "4/3/2010", "4/3/10"}; 411 for (int i = 0; i < 4; i += 2) { 412 Date d = fmt.parse(tests[i]); 413 Date dd = fmt.parse(tests[i + 1]); 414 String s; 415 s = fmt.format(d); 416 String ss; 417 ss = fmt.format(dd); 418 if (d.getTime() != dd.getTime()) 419 errln("Fail: " + d + " != " + dd); 420 if (!s.equals(ss)) 421 errln("Fail: " + s + " != " + ss); 422 logln("Ok: " + s + " " + d); 423 } 424 } catch (ParseException e) { 425 errln("Fail: " + e); 426 e.printStackTrace(); 427 } 428 } 429 430 /** 431 * @bug 4089106 432 */ 433 @Test 434 public void Test4089106() { 435 TimeZone def = TimeZone.getDefault(); 436 try { 437 TimeZone z = new SimpleTimeZone((int) (1.25 * 3600000), "FAKEZONE"); 438 TimeZone.setDefault(z); 439 // Android patch (http://b/28949992) start. 440 // ICU TimeZone.setDefault() not supported on Android. 441 z = TimeZone.getDefault(); 442 // Android patch (http://b/28949992) end. 443 SimpleDateFormat f = new SimpleDateFormat(); 444 if (!f.getTimeZone().equals(z)) 445 errln("Fail: SimpleTimeZone should use TimeZone.getDefault()"); 446 } finally { 447 TimeZone.setDefault(def); 448 } 449 } 450 451 /** 452 * @bug 4100302 453 */ 454 @Test 455 public void Test4100302() { 456 457 Locale locales[] = { 458 Locale.CANADA, Locale.CANADA_FRENCH, Locale.CHINA, 459 Locale.CHINESE, Locale.ENGLISH, Locale.FRANCE, Locale.FRENCH, 460 Locale.GERMAN, Locale.GERMANY, Locale.ITALIAN, Locale.ITALY, 461 Locale.JAPAN, Locale.JAPANESE, Locale.KOREA, Locale.KOREAN, 462 Locale.PRC, Locale.SIMPLIFIED_CHINESE, Locale.TAIWAN, 463 Locale.TRADITIONAL_CHINESE, Locale.UK, Locale.US}; 464 try { 465 boolean pass = true; 466 for (int i = 0; i < 21; i++) { 467 Format format = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locales[i]); 468 byte[] bytes; 469 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 470 ObjectOutputStream oos = new ObjectOutputStream(baos); 471 oos.writeObject(format); 472 oos.flush(); 473 baos.close(); 474 bytes = baos.toByteArray(); 475 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); 476 Object o = ois.readObject(); 477 if (!format.equals(o)) { 478 pass = false; 479 logln("DateFormat instance for locale " + locales[i] + " is incorrectly serialized/deserialized."); 480 } else { 481 logln("DateFormat instance for locale " + locales[i] + " is OKAY."); 482 } 483 } 484 if (!pass) 485 errln("Fail: DateFormat serialization/equality bug"); 486 } catch (OptionalDataException e) { 487 errln("Fail: " + e); 488 } catch (IOException e) { 489 errln("Fail: " + e); 490 } catch (ClassNotFoundException e) { 491 errln("Fail: " + e); 492 } 493 494 } 495 496 /** 497 * @bug 4101483 498 */ 499 @Test 500 public void Test4101483() { 501 SimpleDateFormat sdf = new SimpleDateFormat("z", Locale.US); 502 FieldPosition fp = new FieldPosition(DateFormat.TIMEZONE_FIELD); 503 Date d = new Date(9234567890L); 504 StringBuffer buf = new StringBuffer(""); 505 sdf.format(d, buf, fp); 506 logln(sdf.format(d, buf, fp).toString()); 507 logln("beginIndex = " + fp.getBeginIndex()); 508 logln("endIndex = " + fp.getEndIndex()); 509 if (fp.getBeginIndex() == fp.getEndIndex()) 510 errln("Fail: Empty field"); 511 } 512 513 /** 514 * @bug 4103340 515 * @bug 4138203 516 * This bug really only works in Locale.US, since that's what the locale 517 * used for Date.toString() is. Bug 4138203 reports that it fails on Korean 518 * NT; it would actually have failed on any non-US locale. Now it should 519 * work on all locales. 520 */ 521 @Test 522 public void Test4103340() { 523 524 // choose a date that is the FIRST of some month 525 // and some arbitrary time 526 Calendar cal = Calendar.getInstance(); 527 cal.clear(); 528 cal.set(1997, 3, 1, 1, 1, 1); 529 Date d = cal.getTime(); 530 SimpleDateFormat df = new SimpleDateFormat("MMMM", Locale.US); 531 String s = d.toString(); 532 StringBuffer s2 = new StringBuffer(""); 533 FieldPosition pos = new FieldPosition(0); 534 s2 = df.format(d, s2, pos); 535 logln("Date=" + s); 536 logln("DF=" + s2); 537 String substr = s2.substring(0,2); 538 if (s.indexOf(substr) == -1) 539 errln("Months should match"); 540 } 541 542 /** 543 * @bug 4103341 544 */ 545 @Test 546 public void Test4103341() { 547 TimeZone saveZone = TimeZone.getDefault(); 548 try { 549 // {sfb} changed from adoptDefault to setDefault 550 TimeZone.setDefault(TimeZone.getTimeZone("CST")); 551 SimpleDateFormat simple = new SimpleDateFormat("MM/dd/yyyy HH:mm"); 552 TimeZone temp = TimeZone.getDefault(); 553 if (!simple.getTimeZone().equals(temp)) 554 errln("Fail: SimpleDateFormat not using default zone"); 555 } finally { 556 TimeZone.setDefault(saveZone); 557 } 558 } 559 560 /** 561 * @bug 4104136 562 */ 563 @Test 564 public void Test4104136() { 565 SimpleDateFormat sdf = new SimpleDateFormat(); 566 String pattern = "'time' hh:mm"; 567 sdf.applyPattern(pattern); 568 logln("pattern: \"" + pattern + "\""); 569 String strings[] = {"time 10:30", "time 10:x", "time 10x"}; 570 ParsePosition ppos[] = {new ParsePosition(10), new ParsePosition(0), new ParsePosition(0)}; 571 Calendar cal = Calendar.getInstance(); 572 cal.clear(); 573 cal.set(1970, Calendar.JANUARY, 1, 10, 30); 574 Date dates[] = {cal.getTime(), new Date(-1), new Date(-1)}; 575 for (int i = 0; i < 3; i++) { 576 String text = strings[i]; 577 ParsePosition finish = ppos[i]; 578 Date exp = dates[i]; 579 ParsePosition pos = new ParsePosition(0); 580 Date d = sdf.parse(text, pos); 581 logln(" text: \"" + text + "\""); 582 logln(" index: %d" + pos.getIndex()); 583 logln(" result: " + d); 584 if (pos.getIndex() != finish.getIndex()) 585 errln("Fail: Expected pos " + finish.getIndex()); 586 if (!((d == null && exp.equals(new Date(-1))) || (d.equals(exp)))) 587 errln( "Fail: Expected result " + exp); 588 } 589 } 590 591 /** 592 * @bug 4104522 593 * CANNOT REPRODUCE 594 * According to the bug report, this test should throw a 595 * StringIndexOutOfBoundsException during the second parse. However, 596 * this is not seen. 597 */ 598 @Test 599 public void Test4104522() { 600 SimpleDateFormat sdf = new SimpleDateFormat(); 601 String pattern = "'time' hh:mm"; 602 sdf.applyPattern(pattern); 603 logln("pattern: \"" + pattern + "\""); 604 // works correctly 605 ParsePosition pp = new ParsePosition(0); 606 String text = "time "; 607 Date dt = sdf.parse(text, pp); 608 logln(" text: \"" + text + "\"" + " date: " + dt); 609 // works wrong 610 pp.setIndex(0); 611 text = "time"; 612 dt = sdf.parse(text, pp); 613 logln(" text: \"" + text + "\"" + " date: " + dt); 614 } 615 616 /** 617 * @bug 4106807 618 */ 619 @Test 620 public void Test4106807() { 621 Date dt; 622 DateFormat df = DateFormat.getDateTimeInstance(); 623 624 SimpleDateFormat sdfs[] = { 625 new SimpleDateFormat("yyyyMMddHHmmss"), 626 new SimpleDateFormat("yyyyMMddHHmmss'Z'"), 627 new SimpleDateFormat("yyyyMMddHHmmss''"), 628 new SimpleDateFormat("yyyyMMddHHmmss'a''a'"), 629 new SimpleDateFormat("yyyyMMddHHmmss %")}; 630 String strings[] = { 631 "19980211140000", 632 "19980211140000", 633 "19980211140000", 634 "19980211140000a", 635 "19980211140000 "}; 636 GregorianCalendar gc = new GregorianCalendar(); 637 TimeZone timeZone = TimeZone.getDefault(); 638 TimeZone gmt = (TimeZone) timeZone.clone(); 639 gmt.setRawOffset(0); 640 for (int i = 0; i < 5; i++) { 641 SimpleDateFormat format = sdfs[i]; 642 String dateString = strings[i]; 643 try { 644 format.setTimeZone(gmt); 645 dt = format.parse(dateString); 646 // {sfb} some of these parses will fail purposely 647 648 StringBuffer fmtd = new StringBuffer(""); 649 FieldPosition pos = new FieldPosition(0); 650 fmtd = df.format(dt, fmtd, pos); 651 logln(fmtd.toString()); 652 //logln(df.format(dt)); 653 gc.setTime(dt); 654 logln("" + gc.get(Calendar.ZONE_OFFSET)); 655 StringBuffer s = new StringBuffer(""); 656 s = format.format(dt, s, pos); 657 logln(s.toString()); 658 } catch (ParseException e) { 659 logln("No way Jose"); 660 } 661 } 662 } 663 664 /* 665 Synopsis: Chinese time zone CTT is not recogonized correctly. 666 Description: Platform Chinese Windows 95 - ** Time zone set to CST ** 667 */ 668 /** 669 * @bug 4108407 670 */ 671 672 // {sfb} what to do with this one ?? 673 @Test 674 public void Test4108407() { 675 /* 676 // TODO user.timezone is a protected system property, catch securityexception and warn 677 // if this is reenabled 678 long l = System.currentTimeMillis(); 679 logln("user.timezone = " + System.getProperty("user.timezone", "?")); 680 logln("Time Zone :" + 681 DateFormat.getDateInstance().getTimeZone().getID()); 682 logln("Default format :" + 683 DateFormat.getDateInstance().format(new Date(l))); 684 logln("Full format :" + 685 DateFormat.getDateInstance(DateFormat.FULL).format(new 686 Date(l))); 687 logln("*** Set host TZ to CST ***"); 688 logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***"); 689 */ 690 } 691 692 /** 693 * @bug 4134203 694 * SimpleDateFormat won't parse "GMT" 695 */ 696 @Test 697 public void Test4134203() { 698 String dateFormat = "MM/dd/yy HH:mm:ss zzz"; 699 SimpleDateFormat fmt = new SimpleDateFormat(dateFormat); 700 701 ParsePosition p0 = new ParsePosition(0); 702 Date d = fmt.parse("01/22/92 04:52:00 GMT", p0); 703 logln(d.toString()); 704 if(p0.equals(new ParsePosition(0))) 705 errln("Fail: failed to parse 'GMT'"); 706 // In the failure case an exception is thrown by parse(); 707 // if no exception is thrown, the test passes. 708 } 709 710 /** 711 * @bug 4151631 712 * SimpleDateFormat incorrect handling of 2 single quotes in format() 713 */ 714 @Test 715 public void Test4151631() { 716 String pattern = 717 "'TO_DATE('''dd'-'MM'-'yyyy HH:mm:ss''' , ''DD-MM-YYYY HH:MI:SS'')'"; 718 logln("pattern=" + pattern); 719 SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.US); 720 StringBuffer result = new StringBuffer(""); 721 FieldPosition pos = new FieldPosition(0); 722 Calendar cal = Calendar.getInstance(); 723 cal.clear(); 724 cal.set(1998, Calendar.JUNE, 30, 13, 30, 0); 725 Date d = cal.getTime(); 726 result = format.format(d, result, pos); 727 if (!result.toString().equals("TO_DATE('30-06-1998 13:30:00' , 'DD-MM-YYYY HH:MI:SS')")) { 728 errln("Fail: result=" + result); 729 } else { 730 logln("Pass: result=" + result); 731 } 732 } 733 734 /** 735 * @bug 4151706 736 * 'z' at end of date format throws index exception in SimpleDateFormat 737 * CANNOT REPRODUCE THIS BUG ON 1.2FCS 738 */ 739 @Test 740 public void Test4151706() { 741 String dateString = "Thursday, 31-Dec-98 23:00:00 GMT"; 742 SimpleDateFormat fmt = new SimpleDateFormat("EEEE, dd-MMM-yy HH:mm:ss z", Locale.US); 743 Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.US); 744 cal.clear(); 745 cal.set(1998, Calendar.DECEMBER, 31, 23, 0, 0); 746 Date d = new Date(); 747 try { 748 d = fmt.parse(dateString); 749 // {sfb} what about next two lines? 750 if (d.getTime() != cal.getTime().getTime()) 751 errln("Incorrect value: " + d); 752 } catch (Exception e) { 753 errln("Fail: " + e); 754 } 755 StringBuffer temp = new StringBuffer(""); 756 FieldPosition pos = new FieldPosition(0); 757 logln(dateString + " . " + fmt.format(d, temp, pos)); 758 } 759 760 /** 761 * @bug 4162071 762 * Cannot reproduce this bug under 1.2 FCS -- it may be a convoluted duplicate 763 * of some other bug that has been fixed. 764 */ 765 @Test 766 public void Test4162071() { 767 String dateString = "Thu, 30-Jul-1999 11:51:14 GMT"; 768 String format = "EEE', 'dd-MMM-yyyy HH:mm:ss z"; // RFC 822/1123 769 SimpleDateFormat df = new SimpleDateFormat(format, Locale.US); 770 try { 771 Date x = df.parse(dateString); 772 StringBuffer temp = new StringBuffer(""); 773 FieldPosition pos = new FieldPosition(0); 774 logln(dateString + " -> " + df.format(x, temp, pos)); 775 } catch (Exception e) { 776 errln("Parse format \"" + format + "\" failed."); 777 } 778 } 779 780 /** 781 * DateFormat shouldn't parse year "-1" as a two-digit year (e.g., "-1" . 1999). 782 */ 783 @Test 784 public void Test4182066() { 785 SimpleDateFormat fmt = new SimpleDateFormat("MM/dd/yy", Locale.US); 786 SimpleDateFormat dispFmt = new SimpleDateFormat("MMM dd yyyy HH:mm:ss GG", Locale.US); 787 /* We expect 2-digit year formats to put 2-digit years in the right 788 * window. Out of range years, that is, anything less than "00" or 789 * greater than "99", are treated as literal years. So "1/2/3456" 790 * becomes 3456 AD. Likewise, "1/2/-3" becomes -3 AD == 2 BC. 791 */ 792 final String STRINGS[] = 793 {"02/29/00", "01/23/01", "04/05/-1", "01/23/-9", "11/12/1314", "10/31/1", "09/12/+1", "09/12/001",}; 794 int STRINGS_COUNT = STRINGS.length; 795 796 Calendar cal = Calendar.getInstance(); 797 Date FAIL_DATE = cal.getTime(); 798 cal.clear(); 799 cal.set(2000, Calendar.FEBRUARY, 29); 800 Date d0 = cal.getTime(); 801 cal.clear(); 802 cal.set(2001, Calendar.JANUARY, 23); 803 Date d1 = cal.getTime(); 804 cal.clear(); 805 cal.set(-1, Calendar.APRIL, 5); 806 Date d2 = cal.getTime(); 807 cal.clear(); 808 cal.set(-9, Calendar.JANUARY, 23); 809 Date d3 = cal.getTime(); 810 cal.clear(); 811 cal.set(1314, Calendar.NOVEMBER, 12); 812 Date d4 = cal.getTime(); 813 cal.clear(); 814 cal.set(1, Calendar.OCTOBER, 31); 815 Date d5 = cal.getTime(); 816 cal.clear(); 817 cal.set(1, Calendar.SEPTEMBER, 12); 818 Date d7 = cal.getTime(); 819 Date DATES[] = {d0, d1, d2, d3, d4, d5, FAIL_DATE, d7}; 820 821 String out = ""; 822 boolean pass = true; 823 for (int i = 0; i < STRINGS_COUNT; ++i) { 824 String str = STRINGS[i]; 825 Date expected = DATES[i]; 826 Date actual = null; 827 try { 828 actual = fmt.parse(str); 829 } catch (ParseException e) { 830 actual = FAIL_DATE; 831 } 832 String actStr = ""; 833 if ((actual.getTime()) == FAIL_DATE.getTime()) { 834 actStr += "null"; 835 } else { 836 // Yuck: See j25 837 actStr = ((DateFormat) dispFmt).format(actual); 838 } 839 840 if (expected.getTime() == (actual.getTime())) { 841 out += str + " => " + actStr + "\n"; 842 } else { 843 String expStr = ""; 844 if (expected.getTime() == FAIL_DATE.getTime()) { 845 expStr += "null"; 846 } else { 847 // Yuck: See j25 848 expStr = ((DateFormat) dispFmt).format(expected); 849 } 850 out += "FAIL: " + str + " => " + actStr + ", expected " + expStr + "\n"; 851 pass = false; 852 } 853 } 854 if (pass) { 855 log(out); 856 } else { 857 err(out); 858 } 859 } 860 861 /** 862 * j32 {JDK Bug 4210209 4209272} 863 * DateFormat cannot parse Feb 29 2000 when setLenient(false) 864 */ 865 @Test 866 public void Test4210209() { 867 868 String pattern = "MMM d, yyyy"; 869 DateFormat fmt = new SimpleDateFormat(pattern, Locale.US); 870 DateFormat disp = new SimpleDateFormat("MMM dd yyyy GG", Locale.US); 871 872 Calendar calx = fmt.getCalendar(); 873 calx.setLenient(false); 874 Calendar calendar = Calendar.getInstance(); 875 calendar.clear(); 876 calendar.set(2000, Calendar.FEBRUARY, 29); 877 Date d = calendar.getTime(); 878 String s = fmt.format(d); 879 logln(disp.format(d) + " f> " + pattern + " => \"" + s + "\""); 880 ParsePosition pos = new ParsePosition(0); 881 d = fmt.parse(s, pos); 882 logln("\"" + s + "\" p> " + pattern + " => " + 883 (d!=null?disp.format(d):"null")); 884 logln("Parse pos = " + pos.getIndex() + ", error pos = " + pos.getErrorIndex()); 885 if (pos.getErrorIndex() != -1) { 886 errln("FAIL: Error index should be -1"); 887 } 888 889 // The underlying bug is in GregorianCalendar. If the following lines 890 // succeed, the bug is fixed. If the bug isn't fixed, they will throw 891 // an exception. 892 GregorianCalendar cal = new GregorianCalendar(); 893 cal.clear(); 894 cal.setLenient(false); 895 cal.set(2000, Calendar.FEBRUARY, 29); // This should work! 896 d = cal.getTime(); 897 logln("Attempt to set Calendar to Feb 29 2000: " + disp.format(d)); 898 } 899 900 @Test 901 public void Test714() { 902 //TimeZone Offset 903 TimeZone defaultTZ = TimeZone.getDefault(); 904 TimeZone PST = TimeZone.getTimeZone("PST"); 905 int defaultOffset = defaultTZ.getRawOffset(); 906 int PSTOffset = PST.getRawOffset(); 907 Date d = new Date(978103543000l - (defaultOffset - PSTOffset)); 908 d = new Date(d.getTime() - (defaultTZ.inDaylightTime(d) ? 3600000 : 0)); 909 DateFormat fmt = DateFormat.getDateTimeInstance(-1, DateFormat.MEDIUM, Locale.US); 910 String tests = "7:25:43 AM"; 911 String s = fmt.format(d); 912 if (!s.equals(tests)) { 913 errln("Fail: " + s + " != " + tests); 914 } else { 915 logln("OK: " + s + " == " + tests); 916 } 917 } 918 919 @Test 920 public void Test_GEec() { 921 class PatternAndResult { 922 private String pattern; 923 private String result; 924 PatternAndResult(String pat, String res) { 925 pattern = pat; 926 result = res; 927 } 928 public String getPattern() { return pattern; } 929 public String getResult() { return result; } 930 } 931 final PatternAndResult[] tests = { 932 new PatternAndResult( "dd MMM yyyy GGG", "02 Jul 2008 AD" ), 933 new PatternAndResult( "dd MMM yyyy GGGGG", "02 Jul 2008 A" ), 934 new PatternAndResult( "e dd MMM yyyy", "4 02 Jul 2008" ), 935 new PatternAndResult( "ee dd MMM yyyy", "04 02 Jul 2008" ), 936 new PatternAndResult( "c dd MMM yyyy", "4 02 Jul 2008" ), 937 new PatternAndResult( "cc dd MMM yyyy", "4 02 Jul 2008" ), 938 new PatternAndResult( "eee dd MMM yyyy", "Wed 02 Jul 2008" ), 939 new PatternAndResult( "EEE dd MMM yyyy", "Wed 02 Jul 2008" ), 940 new PatternAndResult( "EE dd MMM yyyy", "Wed 02 Jul 2008" ), 941 new PatternAndResult( "eeee dd MMM yyyy", "Wednesday 02 Jul 2008" ), 942 new PatternAndResult( "eeeee dd MMM yyyy", "W 02 Jul 2008" ), 943 new PatternAndResult( "e ww YYYY", "4 27 2008" ), 944 new PatternAndResult( "c ww YYYY", "4 27 2008" ), 945 }; 946 ULocale loc = ULocale.ENGLISH; 947 TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); 948 Calendar cal = new GregorianCalendar(tz, loc); 949 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MMM-dd", loc); 950 for ( int i = 0; i < tests.length; i++ ) { 951 PatternAndResult item = tests[i]; 952 dateFormat.applyPattern( item.getPattern() ); 953 cal.set(2008, 6, 2, 5, 0); // 2008 July 02 5 AM PDT 954 StringBuffer buf = new StringBuffer(32); 955 FieldPosition fp = new FieldPosition(DateFormat.YEAR_FIELD); 956 dateFormat.format(cal, buf, fp); 957 if ( buf.toString().compareTo(item.getResult()) != 0 ) { 958 errln("for pattern " + item.getPattern() + ", expected " + item.getResult() + ", got " + buf ); 959 } 960 ParsePosition pos = new ParsePosition(0); 961 dateFormat.parse( item.getResult(), cal, pos); 962 int year = cal.get(Calendar.YEAR); 963 int month = cal.get(Calendar.MONTH); 964 int day = cal.get(Calendar.DATE); 965 if ( year != 2008 || month != 6 || day != 2 ) { 966 errln("use pattern " + item.getPattern() + " to parse " + item.getResult() + 967 ", expected y2008 m6 d2, got " + year + " " + month + " " + day ); 968 } 969 } 970 } 971 972 static final char kArabicZero = 0x0660; 973 static final char kHindiZero = 0x0966; 974 static final char kLatinZero = 0x0030; 975 976 @Test 977 public void TestHindiArabicDigits() 978 { 979 String s; 980 char first; 981 String what; 982 983 { 984 DateFormat df = DateFormat.getInstance(new GregorianCalendar(), new ULocale("hi_IN@numbers=deva")); 985 what = "Gregorian Calendar, hindi"; 986 s = df.format(new Date(0)); /* 31/12/1969 */ 987 logln(what + "=" + s); 988 first = s.charAt(0); 989 if(first<kHindiZero || first>(kHindiZero+9)) { 990 errln(what + "- wrong digit, got " + s + " (integer digit value " + new Integer((int)first).toString()); 991 } 992 } 993 994 { 995 DateFormat df = DateFormat.getInstance(new IslamicCalendar(), new Locale("ar","IQ")); 996 s = df.format(new Date(0)); /* 21/10/1989 */ 997 what = "Islamic Calendar, Arabic"; 998 logln(what + ": " + s); 999 first = s.charAt(0); 1000 if(first<kArabicZero || first>(kArabicZero+9)) { 1001 errln(what + " wrong digit, got " + s + " (integer digit value " + new Integer((int)first).toString()); 1002 } 1003 } 1004 1005 { 1006 DateFormat df = DateFormat.getInstance(new GregorianCalendar(), new Locale("ar","IQ")); 1007 s = df.format(new Date(0)); /* 31/12/1969 */ 1008 what = "Gregorian, ar_IQ, df.getInstance"; 1009 logln(what + ": " + s); 1010 first = s.charAt(0); 1011 if(first<kArabicZero || first>(kArabicZero+9)) { 1012 errln(what + " wrong digit but got " + s + " (integer digit value " + new Integer((int)first).toString()); 1013 } 1014 } 1015 { 1016 DateFormat df = DateFormat.getInstance(new GregorianCalendar(), new Locale("mt","MT")); 1017 s = df.format(new Date(0)); /* 31/12/1969 */ 1018 what = "Gregorian, mt_MT, df.getInstance"; 1019 logln(what + ": " + s); 1020 first = s.charAt(0); 1021 if(first<kLatinZero || first>(kLatinZero+9)) { 1022 errln(what + " wrong digit but got " + s + " (integer digit value " + new Integer((int)first).toString()); 1023 } 1024 } 1025 1026 { 1027 DateFormat df = DateFormat.getInstance(new IslamicCalendar(), new Locale("ar","IQ")); 1028 s = df.format(new Date(0)); /* 31/12/1969 */ 1029 what = "Islamic calendar, ar_IQ, df.getInstance"; 1030 logln(what+ ": " + s); 1031 first = s.charAt(0); 1032 if(first<kArabicZero || first>(kArabicZero+9)) { 1033 errln(what + " wrong digit but got " + s + " (integer digit value " + new Integer((int)first).toString()); 1034 } 1035 } 1036 1037 { 1038 DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, new Locale("ar","IQ")); 1039 s = df.format(new Date(0)); /* 31/12/1969 */ 1040 what = "ar_IQ, getDateTimeInstance"; 1041 logln(what+ ": " + s); 1042 first = s.charAt(0); 1043 if(first<kArabicZero || first>(kArabicZero+9)) { 1044 errln(what + " wrong digit but got " + s + " (integer digit value " + new Integer((int)first).toString()); 1045 } 1046 } 1047 1048 { 1049 DateFormat df = DateFormat.getInstance(new JapaneseCalendar(), new Locale("ar","IQ")); 1050 s = df.format(new Date(0)); /* 31/12/1969 */ 1051 what = "ar_IQ, Japanese Calendar, getInstance"; 1052 logln(what+ ": " + s); 1053 first = s.charAt(0); 1054 if(first<kArabicZero || first>(kArabicZero+9)) { 1055 errln(what + " wrong digit but got " + s + " (integer digit value " + new Integer((int)first).toString()); 1056 } 1057 } 1058 } 1059 1060 // Ticket#5683 1061 // Some ICU4J 3.6 data files contain garbage data which prevent the code to resolve another 1062 // bundle as an alias. zh_TW should be equivalent to zh_Hant_TW 1063 @Test 1064 public void TestT5683() { 1065 Locale[] aliasLocales = { 1066 new Locale("zh", "CN"), 1067 new Locale("zh", "TW"), 1068 new Locale("zh", "HK"), 1069 new Locale("zh", "SG"), 1070 new Locale("zh", "MO") 1071 }; 1072 1073 ULocale[] canonicalLocales = { 1074 new ULocale("zh_Hans_CN"), 1075 new ULocale("zh_Hant_TW"), 1076 new ULocale("zh_Hant_HK"), 1077 new ULocale("zh_Hans_SG"), 1078 new ULocale("zh_Hant_MO") 1079 }; 1080 1081 Date d = new Date(0); 1082 1083 for (int i = 0; i < aliasLocales.length; i++) { 1084 DateFormat dfAlias = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, aliasLocales[i]); 1085 DateFormat dfCanonical = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, canonicalLocales[i]); 1086 1087 String sAlias = dfAlias.format(d); 1088 String sCanonical = dfCanonical.format(d); 1089 1090 if (!sAlias.equals(sCanonical)) { 1091 errln("Fail: The format result for locale " + aliasLocales[i] + " is different from the result for locale " + canonicalLocales[i] 1092 + ": " + sAlias + "[" + aliasLocales[i] + "] / " + sCanonical + "[" + canonicalLocales[i] + "]"); 1093 } 1094 } 1095 } 1096 1097 // Note: The purpose of this test case is a little bit questionable. This test 1098 // case expects Islamic month name is different from Gregorian month name. 1099 // However, some locales (in this code, zh_CN) may intentionally use the same 1100 // month name for both Gregorian and Islamic calendars. See #9645. 1101 @Test 1102 public void Test5006GetShortMonths() throws Exception { 1103 // Currently supported NLV locales 1104 Locale ENGLISH = new Locale("en", "US"); // We don't support 'en' alone 1105 Locale ARABIC = new Locale("ar", ""); 1106 Locale CZECH = new Locale("cs", ""); 1107 Locale GERMAN = new Locale("de", ""); 1108 Locale GREEK = new Locale("el", ""); 1109 Locale SPANISH = new Locale("es", ""); 1110 Locale FRENCH = new Locale("fr", ""); 1111 Locale HUNGARIAN = new Locale("hu", ""); 1112 Locale ITALIAN = new Locale("it", ""); 1113 Locale HEBREW = new Locale("iw", ""); 1114 Locale JAPANESE = new Locale("ja", ""); 1115 Locale KOREAN = new Locale("ko", ""); 1116 Locale POLISH = new Locale("pl", ""); 1117 Locale PORTUGUESE = new Locale("pt", "BR"); 1118 Locale RUSSIAN = new Locale("ru", ""); 1119 Locale TURKISH = new Locale("tr", ""); 1120 Locale CHINESE_SIMPLIFIED = new Locale("zh", "CN"); 1121 Locale CHINESE_TRADITIONAL = new Locale("zh", "TW"); 1122 1123 Locale[] locales = new Locale[] { ENGLISH, ARABIC, CZECH, GERMAN, GREEK, SPANISH, FRENCH, 1124 HUNGARIAN, ITALIAN, HEBREW, JAPANESE, KOREAN, POLISH, PORTUGUESE, RUSSIAN, TURKISH, 1125 CHINESE_SIMPLIFIED, CHINESE_TRADITIONAL }; 1126 1127 String[] islamicCivilTwelfthMonthLocalized = new String[locales.length]; 1128 String[] islamicTwelfthMonthLocalized = new String[locales.length]; 1129 String[] gregorianTwelfthMonthLocalized = new String[locales.length]; 1130 1131 for (int i = 0; i < locales.length; i++) { 1132 1133 Locale locale = locales[i]; 1134 1135 // Islamic 1136 android.icu.util.Calendar islamicCivilCalendar = new android.icu.util.IslamicCalendar(locale); 1137 android.icu.text.SimpleDateFormat islamicCivilDateFormat = (android.icu.text.SimpleDateFormat) islamicCivilCalendar 1138 .getDateTimeFormat(android.icu.text.DateFormat.FULL, -1, locale); 1139 android.icu.text.DateFormatSymbols islamicCivilDateFormatSymbols = islamicCivilDateFormat 1140 .getDateFormatSymbols(); 1141 1142 String[] shortMonthsCivil = islamicCivilDateFormatSymbols.getShortMonths(); 1143 String twelfthMonthLocalizedCivil = shortMonthsCivil[11]; 1144 1145 islamicCivilTwelfthMonthLocalized[i] = twelfthMonthLocalizedCivil; 1146 1147 android.icu.util.IslamicCalendar islamicCalendar = new android.icu.util.IslamicCalendar(locale); 1148 islamicCalendar.setCivil(false); 1149 android.icu.text.SimpleDateFormat islamicDateFormat = (android.icu.text.SimpleDateFormat) islamicCalendar 1150 .getDateTimeFormat(android.icu.text.DateFormat.FULL, -1, locale); 1151 android.icu.text.DateFormatSymbols islamicDateFormatSymbols = islamicDateFormat 1152 .getDateFormatSymbols(); 1153 1154 String[] shortMonths = islamicDateFormatSymbols.getShortMonths(); 1155 String twelfthMonthLocalized = shortMonths[11]; 1156 1157 islamicTwelfthMonthLocalized[i] = twelfthMonthLocalized; 1158 1159 // Gregorian 1160 android.icu.util.Calendar gregorianCalendar = new android.icu.util.GregorianCalendar( 1161 locale); 1162 android.icu.text.SimpleDateFormat gregorianDateFormat = (android.icu.text.SimpleDateFormat) gregorianCalendar 1163 .getDateTimeFormat(android.icu.text.DateFormat.FULL, -1, locale); 1164 1165 android.icu.text.DateFormatSymbols gregorianDateFormatSymbols = gregorianDateFormat 1166 .getDateFormatSymbols(); 1167 shortMonths = gregorianDateFormatSymbols.getShortMonths(); 1168 twelfthMonthLocalized = shortMonths[11]; 1169 1170 gregorianTwelfthMonthLocalized[i] = twelfthMonthLocalized; 1171 1172 } 1173 1174 // Compare 1175 for (int i = 0; i < locales.length; i++) { 1176 1177 String gregorianTwelfthMonth = gregorianTwelfthMonthLocalized[i]; 1178 String islamicCivilTwelfthMonth = islamicCivilTwelfthMonthLocalized[i]; 1179 String islamicTwelfthMonth = islamicTwelfthMonthLocalized[i]; 1180 1181 logln(locales[i] + ": g:" + gregorianTwelfthMonth + ", ic:" + islamicCivilTwelfthMonth + ", i:"+islamicTwelfthMonth); 1182 if (gregorianTwelfthMonth.equalsIgnoreCase(islamicTwelfthMonth)) { 1183 // Simplified Chinese uses numeric month for both Gregorian/Islamic calendars 1184 if (locales[i] != CHINESE_SIMPLIFIED) { 1185 errln(locales[i] + ": gregorian and islamic are same: " + gregorianTwelfthMonth 1186 + ", " + islamicTwelfthMonth); 1187 } 1188 } 1189 1190 if (gregorianTwelfthMonth.equalsIgnoreCase(islamicCivilTwelfthMonth)) { 1191 // Simplified Chinese uses numeric month for both Gregorian/Islamic calendars 1192 if (locales[i] != CHINESE_SIMPLIFIED) { 1193 errln(locales[i] + ": gregorian and islamic-civil are same: " + gregorianTwelfthMonth 1194 + ", " + islamicCivilTwelfthMonth); 1195 } 1196 } 1197 if (!islamicTwelfthMonth.equalsIgnoreCase(islamicCivilTwelfthMonth)) { 1198 errln(locales[i] + ": islamic-civil and islamic are NOT same: " + islamicCivilTwelfthMonth 1199 + ", " + islamicTwelfthMonth); 1200 } 1201 } 1202 } 1203 1204 @Test 1205 public void TestParsing() { 1206 String pattern = "EEE-WW-MMMM-yyyy"; 1207 String text = "mon-02-march-2011"; 1208 int expectedDay = 7; 1209 1210 SimpleDateFormat format = new SimpleDateFormat(pattern); 1211 Calendar cal = GregorianCalendar.getInstance(Locale.US); 1212 ParsePosition pos = new ParsePosition(0); 1213 1214 try { 1215 format.parse(text, cal, pos); 1216 } catch (Exception e) { 1217 errln("Fail parsing: " + e); 1218 } 1219 1220 if (cal.get(Calendar.DAY_OF_MONTH) != expectedDay) { 1221 errln("Parsing failed: day of month should be '7' with pattern: \"" + pattern + "\" for text: \"" + text + "\""); 1222 } 1223 } 1224 1225 // Date formatting with Dangi calendar in en locale (#9987) 1226 @Test 1227 public void TestDangiFormat() { 1228 DateFormat fmt = DateFormat.getDateInstance(DateFormat.MEDIUM, new ULocale("en@calendar=dangi")); 1229 String calType = fmt.getCalendar().getType(); 1230 assertEquals("Incorrect calendar type used by the date format instance", "dangi", calType); 1231 1232 GregorianCalendar gcal = new GregorianCalendar(); 1233 gcal.set(2013, Calendar.MARCH, 1, 0, 0, 0); 1234 Date d = gcal.getTime(); 1235 1236 String dangiDateStr = fmt.format(d); 1237 assertEquals("Bad date format", "Mo1 20, 2013", dangiDateStr); 1238 } 1239 1240 @Test 1241 public void TestT10110() { 1242 try { 1243 SimpleDateFormat formatter = new SimpleDateFormat("Gy年M月d日E", new Locale("zh_Hans")); 1244 /* Object parsed = */ formatter.parseObject("610000"); 1245 } 1246 catch(ParseException pe) { 1247 return; 1248 } 1249 catch(Throwable t) { 1250 errln("ParseException not thrown for bad pattern! exception was: " + t.getLocalizedMessage()); 1251 return; 1252 } 1253 errln("No exception thrown at all for bad pattern!"); 1254 } 1255 1256 @Test 1257 public void TestT10239() { 1258 1259 class TestDateFormatItem { 1260 public String parseString; 1261 public String pattern; 1262 public String expectedResult; // null indicates expected error 1263 // Simple constructor 1264 public TestDateFormatItem(String parString, String patt, String expResult) { 1265 pattern = patt; 1266 parseString = parString; 1267 expectedResult = expResult; 1268 } 1269 }; 1270 1271 final TestDateFormatItem[] items = { 1272 // parse String pattern expected result 1273 new TestDateFormatItem("1 Oct 13 2013", "e MMM dd yyyy", "1 Oct 13 2013"), 1274 new TestDateFormatItem("02 Oct 14 2013", "ee MMM dd yyyy", "02 Oct 14 2013"), 1275 new TestDateFormatItem("Tue Oct 15 2013", "eee MMM dd yyyy", "Tue Oct 15 2013"), 1276 new TestDateFormatItem("Wednesday Oct 16 2013", "eeee MMM dd yyyy", "Wednesday Oct 16 2013"), 1277 new TestDateFormatItem("Th Oct 17 2013", "eeeeee MMM dd yyyy", "Th Oct 17 2013"), 1278 new TestDateFormatItem("Fr Oct 18 2013", "EEEEEE MMM dd yyyy", "Fr Oct 18 2013"), 1279 new TestDateFormatItem("S Oct 19 2013", "eeeee MMM dd yyyy", "S Oct 19 2013"), 1280 new TestDateFormatItem("S Oct 20 2013", "EEEEE MMM dd yyyy", "S Oct 20 2013"), 1281 }; 1282 1283 StringBuffer result = new StringBuffer(); 1284 Date d = new Date(); 1285 Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.US); 1286 SimpleDateFormat sdfmt = new SimpleDateFormat(); 1287 ParsePosition p = new ParsePosition(0); 1288 for (TestDateFormatItem item: items) { 1289 cal.clear(); 1290 sdfmt.setCalendar(cal); 1291 sdfmt.applyPattern(item.pattern); 1292 result.setLength(0); 1293 p.setIndex(0); 1294 p.setErrorIndex(-1); 1295 d = sdfmt.parse(item.parseString, p); 1296 if(item.expectedResult == null) { 1297 if(p.getErrorIndex() != -1) 1298 continue; 1299 else 1300 errln("error: unexpected parse success..."+item.parseString + " should have failed"); 1301 } 1302 if(p.getErrorIndex() != -1) { 1303 errln("error: parse error for string " +item.parseString + " against pattern " + item.pattern + " -- idx["+p.getIndex()+"] errIdx["+p.getErrorIndex()+"]"); 1304 continue; 1305 } 1306 cal.setTime(d); 1307 result = sdfmt.format(cal, result, new FieldPosition(0)); 1308 if(!result.toString().equalsIgnoreCase(item.expectedResult)) { 1309 errln("error: unexpected format result. expected - " + item.expectedResult + " but result was - " + result); 1310 } else { 1311 logln("formatted results match! - " + result.toString()); 1312 } 1313 } 1314 } 1315 1316 1317 @Test 1318 public void TestT10334() { 1319 String pattern = new String("'--: 'EEE-WW-MMMM-yyyy"); 1320 String text = new String("--mon-02-march-2011"); 1321 SimpleDateFormat format = new SimpleDateFormat(pattern); 1322 1323 format.setBooleanAttribute(DateFormat.BooleanAttribute.PARSE_PARTIAL_LITERAL_MATCH, false); 1324 try { 1325 format.parse(text); 1326 errln("parse partial match did NOT fail in strict mode!"); 1327 } catch (ParseException pe) { 1328 // expected 1329 } 1330 1331 format.setBooleanAttribute(DateFormat.BooleanAttribute.PARSE_PARTIAL_LITERAL_MATCH, true); 1332 try { 1333 format.parse(text); 1334 } catch (ParseException pe) { 1335 errln("parse partial match failure in lenient mode: " + pe.getLocalizedMessage()); 1336 } 1337 1338 pattern = new String("YYYY MM dd"); 1339 text = new String("2013 12 10"); 1340 format.applyPattern(pattern); 1341 Date referenceDate = null; 1342 try { 1343 referenceDate = format.parse(text); 1344 } catch (ParseException pe) { 1345 errln("unable to instantiate reference date: " + pe.getLocalizedMessage()); 1346 } 1347 1348 FieldPosition fp = new FieldPosition(0); 1349 pattern = new String("YYYY LL dd ee cc qq QQ"); 1350 format.applyPattern(pattern); 1351 StringBuffer formattedString = new StringBuffer(); 1352 formattedString = format.format(referenceDate, formattedString, fp); 1353 logln("ref date: " + formattedString); 1354 1355 1356 pattern = new String("YYYY LLL dd eee ccc qqq QQQ"); 1357 text = new String("2013 12 10 03 3 04 04"); 1358 format.applyPattern(pattern); 1359 logln(format.format(referenceDate)); 1360 1361 format.setBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC, true); 1362 ParsePosition pp = new ParsePosition(0); 1363 format.parse(text, pp); 1364 int errorIdx = pp.getErrorIndex(); 1365 if (errorIdx != -1) { 1366 1367 errln("numeric parse error at["+errorIdx+"] on char["+pattern.substring(errorIdx, errorIdx+1)+"] in pattern["+pattern+"]"); 1368 } 1369 1370 format.setBooleanAttribute(DateFormat.BooleanAttribute.PARSE_ALLOW_NUMERIC, false); 1371 try { 1372 format.parse(text); 1373 errln("numeric parse did NOT fail in strict mode!"); 1374 } catch (ParseException pe) { 1375 // expected 1376 } 1377 1378 /* 1379 * test to verify new code (and improve code coverage) for normal quarter processing 1380 */ 1381 text = new String("2013 Dec 10 Thu Thu Q4 Q4"); 1382 try { 1383 format.parse(text); 1384 } catch (ParseException pe) { 1385 errln("normal quarter processing failed"); 1386 } 1387 1388 } 1389 1390 @Test 1391 public void TestT10619() { 1392 1393 class TestDateFormatLeniencyItem { 1394 public boolean leniency; 1395 public String parseString; 1396 public String pattern; 1397 public String expectedResult; // null indicates expected error 1398 // Simple constructor 1399 public TestDateFormatLeniencyItem(boolean len, String parString, String patt, String expResult) { 1400 leniency = len; 1401 pattern = patt; 1402 parseString = parString; 1403 expectedResult = expResult; 1404 } 1405 }; 1406 1407 final TestDateFormatLeniencyItem[] items = { 1408 // leniency parse String pattern expected result 1409 new TestDateFormatLeniencyItem(true, "2008-Jan 02", "yyyy-LLL. dd", "2008-Jan. 02"), 1410 new TestDateFormatLeniencyItem(false, "2008-Jan 03", "yyyy-LLL. dd", null), 1411 new TestDateFormatLeniencyItem(true, "2008-Jan--04", "yyyy-MMM' -- 'dd", "2008-Jan -- 04"), 1412 new TestDateFormatLeniencyItem(false, "2008-Jan--05", "yyyy-MMM' -- 'dd", null), 1413 new TestDateFormatLeniencyItem(true, "2008-12-31", "yyyy-mm-dd", "2008-12-31"), 1414 new TestDateFormatLeniencyItem(false, "6 Jan 05 2008", "eee MMM dd yyyy", null), 1415 new TestDateFormatLeniencyItem(true, "6 Jan 05 2008", "eee MMM dd yyyy", "Sat Jan 05 2008"), 1416 }; 1417 1418 StringBuffer result = new StringBuffer(); 1419 Date d = new Date(); 1420 Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.US); 1421 SimpleDateFormat sdfmt = new SimpleDateFormat(); 1422 ParsePosition p = new ParsePosition(0); 1423 for (TestDateFormatLeniencyItem item: items) { 1424 cal.clear(); 1425 sdfmt.setCalendar(cal); 1426 sdfmt.applyPattern(item.pattern); 1427 sdfmt.setLenient(item.leniency); 1428 result.setLength(0); 1429 p.setIndex(0); 1430 p.setErrorIndex(-1); 1431 d = sdfmt.parse(item.parseString, p); 1432 if(item.expectedResult == null) { 1433 if(p.getErrorIndex() != -1) 1434 continue; 1435 else 1436 errln("error: unexpected parse success..."+item.parseString + " w/ lenient="+item.leniency+" should have failed"); 1437 } 1438 if(p.getErrorIndex() != -1) { 1439 errln("error: parse error for string " +item.parseString + " -- idx["+p.getIndex()+"] errIdx["+p.getErrorIndex()+"]"); 1440 continue; 1441 } 1442 cal.setTime(d); 1443 result = sdfmt.format(cal, result, new FieldPosition(0)); 1444 if(!result.toString().equalsIgnoreCase(item.expectedResult)) { 1445 errln("error: unexpected format result. expected - " + item.expectedResult + " but result was - " + result); 1446 } else { 1447 logln("formatted results match! - " + result.toString()); 1448 } 1449 } 1450 } 1451 1452 @Test 1453 public void TestT10906() 1454 { 1455 String pattern = new String("MM-dd-yyyy"); 1456 String text = new String("06-10-2014"); 1457 SimpleDateFormat format = new SimpleDateFormat(pattern); 1458 ParsePosition pp = new ParsePosition(-1); 1459 try { 1460 format.parse(text, pp); 1461 int errorIdx = pp.getErrorIndex(); 1462 if (errorIdx == -1) { 1463 errln("failed to report invalid (negative) starting parse position"); 1464 } 1465 } catch(StringIndexOutOfBoundsException e) { 1466 errln("failed to fix invalid (negative) starting parse position"); 1467 } 1468 1469 } 1470 1471 // Test case for numeric field format threading problem 1472 @Test 1473 public void TestT11363() { 1474 1475 class TestThread extends Thread { 1476 SimpleDateFormat fmt; 1477 Date d; 1478 1479 TestThread(SimpleDateFormat fmt, Date d) { 1480 this.fmt = fmt; 1481 this.d = d; 1482 } 1483 1484 public void run() { 1485 String s0 = fmt.format(d); 1486 for (int i = 0; i < 1000; i++) { 1487 String s = fmt.format(d); 1488 if (!s0.equals(s)) { 1489 errln("Result: " + s + ", Expected: " + s0); 1490 } 1491 } 1492 } 1493 } 1494 1495 SimpleDateFormat fmt0 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 1496 1497 Thread[] threads = new Thread[10]; 1498 1499 GregorianCalendar cal = new GregorianCalendar(2014, Calendar.NOVEMBER, 5, 12, 34, 56); 1500 cal.set(Calendar.MILLISECOND, 777); 1501 1502 // calls format() once on the base object to trigger 1503 // lazy initialization stuffs. 1504 fmt0.format(cal.getTime()); 1505 1506 for (int i = 0; i < threads.length; i++) { 1507 // Add 1 to all fields to use different numbers in each thread 1508 cal.add(Calendar.YEAR, 1); 1509 cal.add(Calendar.MONTH, 1); 1510 cal.add(Calendar.DAY_OF_MONTH, 1); 1511 cal.add(Calendar.HOUR_OF_DAY, 1); 1512 cal.add(Calendar.MINUTE, 1); 1513 cal.add(Calendar.SECOND, 1); 1514 cal.add(Calendar.MILLISECOND, 1); 1515 Date d = cal.getTime(); 1516 SimpleDateFormat fmt = (SimpleDateFormat)fmt0.clone(); 1517 threads[i] = new TestThread(fmt, d); 1518 } 1519 1520 for (Thread t : threads) { 1521 t.start(); 1522 } 1523 1524 for (Thread t : threads) { 1525 try { 1526 t.join(); 1527 } catch (InterruptedException e) { 1528 errln(e.toString()); 1529 } 1530 } 1531 } 1532} 1533