1 /* 2 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @bug 4823811 8008577 27 * @summary Confirm that text which includes numbers with a trailing minus sign is parsed correctly. 28 * @run main/othervm -Duser.timezone=GMT+09:00 -Djava.locale.providers=JRE,SPI Bug4823811 29 */ 30 31 import java.text.*; 32 import java.util.*; 33 34 public class Bug4823811 { 35 36 private static Locale localeEG = new Locale("ar", "EG"); 37 private static Locale localeUS = Locale.US; 38 39 private static String JuneInArabic = "\u064a\u0648\u0646\u064a\u0648"; 40 private static String JulyInArabic = "\u064a\u0648\u0644\u064a\u0648"; 41 private static String JuneInEnglish = "June"; 42 private static String JulyInEnglish = "July"; 43 44 private static String BORDER = 45 "============================================================"; 46 47 /* 48 * I don't use static import here intentionally so that this test program 49 * can be run on JDK 1.4.2. 50 */ 51 private static int ERA = Calendar.ERA; 52 private static int BC = GregorianCalendar.BC; 53 // private static int JAN = Calendar.JANUARY; 54 // private static int FEB = Calendar.FEBRUARY; 55 // private static int MAR = Calendar.MARCH; 56 private static int APR = Calendar.APRIL; 57 private static int MAY = Calendar.MAY; 58 private static int JUN = Calendar.JUNE; 59 private static int JUL = Calendar.JULY; 60 // private static int AUG = Calendar.AUGUST; 61 // private static int SEP = Calendar.SEPTEMBER; 62 // private static int OCT = Calendar.OCTOBER; 63 // private static int NOV = Calendar.NOVEMBER; 64 // private static int DEC = Calendar.DECEMBER; 65 66 private static String[] patterns = { 67 "yyyy MMMM d H m s", 68 "yyyy MM dd hh mm ss", 69 70 /* 71 * Because 1-based HOUR_OF_DAY, 1-based HOUR, MONTH, and YEAR fields 72 * are parsed using different code from the code for other numeric 73 * fields, I prepared YEAR-preceding patterns and SECOND-preceding 74 * patterns. 75 */ 76 "yyyy M d h m s", 77 " yyyy M d h m s", 78 "yyyy M d h m s ", 79 80 "s m h d M yyyy", 81 " s m h d M yyyy", 82 "s m h d M yyyy ", 83 }; 84 85 private static char originalMinusSign1 = ':'; 86 private static char originalMinusSign2 = '\uff0d'; // fullwidth minus 87 private static String[] delimiters = {"-", "/", ":", "/", "\uff0d", "/"}; 88 private static String[][] specialDelimiters = { 89 // for Arabic formatter and modified English formatter 90 {"--", "-/", "::", ":/", "\uff0d\uff0d", "\uff0d/"}, 91 92 // for English formatter and modified Arabic formatter 93 {"--", "/-", "::", "/:", "\uff0d\uff0d", "/\uff0d"}, 94 }; 95 96 /* 97 * Format: 98 * +-------------------------------------------------------------------+ 99 * | Input | Output | 100 * +---------------------+---------------------------------------------| 101 * | datesEG & datesUS | formattedDatesEG & formattedDatesUS | 102 * +-------------------------------------------------------------------+ 103 * 104 * Parse: 105 * +-------------------------------------------------------------------+ 106 * | Input | Output | 107 * |---------------------+---------------------------------------------| 108 * | datesToParse | datesEG & datesUS | 109 * +-------------------------------------------------------------------+ 110 */ 111 private static String[][] datesToParse = { 112 // "JUNE" and "JULY" are replaced with a localized month name later. 113 {"2008 JULY 20 3 12 83", 114 "2008 JULY 20 3 12 83", 115 "2008 JULY 20 3 12 83"}, 116 117 {"2008 07 20 03 12 83", 118 "2008 07 20 03 12 83", 119 "2008 07 20 03 12 83"}, 120 121 {"2008 7 20 3 12 83", 122 "2008 7 20 3 12 83", 123 "2008 7 20 3 12 83"}, 124 125 {" 2008 7 20 3 12 83", 126 " 2008 7 20 3 12 83", 127 " 2008 7 20 3 12 83", 128 "2008 7 20 3 12 83"}, 129 130 {"2008 7 20 3 12 83 ", 131 "2008 7 20 3 12 83 ", 132 "2008 7 20 3 12 83"}, 133 134 {"83 12 3 20 7 2008", 135 "83 12 3 20 7 2008", 136 "83 12 3 20 7 2008"}, 137 138 {" 83 12 3 20 7 2008", 139 " 83 12 3 20 7 2008", 140 " 83 12 3 20 7 2008", 141 "83 12 3 20 7 2008"}, 142 143 {"83 12 3 20 7 2008 ", 144 "83 12 3 20 7 2008 ", 145 "83 12 3 20 7 2008"}, 146 }; 147 148 // For formatting 149 private static String[][] formattedDatesEG = { 150 {"2008 JULY 20 3 13 23", 151 "2009 JULY 20 3 13 23", 152 null}, 153 154 {"2008 07 20 03 13 23", 155 "2009 07 20 03 13 23", 156 "2007 05 20 03 13 23"}, 157 158 {"2008 7 20 3 13 23", 159 "2009 6 10 3 13 23", 160 "2007 4 10 3 13 23"}, 161 162 {" 2008 7 20 3 13 23", 163 null, 164 " 2009 7 20 3 13 23", 165 null}, 166 167 {"2008 7 20 3 13 23 ", 168 "2008 7 20 3 10 37 ", 169 null}, 170 171 {"23 13 3 20 7 2008", 172 "37 10 9 19 7 2008", 173 "23 49 8 19 7 2008"}, 174 175 {" 23 13 3 20 7 2008", 176 null, 177 " 37 10 3 20 7 2008", 178 null}, 179 180 {"23 13 3 20 7 2008 ", 181 "23 13 3 20 7 2009 ", 182 null}, 183 }; 184 185 private static String[][] formattedDatesUS = { 186 {"2008 JULY 20 3 13 23", 187 null, 188 "2008 JUNE 10 3 13 23"}, 189 190 {"2008 07 20 03 13 23", 191 "2007 05 20 03 13 23", 192 "2008 06 10 03 13 23"}, 193 194 {"2008 7 20 3 13 23", 195 "2007 5 19 9 13 23", 196 "2008 6 9 9 13 23"}, 197 198 {" 2008 7 20 3 13 23", 199 " 2009 7 20 3 13 23", 200 " 2007 5 20 3 13 23", 201 null}, 202 203 {"2008 7 20 3 13 23 ", 204 "2008 7 20 3 13 23 ", 205 null}, 206 207 {"23 13 3 20 7 2008", 208 "23 49 2 10 6 2008", 209 "23 13 9 9 6 2008"}, 210 211 {" 23 13 3 20 7 2008", 212 " 37 10 3 20 7 2008", 213 " 23 49 2 20 7 2008", 214 null}, 215 216 {"23 13 3 20 7 2008 ", 217 "23 13 3 20 7 2008 ", 218 null}, 219 }; 220 221 private static GregorianCalendar[][] datesEG = { 222 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 223 new GregorianCalendar(-2008, JUL, 20, 3, 12, 83), 224 null}, 225 226 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 227 new GregorianCalendar(-2008, JUL, 20, 3, 12, 83), 228 new GregorianCalendar( 2007, MAY, 20, 3, 12, 83)}, 229 230 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 231 new GregorianCalendar(-2008, JUL, -20, 3, 12, 83), 232 new GregorianCalendar( 2007, APR, 10, 3, 12, 83)}, 233 234 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 235 null, 236 new GregorianCalendar(-2008, JUL, 20, 3, 12, 83), 237 null}, 238 239 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 240 new GregorianCalendar( 2008, JUL, 20, 3, 12, -83), 241 null}, 242 243 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 244 new GregorianCalendar( 2008, JUL, 20, -3, 12, -83), 245 new GregorianCalendar( 2008, JUL, 20, -3, -12, 83)}, 246 247 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 248 null, 249 new GregorianCalendar( 2008, JUL, 20, 3, 12, -83), 250 null}, 251 252 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 253 new GregorianCalendar(-2008, JUL, 20, 3, 12, 83), 254 null}, 255 }; 256 257 private static GregorianCalendar[][] datesUS = { 258 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 259 null, 260 new GregorianCalendar( 2008, JUN, 10, 3, 12, 83)}, 261 262 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 263 new GregorianCalendar( 2007, MAY, 20, 3, 12, 83), 264 new GregorianCalendar( 2008, JUN, 10, 3, 12, 83)}, 265 266 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 267 new GregorianCalendar( 2007, MAY, 20, -3, 12, 83), 268 new GregorianCalendar( 2008, JUL, -20, -3, 12, 83)}, 269 270 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 271 new GregorianCalendar(-2008, JUL, 20, 3, 12, 83), 272 new GregorianCalendar( 2007, MAY, 20, 3, 12, 83), 273 null}, 274 275 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 276 new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 277 null}, 278 279 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 280 new GregorianCalendar( 2008, JUL, -20, 3, -12, 83), 281 new GregorianCalendar( 2008, JUL, -20, -3, 12, 83)}, 282 283 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 284 new GregorianCalendar( 2008, JUL, 20, 3, 12, -83), 285 new GregorianCalendar( 2008, JUL, 20, 3, -12, 83), 286 null}, 287 288 {new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 289 new GregorianCalendar( 2008, JUL, 20, 3, 12, 83), 290 null}, 291 }; 292 293 /* flags */ 294 private static boolean err = false; 295 private static boolean verbose = false; 296 297 298 public static void main(String[] args) { 299 if (args.length == 1 && args[0].equals("-v")) { 300 verbose = true; 301 } 302 303 Locale defaultLocale = Locale.getDefault(); 304 TimeZone defaultTimeZone = TimeZone.getDefault(); 305 306 TimeZone.setDefault(TimeZone.getTimeZone("Asia/Tokyo")); 307 308 try { 309 /* 310 * Test SimpleDateFormat.parse() and format() for original 311 * SimpleDateFormat instances 312 */ 313 testDateFormat1(); 314 315 /* 316 * Test SimpleDateFormat.parse() and format() for modified 317 * SimpleDateFormat instances using an original minus sign, 318 * pattern, and diffenrent month names in DecimalFormat 319 */ 320 testDateFormat2(); 321 322 /* 323 * Test SimpleDateFormat.parse() and format() for modified 324 * SimpleDateFormat instances using a fullwidth minus sign 325 */ 326 testDateFormat3(); 327 328 /* 329 * Just to confirm that regressions aren't introduced in 330 * DecimalFormat. This cannot happen, though. Because I didn't 331 * change DecimalFormat at all. 332 */ 333 testNumberFormat(); 334 } 335 catch (Exception e) { 336 err = true; 337 System.err.println("Unexpected exception: " + e); 338 } 339 finally { 340 Locale.setDefault(defaultLocale); 341 TimeZone.setDefault(defaultTimeZone); 342 343 if (err) { 344 System.err.println(BORDER + " Test failed."); 345 throw new RuntimeException("Date/Number formatting/parsing error."); 346 } else { 347 System.out.println(BORDER + " Test passed."); 348 } 349 } 350 } 351 352 353 // 354 // DateFormat test 355 // 356 private static void testDateFormat1() { 357 for (int i = 0; i < patterns.length; i++) { 358 System.out.println(BORDER); 359 for (int j = 0; j <= 1; j++) { 360 // Generate a pattern 361 String pattern = patterns[i].replaceAll(" ", delimiters[j]); 362 System.out.println("Pattern=\"" + pattern + "\""); 363 364 System.out.println("*** DateFormat.format test in ar_EG"); 365 testDateFormatFormattingInRTL(pattern, i, j, null, localeEG, false); 366 367 System.out.println("*** DateFormat.parse test in ar_EG"); 368 testDateFormatParsingInRTL(pattern, i, j, null, localeEG, false); 369 370 System.out.println("*** DateFormat.format test in en_US"); 371 testDateFormatFormattingInLTR(pattern, i, j, null, localeUS, true); 372 373 System.out.println("*** DateFormat.parse test in en_US"); 374 testDateFormatParsingInLTR(pattern, i, j, null, localeUS, true); 375 } 376 } 377 } 378 379 private static void testDateFormat2() { 380 /* 381 * modified ar_EG Date&Time formatter : 382 * minus sign: ':' 383 * pattern: "#,##0.###" 384 * month names: In Arabic 385 * 386 * modified en_US Date&Time formatter : 387 * minus sign: ':' 388 * pattern: "#,##0.###;#,##0.###-" 389 * month names: In English 390 */ 391 DecimalFormat dfEG = (DecimalFormat)NumberFormat.getInstance(localeEG); 392 DecimalFormat dfUS = (DecimalFormat)NumberFormat.getInstance(localeUS); 393 394 DecimalFormatSymbols dfsEG = dfEG.getDecimalFormatSymbols(); 395 DecimalFormatSymbols dfsUS = dfUS.getDecimalFormatSymbols(); 396 dfsEG.setMinusSign(originalMinusSign1); 397 dfsUS.setMinusSign(originalMinusSign1); 398 dfEG.setDecimalFormatSymbols(dfsUS); 399 dfUS.setDecimalFormatSymbols(dfsEG); 400 401 String patternEG = dfEG.toPattern(); 402 String patternUS = dfUS.toPattern(); 403 404 dfEG.applyPattern(patternUS); 405 dfUS.applyPattern(patternEG); 406 407 for (int i = 0; i < patterns.length; i++) { 408 System.out.println(BORDER); 409 for (int j = 2; j <= 3; j++) { 410 // Generate a pattern 411 String pattern = patterns[i].replaceAll(" ", delimiters[j]); 412 System.out.println("Pattern=\"" + pattern + "\""); 413 414 System.out.println("*** DateFormat.format test in modified en_US"); 415 testDateFormatFormattingInRTL(pattern, i, j, dfUS, localeUS, true); 416 417 System.out.println("*** DateFormat.parse test in modified en_US"); 418 testDateFormatParsingInRTL(pattern, i, j, dfUS, localeUS, true); 419 420 System.out.println("*** DateFormat.format test in modified ar_EG"); 421 testDateFormatFormattingInLTR(pattern, i, j, dfEG, localeEG, false); 422 423 System.out.println("*** DateFormat.parse test in modified ar_EG"); 424 testDateFormatParsingInLTR(pattern, i, j, dfEG, localeEG, false); 425 } 426 } 427 } 428 429 private static void testDateFormat3() { 430 /* 431 * modified ar_EG Date&Time formatter : 432 * minus sign: '\uff0d' // fullwidth minus 433 * pattern: "#,##0.###;#,##0.###-" 434 * month names: In Arabic 435 * 436 * modified en_US Date&Time formatter : 437 * minus sign: '\uff0d' // fullwidth minus 438 * pattern: "#,##0.###" 439 * month names: In English 440 */ 441 DecimalFormat dfEG = (DecimalFormat)NumberFormat.getInstance(localeEG); 442 DecimalFormat dfUS = (DecimalFormat)NumberFormat.getInstance(localeUS); 443 444 DecimalFormatSymbols dfsEG = dfEG.getDecimalFormatSymbols(); 445 DecimalFormatSymbols dfsUS = dfUS.getDecimalFormatSymbols(); 446 dfsEG.setMinusSign(originalMinusSign2); 447 dfsUS.setMinusSign(originalMinusSign2); 448 dfEG.setDecimalFormatSymbols(dfsEG); 449 dfUS.setDecimalFormatSymbols(dfsUS); 450 451 for (int i = 0; i < patterns.length; i++) { 452 System.out.println(BORDER); 453 for (int j = 4; j <= 5; j++) { 454 // Generate a pattern 455 String pattern = patterns[i].replaceAll(" ", delimiters[j]); 456 System.out.println("Pattern=\"" + pattern + "\""); 457 458 System.out.println("*** DateFormat.format test in modified ar_EG"); 459 testDateFormatFormattingInRTL(pattern, i, j, dfEG, localeEG, false); 460 461 System.out.println("*** DateFormat.parse test in modified ar_EG"); 462 testDateFormatParsingInRTL(pattern, i, j, dfEG, localeEG, false); 463 464 System.out.println("*** DateFormat.format test in modified en_US"); 465 testDateFormatFormattingInLTR(pattern, i, j, dfUS, localeUS, true); 466 467 System.out.println("*** DateFormat.parse test in modified en_US"); 468 testDateFormatParsingInLTR(pattern, i, j, dfUS, localeUS, true); 469 } 470 } 471 } 472 473 private static void testDateFormatFormattingInRTL(String pattern, 474 int basePattern, 475 int delimiter, 476 NumberFormat nf, 477 Locale locale, 478 boolean useEnglishMonthName) { 479 Locale.setDefault(locale); 480 481 SimpleDateFormat sdf = new SimpleDateFormat(pattern); 482 if (nf != null) { 483 sdf.setNumberFormat(nf); 484 } 485 for (int i = 0; i < datesToParse[basePattern].length; i++) { 486 if (datesEG[basePattern][i] == null) { 487 continue; 488 } 489 490 String expected = formattedDatesEG[basePattern][i] 491 .replaceAll("JUNE", (useEnglishMonthName ? 492 JuneInEnglish : JuneInArabic)) 493 .replaceAll("JULY", (useEnglishMonthName ? 494 JulyInEnglish : JulyInArabic)) 495 .replaceAll(" ", delimiters[delimiter]); 496 testDateFormatFormatting(sdf, pattern, datesEG[basePattern][i], 497 expected, locale.toString()); 498 } 499 } 500 501 private static void testDateFormatFormattingInLTR(String pattern, 502 int basePattern, 503 int delimiter, 504 NumberFormat nf, 505 Locale locale, 506 boolean useEnglishMonthName) { 507 Locale.setDefault(locale); 508 509 SimpleDateFormat sdf = new SimpleDateFormat(pattern); 510 if (nf != null) { 511 sdf.setNumberFormat(nf); 512 } 513 for (int i = 0; i < datesToParse[basePattern].length; i++) { 514 if (datesUS[basePattern][i] == null) { 515 continue; 516 } 517 518 String expected = formattedDatesUS[basePattern][i] 519 .replaceAll("JUNE", (useEnglishMonthName ? 520 JuneInEnglish : JuneInArabic)) 521 .replaceAll("JULY", (useEnglishMonthName ? 522 JulyInEnglish : JulyInArabic)) 523 .replaceAll(" ", delimiters[delimiter]); 524 testDateFormatFormatting(sdf, pattern, datesUS[basePattern][i], 525 expected, locale.toString()); 526 } 527 } 528 529 private static void testDateFormatFormatting(SimpleDateFormat sdf, 530 String pattern, 531 GregorianCalendar givenGC, 532 String expected, 533 String locale) { 534 Date given = givenGC.getTime(); 535 String str = sdf.format(given); 536 if (expected.equals(str)) { 537 if (verbose) { 538 System.out.print(" Passed: SimpleDateFormat("); 539 System.out.print(locale + ", \"" + pattern + "\").format("); 540 System.out.println(given + ")"); 541 542 System.out.print(" ---> \"" + str + "\" "); 543 System.out.println((givenGC.get(ERA) == BC) ? "(BC)" : "(AD)"); 544 } 545 } else { 546 err = true; 547 548 System.err.print(" Failed: Unexpected SimpleDateFormat("); 549 System.out.print(locale + ", \"" + pattern + "\").format("); 550 System.out.println(given + ") result."); 551 552 System.out.println(" Expected: \"" + expected + "\""); 553 554 System.out.print(" Got: \"" + str + "\" "); 555 System.out.println((givenGC.get(ERA) == BC) ? "(BC)" : "(AD)"); 556 } 557 } 558 559 private static void testDateFormatParsingInRTL(String pattern, 560 int basePattern, 561 int delimiter, 562 NumberFormat nf, 563 Locale locale, 564 boolean useEnglishMonthName) { 565 Locale.setDefault(locale); 566 567 SimpleDateFormat sdf = new SimpleDateFormat(pattern); 568 if (nf != null) { 569 sdf.setNumberFormat(nf); 570 } 571 for (int i = 0; i < datesToParse[basePattern].length; i++) { 572 String given = datesToParse[basePattern][i] 573 .replaceAll(" ", specialDelimiters[0][delimiter]) 574 .replaceAll(" ", delimiters[delimiter]); 575 576 testDateFormatParsing(sdf, pattern, 577 given.replaceAll("JULY", (useEnglishMonthName ? 578 JulyInEnglish : JulyInArabic)), 579 datesEG[basePattern][i], locale.toString()); 580 } 581 } 582 583 private static void testDateFormatParsingInLTR(String pattern, 584 int basePattern, 585 int delimiter, 586 NumberFormat nf, 587 Locale locale, 588 boolean useEnglishMonthName) { 589 Locale.setDefault(locale); 590 591 SimpleDateFormat sdf = new SimpleDateFormat(pattern); 592 if (nf != null) { 593 sdf.setNumberFormat(nf); 594 } 595 for (int i = 0; i < datesToParse[basePattern].length; i++) { 596 String given = datesToParse[basePattern][i] 597 .replaceAll(" ", specialDelimiters[1][delimiter]) 598 .replaceAll(" ", delimiters[delimiter]); 599 600 testDateFormatParsing(sdf, pattern, 601 given.replaceAll("JULY", (useEnglishMonthName ? 602 JulyInEnglish : JulyInArabic)), 603 datesUS[basePattern][i], locale.toString()); 604 } 605 } 606 607 private static void testDateFormatParsing(SimpleDateFormat sdf, 608 String pattern, 609 String given, 610 GregorianCalendar expectedGC, 611 String locale) { 612 try { 613 Date d = sdf.parse(given); 614 if (expectedGC == null) { 615 err = true; 616 System.err.print(" Failed: SimpleDateFormat(" + locale); 617 System.err.print(", \"" + pattern + "\").parse(\"" + given); 618 System.err.println("\") should have thrown ParseException"); 619 } else if (expectedGC.getTime().equals(d)) { 620 if (verbose) { 621 System.out.print(" Passed: SimpleDateFormat(" + locale); 622 System.out.print(", \"" + pattern + "\").parse(\"" + given); 623 System.out.println("\")"); 624 625 System.out.print(" ---> " + d + " (" + d.getTime()); 626 System.out.println(")"); 627 } 628 } else { 629 err = true; 630 System.err.print(" Failed: SimpleDateFormat(" + locale); 631 System.err.print(", \"" + pattern + "\").parse(\"" + given); 632 System.err.println("\")"); 633 634 System.err.print(" Expected: " + expectedGC.getTime()); 635 System.err.println(" (" + d.getTime() + ")"); 636 637 System.err.print(" Got: " + d + " (" + d.getTime()); 638 System.err.println(")"); 639 640 System.err.print(" Pattern: \""); 641 System.err.print(((DecimalFormat)sdf.getNumberFormat()).toPattern()); 642 System.err.println("\""); 643 } 644 } 645 catch (ParseException pe) { 646 if (expectedGC == null) { 647 if (verbose) { 648 System.out.print(" Passed: SimpleDateFormat(" + locale); 649 System.out.print(", \"" + pattern + "\").parse(\"" + given); 650 System.out.println("\")"); 651 652 System.out.println(" threw ParseException as expected"); 653 } 654 } else { 655 err = true; 656 System.err.println(" Failed: Unexpected exception with"); 657 658 System.err.print(" SimpleDateFormat(" + locale); 659 System.err.print(", \"" + pattern + "\").parse(\""); 660 System.err.println(given + "\"):"); 661 662 System.err.println(" " + pe); 663 664 System.err.print(" Pattern: \""); 665 System.err.print(((DecimalFormat)sdf.getNumberFormat()).toPattern()); 666 System.err.println("\""); 667 668 System.err.print(" Month 0: "); 669 System.err.println(sdf.getDateFormatSymbols().getMonths()[0]); 670 } 671 } 672 } 673 674 675 // 676 // NumberFormat test 677 // 678 private static void testNumberFormat() { 679 NumberFormat nfEG = NumberFormat.getInstance(localeEG); 680 NumberFormat nfUS = NumberFormat.getInstance(localeUS); 681 682 System.out.println("*** DecimalFormat.format test in ar_EG"); 683 testNumberFormatFormatting(nfEG, -123456789, "123,456,789-", "ar_EG"); 684 testNumberFormatFormatting(nfEG, -456, "456-", "ar_EG"); 685 686 System.out.println("*** DecimalFormat.parse test in ar_EG"); 687 testNumberFormatParsing(nfEG, "123-", new Long(-123), "ar_EG"); 688 testNumberFormatParsing(nfEG, "123--", new Long(-123), "ar_EG"); 689 testNumberFormatParsingCheckException(nfEG, "-123", 0, "ar_EG"); 690 691 System.out.println("*** DecimalFormat.format test in en_US"); 692 testNumberFormatFormatting(nfUS, -123456789, "-123,456,789", "en_US"); 693 testNumberFormatFormatting(nfUS, -456, "-456", "en_US"); 694 695 System.out.println("*** DecimalFormat.parse test in en_US"); 696 testNumberFormatParsing(nfUS, "123-", new Long(123), "en_US"); 697 testNumberFormatParsing(nfUS, "-123", new Long(-123), "en_US"); 698 testNumberFormatParsingCheckException(nfUS, "--123", 0, "en_US"); 699 } 700 701 private static void testNumberFormatFormatting(NumberFormat nf, 702 int given, 703 String expected, 704 String locale) { 705 String str = nf.format(given); 706 if (expected.equals(str)) { 707 if (verbose) { 708 System.out.print(" Passed: NumberFormat(" + locale); 709 System.out.println(").format(" + given + ")"); 710 711 System.out.println(" ---> \"" + str + "\""); 712 } 713 } else { 714 err = true; 715 System.err.print(" Failed: Unexpected NumberFormat(" + locale); 716 System.err.println(").format(" + given + ") result."); 717 718 System.err.println(" Expected: \"" + expected + "\""); 719 720 System.err.println(" Got: \"" + str + "\""); 721 } 722 } 723 724 private static void testNumberFormatParsing(NumberFormat nf, 725 String given, 726 Number expected, 727 String locale) { 728 try { 729 Number n = nf.parse(given); 730 if (n.equals(expected)) { 731 if (verbose) { 732 System.out.print(" Passed: NumberFormat(" + locale); 733 System.out.println(").parse(\"" + given + "\")"); 734 735 System.out.println(" ---> " + n); 736 } 737 } else { 738 err = true; 739 System.err.print(" Failed: Unexpected NumberFormat(" + locale); 740 System.err.println(").parse(\"" + given + "\") result."); 741 742 System.err.println(" Expected: " + expected); 743 744 System.err.println(" Got: " + n); 745 } 746 } 747 catch (ParseException pe) { 748 err = true; 749 System.err.print(" Failed: Unexpected exception with NumberFormat("); 750 System.err.println(locale + ").parse(\"" + given + "\") :"); 751 752 System.err.println(" " + pe); 753 } 754 } 755 756 private static void testNumberFormatParsingCheckException(NumberFormat nf, 757 String given, 758 int expected, 759 String locale) { 760 try { 761 Number n = nf.parse(given); 762 err = true; 763 764 System.err.print(" Failed: NumberFormat(" + locale); 765 System.err.println(").parse(\"" + given + "\")"); 766 767 System.err.println(" should have thrown ParseException"); 768 } 769 catch (ParseException pe) { 770 int errorOffset = pe.getErrorOffset(); 771 if (errorOffset == expected) { 772 if (verbose) { 773 System.out.print(" Passed: NumberFormat(" + locale); 774 System.out.println(").parse(\"" + given + "\")"); 775 776 System.out.print(" threw ParseException as expected, and its errorOffset was correct: "); 777 System.out.println(errorOffset); 778 } 779 } else { 780 err = true; 781 System.err.print(" Failed: NumberFormat(" + locale); 782 System.err.println(").parse(\"" + given + "\")"); 783 784 System.err.print(" threw ParseException as expected, but its errorOffset was incorrect: "); 785 System.err.println(errorOffset); 786 } 787 } 788 } 789 790 }