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