1// © 2016 and later: Unicode, Inc. and others. 2// License & terms of use: http://www.unicode.org/copyright.html#License 3/* 4 ******************************************************************************* 5 * Copyright (c) 2004-2014, International Business Machines 6 * Corporation and others. All Rights Reserved. 7 ******************************************************************************* 8 * 9 */ 10package com.ibm.icu.dev.test.serializable; 11 12import java.text.AttributedCharacterIterator; 13import java.util.Date; 14import java.util.HashMap; 15import java.util.Locale; 16 17import com.ibm.icu.impl.DateNumberFormat; 18import com.ibm.icu.impl.TZDBTimeZoneNames; 19import com.ibm.icu.impl.TimeZoneGenericNames; 20import com.ibm.icu.impl.TimeZoneGenericNames.GenericNameType; 21import com.ibm.icu.impl.Utility; 22import com.ibm.icu.text.ChineseDateFormat; 23import com.ibm.icu.text.ChineseDateFormatSymbols; 24import com.ibm.icu.text.CompactDecimalFormat; 25import com.ibm.icu.text.CurrencyPluralInfo; 26import com.ibm.icu.text.DateFormat; 27import com.ibm.icu.text.DateFormatSymbols; 28import com.ibm.icu.text.DateIntervalFormat; 29import com.ibm.icu.text.DateIntervalInfo; 30import com.ibm.icu.text.DecimalFormat; 31import com.ibm.icu.text.DecimalFormatSymbols; 32import com.ibm.icu.text.DurationFormat; 33import com.ibm.icu.text.MessageFormat; 34import com.ibm.icu.text.NumberFormat; 35import com.ibm.icu.text.PluralFormat; 36import com.ibm.icu.text.PluralRules; 37import com.ibm.icu.text.RuleBasedNumberFormat; 38import com.ibm.icu.text.SelectFormat; 39import com.ibm.icu.text.SimpleDateFormat; 40import com.ibm.icu.text.TimeUnitFormat; 41import com.ibm.icu.text.TimeZoneFormat; 42import com.ibm.icu.text.TimeZoneFormat.Style; 43import com.ibm.icu.text.TimeZoneNames; 44import com.ibm.icu.text.TimeZoneNames.NameType; 45import com.ibm.icu.util.Calendar; 46import com.ibm.icu.util.DateInterval; 47import com.ibm.icu.util.GregorianCalendar; 48import com.ibm.icu.util.TimeUnit; 49import com.ibm.icu.util.TimeUnitAmount; 50import com.ibm.icu.util.TimeZone; 51import com.ibm.icu.util.ULocale; 52 53/** 54 * @author emader 55 * 56 * TODO To change the template for this generated type comment go to 57 * Window - Preferences - Java - Code Style - Code Templates 58 */ 59public class FormatHandler 60{ 61 /* 62 * The serialized form of a normally created DateFormatSymbols object 63 * will have locale-specific data in it that might change from one version 64 * of ICU4J to another. To guard against this, we store the following canned 65 * data into the test objects we create. 66 */ 67 static HashMap cannedMonthNames = new HashMap(); 68 static HashMap cannedShortMonthNames = new HashMap(); 69 70 static String en_CA_MonthNames[] = { 71 "January", 72 "February", 73 "March", 74 "April", 75 "May", 76 "June", 77 "July", 78 "August", 79 "September", 80 "October", 81 "November", 82 "December", 83 }; 84 85 static String fr_CA_MonthNames[] = { 86 "janvier", 87 "f\u00E9vrier", 88 "mars", 89 "avril", 90 "mai", 91 "juin", 92 "juillet", 93 "ao\u00FBt", 94 "septembre", 95 "octobre", 96 "novembre", 97 "d\u00E9cembre", 98 }; 99 100 static String zh_Hans_CN_MonthNames[] = { 101 "\u4E00\u6708", 102 "\u4E8C\u6708", 103 "\u4E09\u6708", 104 "\u56DB\u6708", 105 "\u4E94\u6708", 106 "\u516D\u6708", 107 "\u4E03\u6708", 108 "\u516B\u6708", 109 "\u4E5D\u6708", 110 "\u5341\u6708", 111 "\u5341\u4E00\u6708", 112 "\u5341\u4E8C\u6708", 113 }; 114 115 static String zh_CN_MonthNames[] = { 116 "\u4E00\u6708", 117 "\u4E8C\u6708", 118 "\u4E09\u6708", 119 "\u56DB\u6708", 120 "\u4E94\u6708", 121 "\u516D\u6708", 122 "\u4E03\u6708", 123 "\u516B\u6708", 124 "\u4E5D\u6708", 125 "\u5341\u6708", 126 "\u5341\u4E00\u6708", 127 "\u5341\u4E8C\u6708", 128 }; 129 130 static String zh_MonthNames[] = { 131 "\u4E00\u6708", 132 "\u4E8C\u6708", 133 "\u4E09\u6708", 134 "\u56DB\u6708", 135 "\u4E94\u6708", 136 "\u516D\u6708", 137 "\u4E03\u6708", 138 "\u516B\u6708", 139 "\u4E5D\u6708", 140 "\u5341\u6708", 141 "\u5341\u4E00\u6708", 142 "\u5341\u4E8C\u6708", 143 }; 144 145 static String en_MonthNames[] = { 146 "January", 147 "February", 148 "March", 149 "April", 150 "May", 151 "June", 152 "July", 153 "August", 154 "September", 155 "October", 156 "November", 157 "December", 158 }; 159 160 static String fr_FR_MonthNames[] = { 161 "janvier", 162 "f\u00E9vrier", 163 "mars", 164 "avril", 165 "mai", 166 "juin", 167 "juillet", 168 "ao\u00FBt", 169 "septembre", 170 "octobre", 171 "novembre", 172 "d\u00E9cembre", 173 }; 174 175 static String fr_MonthNames[] = { 176 "janvier", 177 "f\u00E9vrier", 178 "mars", 179 "avril", 180 "mai", 181 "juin", 182 "juillet", 183 "ao\u00FBt", 184 "septembre", 185 "octobre", 186 "novembre", 187 "d\u00E9cembre", 188 }; 189 190 static String de_MonthNames[] = { 191 "Januar", 192 "Februar", 193 "M\u00E4rz", 194 "April", 195 "Mai", 196 "Juni", 197 "Juli", 198 "August", 199 "September", 200 "Oktober", 201 "November", 202 "Dezember", 203 }; 204 205 static String de_DE_MonthNames[] = { 206 "Januar", 207 "Februar", 208 "M\u00E4rz", 209 "April", 210 "Mai", 211 "Juni", 212 "Juli", 213 "August", 214 "September", 215 "Oktober", 216 "November", 217 "Dezember", 218 }; 219 220 static String it_MonthNames[] = { 221 "gennaio", 222 "febbraio", 223 "marzo", 224 "aprile", 225 "maggio", 226 "giugno", 227 "luglio", 228 "agosto", 229 "settembre", 230 "ottobre", 231 "novembre", 232 "dicembre", 233 }; 234 235 static String it_IT_MonthNames[] = { 236 "gennaio", 237 "febbraio", 238 "marzo", 239 "aprile", 240 "maggio", 241 "giugno", 242 "luglio", 243 "agosto", 244 "settembre", 245 "ottobre", 246 "novembre", 247 "dicembre", 248 }; 249 250 static String ja_JP_MonthNames[] = { 251 "1\u6708", 252 "2\u6708", 253 "3\u6708", 254 "4\u6708", 255 "5\u6708", 256 "6\u6708", 257 "7\u6708", 258 "8\u6708", 259 "9\u6708", 260 "10\u6708", 261 "11\u6708", 262 "12\u6708", 263 }; 264 265 static String ja_MonthNames[] = { 266 "1\u6708", 267 "2\u6708", 268 "3\u6708", 269 "4\u6708", 270 "5\u6708", 271 "6\u6708", 272 "7\u6708", 273 "8\u6708", 274 "9\u6708", 275 "10\u6708", 276 "11\u6708", 277 "12\u6708", 278 }; 279 280 static String ko_KR_MonthNames[] = { 281 "1\uC6D4", 282 "2\uC6D4", 283 "3\uC6D4", 284 "4\uC6D4", 285 "5\uC6D4", 286 "6\uC6D4", 287 "7\uC6D4", 288 "8\uC6D4", 289 "9\uC6D4", 290 "10\uC6D4", 291 "11\uC6D4", 292 "12\uC6D4", 293 }; 294 295 static String ko_MonthNames[] = { 296 "1\uC6D4", 297 "2\uC6D4", 298 "3\uC6D4", 299 "4\uC6D4", 300 "5\uC6D4", 301 "6\uC6D4", 302 "7\uC6D4", 303 "8\uC6D4", 304 "9\uC6D4", 305 "10\uC6D4", 306 "11\uC6D4", 307 "12\uC6D4", 308 }; 309 310 static String zh_Hant_TW_MonthNames[] = { 311 "\u4E00\u6708", 312 "\u4E8C\u6708", 313 "\u4E09\u6708", 314 "\u56DB\u6708", 315 "\u4E94\u6708", 316 "\u516D\u6708", 317 "\u4E03\u6708", 318 "\u516B\u6708", 319 "\u4E5D\u6708", 320 "\u5341\u6708", 321 "\u5341\u4E00\u6708", 322 "\u5341\u4E8C\u6708", 323 }; 324 325 static String zh_TW_MonthNames[] = { 326 "\u4E00\u6708", 327 "\u4E8C\u6708", 328 "\u4E09\u6708", 329 "\u56DB\u6708", 330 "\u4E94\u6708", 331 "\u516D\u6708", 332 "\u4E03\u6708", 333 "\u516B\u6708", 334 "\u4E5D\u6708", 335 "\u5341\u6708", 336 "\u5341\u4E00\u6708", 337 "\u5341\u4E8C\u6708", 338 }; 339 340 static String en_GB_MonthNames[] = { 341 "January", 342 "February", 343 "March", 344 "April", 345 "May", 346 "June", 347 "July", 348 "August", 349 "September", 350 "October", 351 "November", 352 "December", 353 }; 354 355 static String en_US_MonthNames[] = { 356 "January", 357 "February", 358 "March", 359 "April", 360 "May", 361 "June", 362 "July", 363 "August", 364 "September", 365 "October", 366 "November", 367 "December", 368 }; 369 370 static String en_CA_ShortMonthNames[] = { 371 "Jan", 372 "Feb", 373 "Mar", 374 "Apr", 375 "May", 376 "Jun", 377 "Jul", 378 "Aug", 379 "Sep", 380 "Oct", 381 "Nov", 382 "Dec", 383 }; 384 385 static String fr_CA_ShortMonthNames[] = { 386 "janv.", 387 "f\u00E9vr.", 388 "mars", 389 "avr.", 390 "mai", 391 "juin", 392 "juil.", 393 "ao\u00FBt", 394 "sept.", 395 "oct.", 396 "nov.", 397 "d\u00E9c.", 398 }; 399 400 static String zh_Hans_CN_ShortMonthNames[] = { 401 "\u4E00\u6708", 402 "\u4E8C\u6708", 403 "\u4E09\u6708", 404 "\u56DB\u6708", 405 "\u4E94\u6708", 406 "\u516D\u6708", 407 "\u4E03\u6708", 408 "\u516B\u6708", 409 "\u4E5D\u6708", 410 "\u5341\u6708", 411 "\u5341\u4E00\u6708", 412 "\u5341\u4E8C\u6708", 413 }; 414 415 static String zh_CN_ShortMonthNames[] = { 416 "\u4E00\u6708", 417 "\u4E8C\u6708", 418 "\u4E09\u6708", 419 "\u56DB\u6708", 420 "\u4E94\u6708", 421 "\u516D\u6708", 422 "\u4E03\u6708", 423 "\u516B\u6708", 424 "\u4E5D\u6708", 425 "\u5341\u6708", 426 "\u5341\u4E00\u6708", 427 "\u5341\u4E8C\u6708", 428 }; 429 430 static String zh_ShortMonthNames[] = { 431 "\u4E00\u6708", 432 "\u4E8C\u6708", 433 "\u4E09\u6708", 434 "\u56DB\u6708", 435 "\u4E94\u6708", 436 "\u516D\u6708", 437 "\u4E03\u6708", 438 "\u516B\u6708", 439 "\u4E5D\u6708", 440 "\u5341\u6708", 441 "\u5341\u4E00\u6708", 442 "\u5341\u4E8C\u6708", 443 }; 444 445 static String en_ShortMonthNames[] = { 446 "Jan", 447 "Feb", 448 "Mar", 449 "Apr", 450 "May", 451 "Jun", 452 "Jul", 453 "Aug", 454 "Sep", 455 "Oct", 456 "Nov", 457 "Dec", 458 }; 459 460 static String fr_FR_ShortMonthNames[] = { 461 "janv.", 462 "f\u00E9vr.", 463 "mars", 464 "avr.", 465 "mai", 466 "juin", 467 "juil.", 468 "ao\u00FBt", 469 "sept.", 470 "oct.", 471 "nov.", 472 "d\u00E9c.", 473 }; 474 475 static String fr_ShortMonthNames[] = { 476 "janv.", 477 "f\u00E9vr.", 478 "mars", 479 "avr.", 480 "mai", 481 "juin", 482 "juil.", 483 "ao\u00FBt", 484 "sept.", 485 "oct.", 486 "nov.", 487 "d\u00E9c.", 488 }; 489 490 static String de_ShortMonthNames[] = { 491 "Jan", 492 "Feb", 493 "Mrz", 494 "Apr", 495 "Mai", 496 "Jun", 497 "Jul", 498 "Aug", 499 "Sep", 500 "Okt", 501 "Nov", 502 "Dez", 503 }; 504 505 static String de_DE_ShortMonthNames[] = { 506 "Jan", 507 "Feb", 508 "Mrz", 509 "Apr", 510 "Mai", 511 "Jun", 512 "Jul", 513 "Aug", 514 "Sep", 515 "Okt", 516 "Nov", 517 "Dez", 518 }; 519 520 static String it_ShortMonthNames[] = { 521 "gen", 522 "feb", 523 "mar", 524 "apr", 525 "mag", 526 "giu", 527 "lug", 528 "ago", 529 "set", 530 "ott", 531 "nov", 532 "dic", 533 }; 534 535 static String it_IT_ShortMonthNames[] = { 536 "gen", 537 "feb", 538 "mar", 539 "apr", 540 "mag", 541 "giu", 542 "lug", 543 "ago", 544 "set", 545 "ott", 546 "nov", 547 "dic", 548 }; 549 550 static String ja_JP_ShortMonthNames[] = { 551 "1 \u6708", 552 "2 \u6708", 553 "3 \u6708", 554 "4 \u6708", 555 "5 \u6708", 556 "6 \u6708", 557 "7 \u6708", 558 "8 \u6708", 559 "9 \u6708", 560 "10 \u6708", 561 "11 \u6708", 562 "12 \u6708", 563 }; 564 565 static String ja_ShortMonthNames[] = { 566 "1 \u6708", 567 "2 \u6708", 568 "3 \u6708", 569 "4 \u6708", 570 "5 \u6708", 571 "6 \u6708", 572 "7 \u6708", 573 "8 \u6708", 574 "9 \u6708", 575 "10 \u6708", 576 "11 \u6708", 577 "12 \u6708", 578 }; 579 580 static String ko_KR_ShortMonthNames[] = { 581 "1\uC6D4", 582 "2\uC6D4", 583 "3\uC6D4", 584 "4\uC6D4", 585 "5\uC6D4", 586 "6\uC6D4", 587 "7\uC6D4", 588 "8\uC6D4", 589 "9\uC6D4", 590 "10\uC6D4", 591 "11\uC6D4", 592 "12\uC6D4", 593 }; 594 595 static String ko_ShortMonthNames[] = { 596 "1\uC6D4", 597 "2\uC6D4", 598 "3\uC6D4", 599 "4\uC6D4", 600 "5\uC6D4", 601 "6\uC6D4", 602 "7\uC6D4", 603 "8\uC6D4", 604 "9\uC6D4", 605 "10\uC6D4", 606 "11\uC6D4", 607 "12\uC6D4", 608 }; 609 610 static String zh_Hant_TW_ShortMonthNames[] = { 611 "\u4E00\u6708", 612 "\u4E8C\u6708", 613 "\u4E09\u6708", 614 "\u56DB\u6708", 615 "\u4E94\u6708", 616 "\u516D\u6708", 617 "\u4E03\u6708", 618 "\u516B\u6708", 619 "\u4E5D\u6708", 620 "\u5341\u6708", 621 "\u5341\u4E00\u6708", 622 "\u5341\u4E8C\u6708", 623 }; 624 625 static String zh_TW_ShortMonthNames[] = { 626 "\u4E00\u6708", 627 "\u4E8C\u6708", 628 "\u4E09\u6708", 629 "\u56DB\u6708", 630 "\u4E94\u6708", 631 "\u516D\u6708", 632 "\u4E03\u6708", 633 "\u516B\u6708", 634 "\u4E5D\u6708", 635 "\u5341\u6708", 636 "\u5341\u4E00\u6708", 637 "\u5341\u4E8C\u6708", 638 }; 639 640 static String en_GB_ShortMonthNames[] = { 641 "Jan", 642 "Feb", 643 "Mar", 644 "Apr", 645 "May", 646 "Jun", 647 "Jul", 648 "Aug", 649 "Sep", 650 "Oct", 651 "Nov", 652 "Dec", 653 }; 654 655 static String en_US_ShortMonthNames[] = { 656 "Jan", 657 "Feb", 658 "Mar", 659 "Apr", 660 "May", 661 "Jun", 662 "Jul", 663 "Aug", 664 "Sep", 665 "Oct", 666 "Nov", 667 "Dec", 668 }; 669 670 static { 671 cannedMonthNames.put("en_CA", en_CA_MonthNames); 672 cannedMonthNames.put("fr_CA", fr_CA_MonthNames); 673 cannedMonthNames.put("zh_Hans_CN", zh_Hans_CN_MonthNames); 674 cannedMonthNames.put("zh_CN", zh_CN_MonthNames); 675 cannedMonthNames.put("zh", zh_MonthNames); 676 cannedMonthNames.put("en", en_MonthNames); 677 cannedMonthNames.put("fr_FR", fr_FR_MonthNames); 678 cannedMonthNames.put("fr", fr_MonthNames); 679 cannedMonthNames.put("de", de_MonthNames); 680 cannedMonthNames.put("de_DE", de_DE_MonthNames); 681 cannedMonthNames.put("it", it_MonthNames); 682 cannedMonthNames.put("it_IT", it_IT_MonthNames); 683 cannedMonthNames.put("ja_JP", ja_JP_MonthNames); 684 cannedMonthNames.put("ja", ja_MonthNames); 685 cannedMonthNames.put("ko_KR", ko_KR_MonthNames); 686 cannedMonthNames.put("ko", ko_MonthNames); 687 cannedMonthNames.put("zh_Hant_TW", zh_Hant_TW_MonthNames); 688 cannedMonthNames.put("zh_TW", zh_TW_MonthNames); 689 cannedMonthNames.put("en_GB", en_GB_MonthNames); 690 cannedMonthNames.put("en_US", en_US_MonthNames); 691 692 cannedShortMonthNames.put("en_CA", en_CA_ShortMonthNames); 693 cannedShortMonthNames.put("fr_CA", fr_CA_ShortMonthNames); 694 cannedShortMonthNames.put("zh_Hans_CN", zh_Hans_CN_ShortMonthNames); 695 cannedShortMonthNames.put("zh_CN", zh_CN_ShortMonthNames); 696 cannedShortMonthNames.put("zh", zh_ShortMonthNames); 697 cannedShortMonthNames.put("en", en_ShortMonthNames); 698 cannedShortMonthNames.put("fr_FR", fr_FR_ShortMonthNames); 699 cannedShortMonthNames.put("fr", fr_ShortMonthNames); 700 cannedShortMonthNames.put("de", de_ShortMonthNames); 701 cannedShortMonthNames.put("de_DE", de_DE_ShortMonthNames); 702 cannedShortMonthNames.put("it", it_ShortMonthNames); 703 cannedShortMonthNames.put("it_IT", it_IT_ShortMonthNames); 704 cannedShortMonthNames.put("ja_JP", ja_JP_ShortMonthNames); 705 cannedShortMonthNames.put("ja", ja_ShortMonthNames); 706 cannedShortMonthNames.put("ko_KR", ko_KR_ShortMonthNames); 707 cannedShortMonthNames.put("ko", ko_ShortMonthNames); 708 cannedShortMonthNames.put("zh_Hant_TW", zh_Hant_TW_ShortMonthNames); 709 cannedShortMonthNames.put("zh_TW", zh_TW_ShortMonthNames); 710 cannedShortMonthNames.put("en_GB", en_GB_ShortMonthNames); 711 cannedShortMonthNames.put("en_US", en_US_ShortMonthNames); 712 } 713 714 private static DateFormatSymbols getCannedDateFormatSymbols(ULocale uloc) 715 { 716 DateFormatSymbols dfs =new DateFormatSymbols(GregorianCalendar.class, uloc); 717 String key = uloc.toString(); 718 719 dfs.setMonths((String[]) cannedMonthNames.get(key)); 720 dfs.setShortMonths((String[]) cannedShortMonthNames.get(key)); 721 722 return dfs; 723 } 724 725 private static SimpleDateFormat getCannedSimpleDateFormat(String pattern, ULocale uloc) 726 { 727 DateFormatSymbols dfs = getCannedDateFormatSymbols(uloc); 728 729 // Force PT 730 TimeZone pt = TimeZone.getTimeZone("America/Los_Angeles"); 731 SimpleDateFormat cannedSDF = new SimpleDateFormat(pattern, dfs, uloc); 732 cannedSDF.setTimeZone(pt); 733 return cannedSDF; 734 } 735 736 /* 737 * The serialized form of a normally created DecimalFormatSymbols object 738 * will have locale-specific data in it that might change from one version 739 * of ICU4J to another. To guard against this, we store the following canned 740 * data into the test objects we create. 741 */ 742 static HashMap cannedDecimalFormatSymbols = new HashMap(); 743 744 static String en_CA_StringSymbols[] = { 745 "$", 746 "E", 747 "\u221E", 748 "CAD", 749 "\uFFFD", 750 ".#,-.*;%\u2030+@0" 751 }; 752 753 static String fr_CA_StringSymbols[] = { 754 "$", 755 "E", 756 "\u221E", 757 "CAD", 758 "\uFFFD", 759 ",#\u00A0-,*;%\u2030+@0" 760 }; 761 762 static String zh_CN_StringSymbols[] = { 763 "\uFFE5", 764 "E", 765 "\u221E", 766 "CNY", 767 "\uFFFD", 768 ".#,-.*;%\u2030+@0" 769 }; 770 771 static String zh_StringSymbols[] = { 772 "\u00A4", 773 "E", 774 "\u221E", 775 "XXX", 776 "\uFFFD", 777 ".#,-.*;%\u2030+@0" 778 }; 779 780 static String en_StringSymbols[] = { 781 "\u00A4", 782 "E", 783 "\u221E", 784 "XXX", 785 "\uFFFD", 786 ".#,-.*;%\u2030+@0" 787 }; 788 789 static String fr_FR_StringSymbols[] = { 790 "\u20AC", 791 "E", 792 "\u221E", 793 "EUR", 794 "\uFFFD", 795 ",#\u00A0-,*;%\u2030+@0" 796 }; 797 798 static String fr_StringSymbols[] = { 799 "\u00A4", 800 "E", 801 "\u221E", 802 "XXX", 803 "\uFFFD", 804 ",#\u00A0-,*;%\u2030+@0" 805 }; 806 807 static String de_StringSymbols[] = { 808 "\u00A4", 809 "E", 810 "\u221E", 811 "XXX", 812 "\uFFFD", 813 ",#.-,*;%\u2030+@0" 814 }; 815 816 static String de_DE_StringSymbols[] = { 817 "\u20AC", 818 "E", 819 "\u221E", 820 "EUR", 821 "\uFFFD", 822 ",#.-,*;%\u2030+@0" 823 }; 824 825 static String it_StringSymbols[] = { 826 "\u00A4", 827 "E", 828 "\u221E", 829 "XXX", 830 "\uFFFD", 831 ",#.-,*;%\u2030+@0" 832 }; 833 834 static String it_IT_StringSymbols[] = { 835 "\u20AC", 836 "E", 837 "\u221E", 838 "EUR", 839 "\uFFFD", 840 ",#.-,*;%\u2030+@0" 841 }; 842 843 static String ja_JP_StringSymbols[] = { 844 "\uFFE5", 845 "E", 846 "\u221E", 847 "JPY", 848 "\uFFFD", 849 ".#,-.*;%\u2030+@0" 850 }; 851 852 static String ja_StringSymbols[] = { 853 "\u00A4", 854 "E", 855 "\u221E", 856 "XXX", 857 "\uFFFD", 858 ".#,-.*;%\u2030+@0" 859 }; 860 861 static String ko_KR_StringSymbols[] = { 862 "\uFFE6", 863 "E", 864 "\u221E", 865 "KRW", 866 "\uFFFD", 867 ".#,-.*;%\u2030+@0" 868 }; 869 870 static String ko_StringSymbols[] = { 871 "\u00A4", 872 "E", 873 "\u221E", 874 "XXX", 875 "\uFFFD", 876 ".#,-.*;%\u2030+@0" 877 }; 878 879 static String zh_Hans_CN_StringSymbols[] = { 880 "\uFFE5", 881 "E", 882 "\u221E", 883 "CNY", 884 "\uFFFD", 885 ".#,-.*;%\u2030+@0" 886 }; 887 888 static String zh_Hant_TW_StringSymbols[] = { 889 "NT$", 890 "E", 891 "\u221E", 892 "TWD", 893 "\uFFFD", 894 ".#,-.*;%\u2030+@0" 895 }; 896 897 static String zh_TW_StringSymbols[] = { 898 "NT$", 899 "E", 900 "\u221E", 901 "TWD", 902 "\uFFFD", 903 ".#,-.*;%\u2030+@0" 904 }; 905 906 static String en_GB_StringSymbols[] = { 907 "\u00A3", 908 "E", 909 "\u221E", 910 "GBP", 911 "\uFFFD", 912 ".#,-.*;%\u2030+@0" 913 }; 914 915 static String en_US_StringSymbols[] = { 916 "$", 917 "E", 918 "\u221E", 919 "USD", 920 "\uFFFD", 921 ".#,-.*;%\u2030+@0" 922 }; 923 924 static { 925 cannedDecimalFormatSymbols.put("en_CA", en_CA_StringSymbols); 926 cannedDecimalFormatSymbols.put("fr_CA", fr_CA_StringSymbols); 927 cannedDecimalFormatSymbols.put("zh_CN", zh_CN_StringSymbols); 928 cannedDecimalFormatSymbols.put("zh", zh_StringSymbols); 929 cannedDecimalFormatSymbols.put("en", en_StringSymbols); 930 cannedDecimalFormatSymbols.put("fr_FR", fr_FR_StringSymbols); 931 cannedDecimalFormatSymbols.put("fr", fr_StringSymbols); 932 cannedDecimalFormatSymbols.put("de", de_StringSymbols); 933 cannedDecimalFormatSymbols.put("de_DE", de_DE_StringSymbols); 934 cannedDecimalFormatSymbols.put("it", it_StringSymbols); 935 cannedDecimalFormatSymbols.put("it_IT", it_IT_StringSymbols); 936 cannedDecimalFormatSymbols.put("ja_JP", ja_JP_StringSymbols); 937 cannedDecimalFormatSymbols.put("ja", ja_StringSymbols); 938 cannedDecimalFormatSymbols.put("ko_KR", ko_KR_StringSymbols); 939 cannedDecimalFormatSymbols.put("ko", ko_StringSymbols); 940 cannedDecimalFormatSymbols.put("zh_Hans_CN", zh_Hans_CN_StringSymbols); 941 cannedDecimalFormatSymbols.put("zh_Hant_TW", zh_Hant_TW_StringSymbols); 942 cannedDecimalFormatSymbols.put("zh_TW", zh_TW_StringSymbols); 943 cannedDecimalFormatSymbols.put("en_GB", en_GB_StringSymbols); 944 cannedDecimalFormatSymbols.put("en_US", en_US_StringSymbols); 945 } 946 947 private static char[] getCharSymbols(DecimalFormatSymbols dfs) 948 { 949 char symbols[] = { 950 dfs.getDecimalSeparator(), 951 dfs.getDigit(), 952 dfs.getGroupingSeparator(), 953 dfs.getMinusSign(), 954 dfs.getMonetaryDecimalSeparator(), 955 dfs.getPadEscape(), 956 dfs.getPatternSeparator(), 957 dfs.getPercent(), 958 dfs.getPerMill(), 959 dfs.getPlusSign(), 960 dfs.getSignificantDigit(), 961 dfs.getZeroDigit() 962 }; 963 964 return symbols; 965 } 966 967 private static void setCharSymbols(DecimalFormatSymbols dfs, char symbols[]) 968 { 969 dfs.setDecimalSeparator(symbols[0]); 970 dfs.setDigit(symbols[1]); 971 dfs.setGroupingSeparator(symbols[2]); 972 dfs.setMinusSign(symbols[3]); 973 dfs.setMonetaryDecimalSeparator(symbols[4]); 974 dfs.setPadEscape(symbols[5]); 975 dfs.setPatternSeparator(symbols[6]); 976 dfs.setPercent(symbols[7]); 977 dfs.setPerMill(symbols[8]); 978 dfs.setPlusSign(symbols[9]); 979 dfs.setSignificantDigit(symbols[10]); 980 dfs.setZeroDigit(symbols[11]); 981 } 982 983 private static String[] getStringSymbols(DecimalFormatSymbols dfs) 984 { 985 String symbols[] = { 986 dfs.getCurrencySymbol(), 987 dfs.getExponentSeparator(), 988 dfs.getInfinity(), 989 dfs.getInternationalCurrencySymbol(), 990 dfs.getNaN() 991 }; 992 993 return symbols; 994 } 995 996 private static DecimalFormatSymbols getCannedDecimalFormatSymbols(ULocale uloc) 997 { 998 DecimalFormatSymbols dfs = new DecimalFormatSymbols(uloc); 999 1000 setSymbols(dfs, (String[]) cannedDecimalFormatSymbols.get(uloc.toString())); 1001 1002 return dfs; 1003 } 1004 1005 private static DecimalFormat getCannedDecimalFormat(String pattern, ULocale uloc) 1006 { 1007 return new DecimalFormat(pattern, getCannedDecimalFormatSymbols(uloc)); 1008 } 1009 1010 private static void setSymbols(DecimalFormatSymbols dfs, String symbols[]) 1011 { 1012 dfs.setCurrencySymbol(symbols[0]); 1013 dfs.setExponentSeparator(symbols[1]); 1014 dfs.setInfinity(symbols[2]); 1015 dfs.setInternationalCurrencySymbol(symbols[3]); 1016 dfs.setNaN(symbols[4]); 1017 1018 setCharSymbols(dfs, symbols[5].toCharArray()); 1019 } 1020 1021 public static class RelativeDateFormatHandler implements SerializableTestUtility.Handler 1022 { 1023 @Override 1024 public Object[] getTestObjects() 1025 { 1026 DateFormat formats[] = { 1027 DateFormat.getDateInstance(DateFormat.RELATIVE_LONG,new ULocale("en")), 1028 DateFormat.getDateInstance(DateFormat.RELATIVE_SHORT,new ULocale("ru")), 1029 }; 1030 1031 return formats; 1032 } 1033 1034 @Override 1035 public boolean hasSameBehavior(Object a, Object b) { 1036 DateFormat da = (DateFormat)a; 1037 DateFormat db = (DateFormat)b; 1038 1039 Date d = new Date(System.currentTimeMillis()); 1040 return da.format(d).equals(db.format(d)); 1041 } 1042 } 1043 1044 public static class BasicDurationFormatHandler implements SerializableTestUtility.Handler 1045 { 1046 @Override 1047 public Object[] getTestObjects() 1048 { 1049 DurationFormat formats[] = { 1050 DurationFormat.getInstance(new ULocale("en")) 1051 1052 }; 1053 1054 return formats; 1055 } 1056 1057 //TODO: Revisit this after 3.8 1058 @Override 1059 public boolean hasSameBehavior(Object a, Object b) { 1060 //DurationFormat da = (DurationFormat)a; 1061 //DurationFormat db = (DurationFormat)b; 1062 1063 //Date d = new Date(12345); 1064 //System.err.println("Warning: BasicDurationFormat test is being skipped for now."); 1065 return true; 1066 //return da.format(d).equals(db.format(d)); 1067 } 1068 } 1069 1070 public static class NumberFormatHandler implements SerializableTestUtility.Handler 1071 { 1072 @Override 1073 public Object[] getTestObjects() 1074 { 1075 ULocale uloc = ULocale.forLocale(Locale.US); 1076 NumberFormat formats[] = { 1077 /* 1078 * The code below was used to genereate the 1079 * serialized NumberFormat objects in ICU 3.6: 1080 * 1081 * NumberFormat.getInstance(Locale.US) 1082 * NumberFormat.getCurrencyInstance(Locale.US) 1083 * NumberFormat.getPercentInstance(Locale.US) 1084 * NumberFormat.getScientificInstance(Locale.US) 1085 * 1086 * Because the locale data might now be different that it was in 1087 * ICU 3.6, the only way to guarantee that the object we generate 1088 * will match the ICU 3.6 objects is to generate DecimalFormat objects 1089 * that use the same patterns and DecimalFormatSymbols that 1090 * were used in ICU 3.6. 1091 */ 1092 getCannedDecimalFormat("#,##0.###", uloc), 1093 getCannedDecimalFormat("\u00A4#,##0.00;(\u00A4#,##0.00)", uloc), 1094 getCannedDecimalFormat("#,##0%", uloc), 1095 getCannedDecimalFormat("#E0", uloc) 1096 1097 }; 1098 1099 return formats; 1100 } 1101 1102 @Override 1103 public boolean hasSameBehavior(Object a, Object b) 1104 { 1105 NumberFormat format_a = (NumberFormat) a; 1106 NumberFormat format_b = (NumberFormat) b; 1107 double number = 1234.56; 1108 1109 return format_a.format(number).equals(format_b.format(number)); 1110 } 1111 } 1112 1113 public static class DecimalFormatHandler extends NumberFormatHandler 1114 { 1115 @Override 1116 public Object[] getTestObjects() 1117 { 1118 Locale locales[] = SerializableTestUtility.getLocales(); 1119 DecimalFormat formats[] = new DecimalFormat[locales.length]; 1120 1121 for (int i = 0; i < locales.length; i += 1) { 1122 ULocale uloc = ULocale.forLocale(locales[i]); 1123 1124 formats[i] = getCannedDecimalFormat("#,##0.###", uloc); 1125 } 1126 if (formats[0] != null) { 1127 // Ticket#6449 1128 // Once formatToCharacterIterator is called, NumberFormat.Field 1129 // instances are created and stored in the private List field. 1130 // NumberForamt.Field is not a serializable, so serializing such 1131 // instances end up NotSerializableException. This problem was 1132 // reproduced since formatToCharacterIterator was introduced, 1133 // up to ICU 4.0. 1134 1135 AttributedCharacterIterator aci = formats[0].formatToCharacterIterator(new Double(12.345D)); 1136 if (aci == null) {} // NOP - for resolving 'Unused local variable' warning. 1137 } 1138 return formats; 1139 } 1140 } 1141 1142 public static class RuleBasedNumberFormatHandler extends NumberFormatHandler 1143 { 1144 // default rules, from root.txt 1145 String xx_SpelloutRules = "=#,##0.######=;\n"; 1146 String xx_OrdinalRules = "=#,##0=;\n"; 1147 String xx_DurationRules = "=#,##0=;\n"; 1148 1149 String ja_spelloutRules = 1150 "%financial:\n" + 1151 "\u96f6; \u58f1; \u5f10; \u53c2; \u56db; \u4f0d; \u516d; \u4e03; \u516b; \u4e5d;\n" + 1152 "\u62fe[>>];\n" + 1153 "20: <<\u62fe[>>];\n" + 1154 "100: <<\u767e[>>];\n" + 1155 "1000: <<\u5343[>>];\n" + 1156 "10,000: <<\u4e07[>>];\n" + 1157 "100,000,000: <<\u5104[>>];\n" + 1158 "1,000,000,000,000: <<\u5146[>>];\n" + 1159 "10,000,000,000,000,000: =#,##0=;\n" + 1160 1161 "%traditional:\n" + 1162 "\u96f6; \u4e00; \u4e8c; \u4e09; \u56db; \u4e94; \u516d; \u4e03; \u516b; \u4e5d;\n" + 1163 "\u5341[>>];\n" + 1164 "20: <<\u5341[>>];\n" + 1165 "100: <<\u767e[>>];\n" + 1166 "1000: <<\u5343[>>];\n" + 1167 "10,000: <<\u4e07[>>];\n" + 1168 "100,000,000: <<\u5104[>>];\n" + 1169 "1,000,000,000,000: <<\u5146[>>];\n" + 1170 "10,000,000,000,000,000: =#,##0=;"; 1171 1172 String en_SpelloutRules = 1173 // This rule set shows the normal simple formatting rules for English 1174 "%simplified:\n" + 1175 // negative number rule. This rule is used to format negative 1176 // numbers. The result of formatting the number's absolute 1177 // value is placed where the >> is. 1178 "-x: minus >>;\n" + 1179 // faction rule. This rule is used for formatting numbers 1180 // with fractional parts. The result of formatting the 1181 // number's integral part is substituted for the <<, and 1182 // the result of formatting the number's fractional part 1183 // (one digit at a time, e.g., 0.123 is "zero point one two 1184 // three") replaces the >>. 1185 "x.x: << point >>;\n" + 1186 // the rules for the values from 0 to 19 are simply the 1187 // words for those numbers 1188 "zero; one; two; three; four; five; six; seven; eight; nine;\n" + 1189 "ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" + 1190 "seventeen; eighteen; nineteen;\n" + 1191 // beginning at 20, we use the >> to mark the position where 1192 // the result of formatting the number's ones digit. Thus, 1193 // we only need a new rule at every multiple of 10. Text in 1194 // backets is omitted if the value being formatted is an 1195 // even multiple of 10. 1196 "20: twenty[->>];\n" + 1197 "30: thirty[->>];\n" + 1198 "40: forty[->>];\n" + 1199 "50: fifty[->>];\n" + 1200 "60: sixty[->>];\n" + 1201 "70: seventy[->>];\n" + 1202 "80: eighty[->>];\n" + 1203 "90: ninety[->>];\n" + 1204 // beginning at 100, we can use << to mark the position where 1205 // the result of formatting the multiple of 100 is to be 1206 // inserted. Notice also that the meaning of >> has shifted: 1207 // here, it refers to both the ones place and the tens place. 1208 // The meanings of the << and >> tokens depend on the base value 1209 // of the rule. A rule's divisor is (usually) the highest 1210 // power of 10 that is less than or equal to the rule's base 1211 // value. The value being formatted is divided by the rule's 1212 // divisor, and the integral quotient is used to get the text 1213 // for <<, while the remainder is used to produce the text 1214 // for >>. Again, text in brackets is omitted if the value 1215 // being formatted is an even multiple of the rule's divisor 1216 // (in this case, an even multiple of 100) 1217 "100: << hundred[ >>];\n" + 1218 // The rules for the higher numbers work the same way as the 1219 // rule for 100: Again, the << and >> tokens depend on the 1220 // rule's divisor, which for all these rules is also the rule's 1221 // base value. To group by thousand, we simply don't have any 1222 // rules between 1,000 and 1,000,000. 1223 "1000: << thousand[ >>];\n" + 1224 "1,000,000: << million[ >>];\n" + 1225 "1,000,000,000: << billion[ >>];\n" + 1226 "1,000,000,000,000: << trillion[ >>];\n" + 1227 // overflow rule. This rule specifies that values of a 1228 // quadrillion or more are shown in numerals rather than words. 1229 // The == token means to format (with new rules) the value 1230 // being formatted by this rule and place the result where 1231 // the == is. The #,##0 inside the == signs is a 1232 // DecimalFormat pattern. It specifies that the value should 1233 // be formatted with a DecimalFormat object, and that it 1234 // should be formatted with no decimal places, at least one 1235 // digit, and a thousands separator. 1236 "1,000,000,000,000,000: =#,##0=;\n" + 1237 1238 // %default is a more elaborate form of %simplified; It is basically 1239 // the same, except that it introduces "and" before the ones digit 1240 // when appropriate (basically, between the tens and ones digits) and 1241 // separates the thousands groups with commas in values over 100,000. 1242 "%default:\n" + 1243 // negative-number and fraction rules. These are the same 1244 // as those for %simplified, but have to be stated here too 1245 // because this is an entry point 1246 "-x: minus >>;\n" + 1247 "x.x: << point >>;\n" + 1248 // just use %simplified for values below 100 1249 "=%simplified=;\n" + 1250 // for values from 100 to 9,999 use %%and to decide whether or 1251 // not to interpose the "and" 1252 "100: << hundred[ >%%and>];\n" + 1253 "1000: << thousand[ >%%and>];\n" + 1254 // for values of 100,000 and up, use %%commas to interpose the 1255 // commas in the right places (and also to interpose the "and") 1256 "100,000>>: << thousand[>%%commas>];\n" + 1257 "1,000,000: << million[>%%commas>];\n" + 1258 "1,000,000,000: << billion[>%%commas>];\n" + 1259 "1,000,000,000,000: << trillion[>%%commas>];\n" + 1260 "1,000,000,000,000,000: =#,##0=;\n" + 1261 // if the value passed to this rule set is greater than 100, don't 1262 // add the "and"; if it's less than 100, add "and" before the last 1263 // digits 1264 "%%and:\n" + 1265 "and =%default=;\n" + 1266 "100: =%default=;\n" + 1267 // this rule set is used to place the commas 1268 "%%commas:\n" + 1269 // for values below 100, add "and" (the apostrophe at the 1270 // beginning is ignored, but causes the space that follows it 1271 // to be significant: this is necessary because the rules 1272 // calling %%commas don't put a space before it) 1273 "' and =%default=;\n" + 1274 // put a comma after the thousands (or whatever preceded the 1275 // hundreds) 1276 "100: , =%default=;\n" + 1277 // put a comma after the millions (or whatever precedes the 1278 // thousands) 1279 "1000: , <%default< thousand, >%default>;\n" + 1280 // and so on... 1281 "1,000,000: , =%default=;" + 1282 // %%lenient-parse isn't really a set of number formatting rules; 1283 // it's a set of collation rules. Lenient-parse mode uses a Collator 1284 // object to compare fragments of the text being parsed to the text 1285 // in the rules, allowing more leeway in the matching text. This set 1286 // of rules tells the formatter to ignore commas when parsing (it 1287 // already ignores spaces, which is why we refer to the space; it also 1288 // ignores hyphens, making "twenty one" and "twenty-one" parse 1289 // identically) 1290 "%%lenient-parse:\n" + 1291 // "& ' ' , ',' ;\n" + 1292 " &\u0000 << ' ' << ',' << '-'; \n"; 1293 1294 String en_GB_SpelloutRules = 1295 "%simplified:\n" + 1296 "-x: minus >>;\n" + 1297 "x.x: << point >>;\n" + 1298 "zero; one; two; three; four; five; six; seven; eight; nine;\n" + 1299 "ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" + 1300 " seventeen; eighteen; nineteen;\n" + 1301 "20: twenty[->>];\n" + 1302 "30: thirty[->>];\n" + 1303 "40: forty[->>];\n" + 1304 "50: fifty[->>];\n" + 1305 "60: sixty[->>];\n" + 1306 "70: seventy[->>];\n" + 1307 "80: eighty[->>];\n" + 1308 "90: ninety[->>];\n" + 1309 "100: << hundred[ >>];\n" + 1310 "1000: << thousand[ >>];\n" + 1311 "1,000,000: << million[ >>];\n" + 1312 "1,000,000,000,000: << billion[ >>];\n" + 1313 "1,000,000,000,000,000: =#,##0=;\n" + 1314 "%default:\n" + 1315 "-x: minus >>;\n" + 1316 "x.x: << point >>;\n" + 1317 "=%simplified=;\n" + 1318 "100: << hundred[ >%%and>];\n" + 1319 "1000: << thousand[ >%%and>];\n" + 1320 "100,000>>: << thousand[>%%commas>];\n" + 1321 "1,000,000: << million[>%%commas>];\n" + 1322 "1,000,000,000,000: << billion[>%%commas>];\n" + 1323 "1,000,000,000,000,000: =#,##0=;\n" + 1324 "%%and:\n" + 1325 "and =%default=;\n" + 1326 "100: =%default=;\n" + 1327 "%%commas:\n" + 1328 "' and =%default=;\n" + 1329 "100: , =%default=;\n" + 1330 "1000: , <%default< thousand, >%default>;\n" + 1331 "1,000,000: , =%default=;" + 1332 "%%lenient-parse:\n" + 1333 "& ' ' , ',' ;\n"; 1334 1335 String fr_SpelloutRules = 1336 // the main rule set 1337 "%main:\n" + 1338 "-x: moins >>;\n" + 1339 "x.x: << virgule >>;\n" + 1340 // words for numbers from 0 to 10 1341 "z\u00e9ro; un; deux; trois; quatre; cinq; six; sept; huit; neuf;\n" + 1342 "dix; onze; douze; treize; quatorze; quinze; seize;\n" + 1343 " dix-sept; dix-huit; dix-neuf;\n" + 1344 // ords for the multiples of 10: %%alt-ones inserts "et" 1345 // when needed 1346 "20: vingt[->%%alt-ones>];\n" + 1347 "30: trente[->%%alt-ones>];\n" + 1348 "40: quarante[->%%alt-ones>];\n" + 1349 "50: cinquante[->%%alt-ones>];\n" + 1350 // rule for 60. The /20 causes this rule's multiplier to be 1351 // 20 rather than 10, allowinhg us to recurse for all values 1352 // from 60 to 79... 1353 "60/20: soixante[->%%alt-ones>];\n" + 1354 // ...except for 71, which must be special-cased 1355 "71: soixante et onze;\n" + 1356 // at 72, we have to repeat the rule for 60 to get us to 79 1357 "72/20: soixante->%%alt-ones>;\n" + 1358 // at 80, we state a new rule with the phrase for 80. Since 1359 // it changes form when there's a ones digit, we need a second 1360 // rule at 81. This rule also includes "/20," allowing it to 1361 // be used correctly for all values up to 99 1362 "80: quatre-vingts; 81/20: quatre-vingt->>;\n" + 1363 // "cent" becomes plural when preceded by a multiplier, and 1364 // the multiplier is omitted from the singular form 1365 "100: cent[ >>];\n" + 1366 "200: << cents[ >>];\n" + 1367 "1000: mille[ >>];\n" + 1368 // values from 1,100 to 1,199 are rendered as "onze cents..." 1369 // instead of "mille cent..." The > after "1000" decreases 1370 // the rule's exponent, causing its multiplier to be 100 instead 1371 // of 1,000. This prevents us from getting "onze cents cent 1372 // vingt-deux" ("eleven hundred one hundred twenty-two"). 1373 "1100>: onze cents[ >>];\n" + 1374 // at 1,200, we go back to formating in thousands, so we 1375 // repeat the rule for 1,000 1376 "1200: mille >>;\n" + 1377 // at 2,000, the multiplier is added 1378 "2000: << mille[ >>];\n" + 1379 "1,000,000: << million[ >>];\n" + 1380 "1,000,000,000: << milliard[ >>];\n" + 1381 "1,000,000,000,000: << billion[ >>];\n" + 1382 "1,000,000,000,000,000: =#,##0=;\n" + 1383 // %%alt-ones is used to insert "et" when the ones digit is 1 1384 "%%alt-ones:\n" + 1385 "; et-un; =%main=;\n" + 1386 "%%lenient-parse:\n" + 1387 "&\u0000 << ' ' << ',' << '-';\n"; 1388 1389 String de_SpelloutRules = 1390 // 1 is "eins" when by itself, but turns into "ein" in most 1391 // combinations 1392 "%alt-ones:\n" + 1393 "-x: minus >>;\n" + 1394 "x.x: << komma >>;\n" + 1395 "null; eins; =%%main=;\n" + 1396 "%%main:\n" + 1397 // words for numbers from 0 to 12. Notice that the values 1398 // from 13 to 19 can derived algorithmically, unlike in most 1399 // other languages 1400 "null; ein; zwei; drei; vier; f\u00fcnf; sechs; sieben; acht; neun;\n" + 1401 "zehn; elf; zw\u00f6lf; >>zehn;\n" + 1402 // rules for the multiples of 10. Notice that the ones digit 1403 // goes on the front 1404 "20: [>>und]zwanzig;\n" + 1405 "30: [>>und]drei\u00dfig;\n" + 1406 "40: [>>und]vierzig;\n" + 1407 "50: [>>und]f\u00fcnfzig;\n" + 1408 "60: [>>und]sechzig;\n" + 1409 "70: [>>und]siebzig;\n" + 1410 "80: [>>und]achtzig;\n" + 1411 "90: [>>und]neunzig;\n" + 1412 "100: hundert[>%alt-ones>];\n" + 1413 "200: <<hundert[>%alt-ones>];\n" + 1414 "1000: tausend[>%alt-ones>];\n" + 1415 "2000: <<tausend[>%alt-ones>];\n" + 1416 "1,000,000: eine Million[ >%alt-ones>];\n" + 1417 "2,000,000: << Millionen[ >%alt-ones>];\n" + 1418 "1,000,000,000: eine Milliarde[ >%alt-ones>];\n" + 1419 "2,000,000,000: << Milliarden[ >%alt-ones>];\n" + 1420 "1,000,000,000,000: eine Billion[ >%alt-ones>];\n" + 1421 "2,000,000,000,000: << Billionen[ >%alt-ones>];\n" + 1422 "1,000,000,000,000,000: =#,##0=;" + 1423 "%%lenient-parse:\n" + 1424 "&\u0000 << ' ' << '-'\n" + 1425 "& ae , \u00e4 & ae , \u00c4\n" + 1426 "& oe , \u00f6 & oe , \u00d6\n" + 1427 "& ue , \u00fc & ue , \u00dc\n"; 1428 1429 String it_SpelloutRules = 1430 // main rule set. Follows the patterns of the preceding rule sets, 1431 // except that the final vowel is omitted from words ending in 1432 // vowels when they are followed by another word; instead, we have 1433 // separate rule sets that are identical to this one, except that 1434 // all the words that don't begin with a vowel have a vowel tacked 1435 // onto them at the front. A word ending in a vowel calls a 1436 // substitution that will supply that vowel, unless that vowel is to 1437 // be elided. 1438 "%main:\n" + 1439 "-x: meno >>;\n" + 1440 "x.x: << virgola >>;\n" + 1441 "zero; uno; due; tre; quattro; cinque; sei; sette; otto; nove;\n" + 1442 "dieci; undici; dodici; tredici; quattordici; quindici; sedici;\n" + 1443 " diciasette; diciotto; diciannove;\n" + 1444 "20: venti; vent>%%with-i>;\n" + 1445 "30: trenta; trent>%%with-i>;\n" + 1446 "40: quaranta; quarant>%%with-a>;\n" + 1447 "50: cinquanta; cinquant>%%with-a>;\n" + 1448 "60: sessanta; sessant>%%with-a>;\n" + 1449 "70: settanta; settant>%%with-a>;\n" + 1450 "80: ottanta; ottant>%%with-a>;\n" + 1451 "90: novanta; novant>%%with-a>;\n" + 1452 "100: cento; cent[>%%with-o>];\n" + 1453 "200: <<cento; <<cent[>%%with-o>];\n" + 1454 "1000: mille; mill[>%%with-i>];\n" + 1455 "2000: <<mila; <<mil[>%%with-a>];\n" + 1456 "100,000>>: <<mila[ >>];\n" + 1457 "1,000,000: =#,##0= (incomplete data);\n" + 1458 "%%with-a:\n" + 1459 "azero; uno; adue; atre; aquattro; acinque; asei; asette; otto; anove;\n" + 1460 "adieci; undici; adodici; atredici; aquattordici; aquindici; asedici;\n" + 1461 " adiciasette; adiciotto; adiciannove;\n" + 1462 "20: aventi; avent>%%with-i>;\n" + 1463 "30: atrenta; atrent>%%with-i>;\n" + 1464 "40: aquaranta; aquarant>%%with-a>;\n" + 1465 "50: acinquanta; acinquant>%%with-a>;\n" + 1466 "60: asessanta; asessant>%%with-a>;\n" + 1467 "70: asettanta; asettant>%%with-a>;\n" + 1468 "80: ottanta; ottant>%%with-a>;\n" + 1469 "90: anovanta; anovant>%%with-a>;\n" + 1470 "100: acento; acent[>%%with-o>];\n" + 1471 "200: <%%with-a<cento; <%%with-a<cent[>%%with-o>];\n" + 1472 "1000: amille; amill[>%%with-i>];\n" + 1473 "2000: <%%with-a<mila; <%%with-a<mil[>%%with-a>];\n" + 1474 "100,000: =%main=;\n" + 1475 "%%with-i:\n" + 1476 "izero; uno; idue; itre; iquattro; icinque; isei; isette; otto; inove;\n" + 1477 "idieci; undici; idodici; itredici; iquattordici; iquindici; isedici;\n" + 1478 " idiciasette; idiciotto; idiciannove;\n" + 1479 "20: iventi; ivent>%%with-i>;\n" + 1480 "30: itrenta; itrent>%%with-i>;\n" + 1481 "40: iquaranta; iquarant>%%with-a>;\n" + 1482 "50: icinquanta; icinquant>%%with-a>;\n" + 1483 "60: isessanta; isessant>%%with-a>;\n" + 1484 "70: isettanta; isettant>%%with-a>;\n" + 1485 "80: ottanta; ottant>%%with-a>;\n" + 1486 "90: inovanta; inovant>%%with-a>;\n" + 1487 "100: icento; icent[>%%with-o>];\n" + 1488 "200: <%%with-i<cento; <%%with-i<cent[>%%with-o>];\n" + 1489 "1000: imille; imill[>%%with-i>];\n" + 1490 "2000: <%%with-i<mila; <%%with-i<mil[>%%with-a>];\n" + 1491 "100,000: =%main=;\n" + 1492 "%%with-o:\n" + 1493 "ozero; uno; odue; otre; oquattro; ocinque; osei; osette; otto; onove;\n" + 1494 "odieci; undici; ododici; otredici; oquattordici; oquindici; osedici;\n" + 1495 " odiciasette; odiciotto; odiciannove;\n" + 1496 "20: oventi; ovent>%%with-i>;\n" + 1497 "30: otrenta; otrent>%%with-i>;\n" + 1498 "40: oquaranta; oquarant>%%with-a>;\n" + 1499 "50: ocinquanta; ocinquant>%%with-a>;\n" + 1500 "60: osessanta; osessant>%%with-a>;\n" + 1501 "70: osettanta; osettant>%%with-a>;\n" + 1502 "80: ottanta; ottant>%%with-a>;\n" + 1503 "90: onovanta; onovant>%%with-a>;\n" + 1504 "100: ocento; ocent[>%%with-o>];\n" + 1505 "200: <%%with-o<cento; <%%with-o<cent[>%%with-o>];\n" + 1506 "1000: omille; omill[>%%with-i>];\n" + 1507 "2000: <%%with-o<mila; <%%with-o<mil[>%%with-a>];\n" + 1508 "100,000: =%main=;\n" ; 1509 1510 String en_OrdinalRules = 1511 // this rule set formats the numeral and calls %%abbrev to 1512 // supply the abbreviation 1513 "%main:\n" + 1514 "=#,##0==%%abbrev=;\n" + 1515 // this rule set supplies the abbreviation 1516 "%%abbrev:\n" + 1517 // the abbreviations. Everything from 4 to 19 ends in "th" 1518 "th; st; nd; rd; th;\n" + 1519 // at 20, we begin repeating the cycle every 10 (13 is "13th", 1520 // but 23 and 33 are "23rd" and "33rd") We do this by 1521 // ignoring all bug the ones digit in selecting the abbreviation 1522 "20: >>;\n" + 1523 // at 100, we repeat the whole cycle by considering only the 1524 // tens and ones digits in picking an abbreviation 1525 "100: >>;\n"; 1526 1527 String en_DurationRules = 1528 // main rule set for formatting with words 1529 "%with-words:\n" + 1530 // take care of singular and plural forms of "second" 1531 "0 seconds; 1 second; =0= seconds;\n" + 1532 // use %%min to format values greater than 60 seconds 1533 "60/60: <%%min<[, >>];\n" + 1534 // use %%hr to format values greater than 3,600 seconds 1535 // (the ">>>" below causes us to see the number of minutes 1536 // when when there are zero minutes) 1537 "3600/60: <%%hr<[, >>>];\n" + 1538 // this rule set takes care of the singular and plural forms 1539 // of "minute" 1540 "%%min:\n" + 1541 "0 minutes; 1 minute; =0= minutes;\n" + 1542 // this rule set takes care of the singular and plural forms 1543 // of "hour" 1544 "%%hr:\n" + 1545 "0 hours; 1 hour; =0= hours;\n" + 1546 1547 // main rule set for formatting in numerals 1548 "%in-numerals:\n" + 1549 // values below 60 seconds are shown with "sec." 1550 "=0= sec.;\n" + 1551 // higher values are shown with colons: %%min-sec is used for 1552 // values below 3,600 seconds... 1553 "60: =%%min-sec=;\n" + 1554 // ...and %%hr-min-sec is used for values of 3,600 seconds 1555 // and above 1556 "3600: =%%hr-min-sec=;\n" + 1557 // this rule causes values of less than 10 minutes to show without 1558 // a leading zero 1559 "%%min-sec:\n" + 1560 "0: :=00=;\n" + 1561 "60/60: <0<>>;\n" + 1562 // this rule set is used for values of 3,600 or more. Minutes are always 1563 // shown, and always shown with two digits 1564 "%%hr-min-sec:\n" + 1565 "0: :=00=;\n" + 1566 "60/60: <00<>>;\n" + 1567 "3600/60: <#,##0<:>>>;\n" + 1568 // the lenient-parse rules allow several different characters to be used 1569 // as delimiters between hours, minutes, and seconds 1570 "%%lenient-parse:\n" + 1571 "& ':' = '.' = ' ' = '-';\n"; 1572 1573 HashMap cannedData = new HashMap(); 1574 1575 { 1576 cannedData.put("en_CA/SpelloutRules", en_SpelloutRules); 1577 cannedData.put("en_CA/OrdinalRules", en_OrdinalRules); 1578 cannedData.put("en_CA/DurationRules", en_DurationRules); 1579 1580 cannedData.put("fr_CA/SpelloutRules", fr_SpelloutRules); 1581 cannedData.put("fr_CA/OrdinalRules", xx_OrdinalRules); 1582 cannedData.put("fr_CA/DurationRules", xx_DurationRules); 1583 1584 cannedData.put("zh_CN/SpelloutRules", en_SpelloutRules); 1585 cannedData.put("zh_CN/OrdinalRules", en_OrdinalRules); 1586 cannedData.put("zh_CH/DurationRules", xx_DurationRules); 1587 1588 cannedData.put("zh/SpelloutRules", en_SpelloutRules); 1589 cannedData.put("zh/OrdinalRules", en_OrdinalRules); 1590 cannedData.put("zh_DurationRules", xx_DurationRules); 1591 1592 cannedData.put("en/SpelloutRules", en_SpelloutRules); 1593 cannedData.put("en/OrdinalRules", en_OrdinalRules); 1594 cannedData.put("en/DurationRules", en_DurationRules); 1595 1596 cannedData.put("fr_FR/SpelloutRules", fr_SpelloutRules); 1597 cannedData.put("fr_FR/OrdinalRules", xx_OrdinalRules); 1598 cannedData.put("fr_FR/DurationRules", xx_DurationRules); 1599 1600 cannedData.put("fr/SpelloutRules", fr_SpelloutRules); 1601 cannedData.put("fr/OrdinalRules", xx_OrdinalRules); 1602 cannedData.put("fr/DurationRules", xx_DurationRules); 1603 1604 cannedData.put("de/SpelloutRules", de_SpelloutRules); 1605 cannedData.put("de/OrdinalRules", xx_OrdinalRules); 1606 cannedData.put("de/DurationRules", xx_DurationRules); 1607 1608 cannedData.put("de_DE/SpelloutRules", de_SpelloutRules); 1609 cannedData.put("de_DE/OrdinalRules", xx_OrdinalRules); 1610 cannedData.put("de_DE/DurationRules", xx_DurationRules); 1611 1612 cannedData.put("it/SpelloutRules", it_SpelloutRules); 1613 cannedData.put("it/OrdinalRules", xx_OrdinalRules); 1614 cannedData.put("it/DurationRules", xx_DurationRules); 1615 1616 cannedData.put("it_IT/SpelloutRules", it_SpelloutRules); 1617 cannedData.put("it_IT/OrdinalRules", xx_OrdinalRules); 1618 cannedData.put("it_IT/DuratonRules", xx_DurationRules); 1619 1620 cannedData.put("ko_KR/SpelloutRules", en_SpelloutRules); 1621 cannedData.put("ko_KR/OrdinalRules", en_OrdinalRules); 1622 cannedData.put("ko_KR/DurationRules", en_DurationRules); 1623 1624 cannedData.put("ko/SpelloutRules", en_SpelloutRules); 1625 cannedData.put("ko/OrdinalRules", en_OrdinalRules); 1626 cannedData.put("ko/DurationRules", en_DurationRules); 1627 1628 cannedData.put("zh_Hans_CN/SpelloutRules", en_SpelloutRules); 1629 cannedData.put("zh_Hans_CN/OrdinalRules", en_OrdinalRules); 1630 cannedData.put("zh_Hans_CH/DurationRules", xx_DurationRules); 1631 1632 cannedData.put("zh_Hant_TW/SpelloutRules", en_SpelloutRules); 1633 cannedData.put("zh_Hant_TW/OrdinalRules", en_OrdinalRules); 1634 cannedData.put("zh_Hant_TW/DurationRules", en_DurationRules); 1635 1636 cannedData.put("zh_TW/SpelloutRules", en_SpelloutRules); 1637 cannedData.put("zh_TW/OrdinalRules", en_OrdinalRules); 1638 cannedData.put("zh_TW/DurationRules", en_DurationRules); 1639 1640 cannedData.put("en_GB/SpelloutRules", en_GB_SpelloutRules); 1641 cannedData.put("en_GB/OrdinalRules", en_OrdinalRules); 1642 cannedData.put("en_GB/DurationRules", en_DurationRules); 1643 1644 cannedData.put("en_US/SpelloutRules", en_SpelloutRules); 1645 cannedData.put("en_US/OrdinalRules", en_OrdinalRules); 1646 cannedData.put("en_US/DurationRules", en_DurationRules); 1647 1648 cannedData.put("ja/SpelloutRules", ja_spelloutRules); 1649 cannedData.put("ja/OrdinalRules", xx_OrdinalRules); 1650 cannedData.put("ja/DurationRules", xx_DurationRules); 1651 1652 cannedData.put("ja_JP/SpelloutRules", ja_spelloutRules); 1653 cannedData.put("ja_JP/OrdinalRules", xx_OrdinalRules); 1654 cannedData.put("ja_JP/DurationRules", xx_DurationRules); 1655 } 1656 1657 int types[] = {RuleBasedNumberFormat.SPELLOUT, RuleBasedNumberFormat.ORDINAL, RuleBasedNumberFormat.DURATION}; 1658 String typeNames[] = {"SpelloutRules", "OrdinalRules", "DurationRules"}; 1659 1660 @Override 1661 public Object[] getTestObjects() 1662 { 1663 Locale locales[] = SerializableTestUtility.getLocales(); 1664 RuleBasedNumberFormat formats[] = new RuleBasedNumberFormat[types.length * locales.length]; 1665 int i = 0; 1666 1667 for (int t = 0; t < types.length; t += 1) { 1668 for (int l = 0; l < locales.length; l += 1) { 1669 String cannedRules = (String) cannedData.get(locales[l].toString() + "/" + typeNames[t]); 1670 1671 if (cannedRules != null) { 1672 formats[i++] = new RuleBasedNumberFormat(cannedRules, locales[l]); 1673 } else { 1674 formats[i++] = new RuleBasedNumberFormat(locales[l], types[t]); 1675 } 1676 } 1677 } 1678 1679 return formats; 1680 } 1681 } 1682 1683 public static class DecimalFormatSymbolsHandler implements SerializableTestUtility.Handler 1684 { 1685 @Override 1686 public Object[] getTestObjects() 1687 { 1688 Locale locales[] = SerializableTestUtility.getLocales(); 1689 DecimalFormatSymbols dfs[] = new DecimalFormatSymbols[locales.length]; 1690 1691 for (int i = 0; i < locales.length; i += 1) { 1692 ULocale uloc = ULocale.forLocale(locales[i]); 1693 1694 dfs[i] = getCannedDecimalFormatSymbols(uloc); 1695 1696// System.out.println("\n " + uloc.toString() + " = \"" + 1697// com.ibm.icu.impl.Utility.escape(String.valueOf(getCharSymbols(dfs[i]), 0, 12)) + "\""); 1698 } 1699 1700 return dfs; 1701 } 1702 1703 @Override 1704 public boolean hasSameBehavior(Object a, Object b) 1705 { 1706 DecimalFormatSymbols dfs_a = (DecimalFormatSymbols) a; 1707 DecimalFormatSymbols dfs_b = (DecimalFormatSymbols) b; 1708 String strings_a[] = getStringSymbols(dfs_a); 1709 String strings_b[] = getStringSymbols(dfs_b); 1710 char chars_a[] = getCharSymbols(dfs_a); 1711 char chars_b[] = getCharSymbols(dfs_b); 1712 1713 return SerializableTestUtility.compareStrings(strings_a, strings_b) && SerializableTestUtility.compareChars(chars_a, chars_b); 1714 } 1715 } 1716 1717 public static class CurrencyPluralInfoHandler implements SerializableTestUtility.Handler 1718 { 1719 @Override 1720 public Object[] getTestObjects() 1721 { 1722 CurrencyPluralInfo currencyPluralInfo[] = { 1723 new CurrencyPluralInfo(), new CurrencyPluralInfo(new ULocale("en_US")), 1724 CurrencyPluralInfo.getInstance(), CurrencyPluralInfo.getInstance(new Locale("en_US")), 1725 CurrencyPluralInfo.getInstance(new ULocale("en_US")) 1726 }; 1727 for(int i=0; i<currencyPluralInfo.length; i++){ 1728 currencyPluralInfo[i].setPluralRules("one: n is 1; few: n in 2..4"); 1729 currencyPluralInfo[i].setCurrencyPluralPattern("few", "few currency"); 1730 } 1731 return currencyPluralInfo; 1732 } 1733 1734 @Override 1735 public boolean hasSameBehavior(Object a, Object b) 1736 { 1737 return a.equals(b); 1738 } 1739 } 1740 1741 public static class CompactDecimalFormatHandler extends NumberFormatHandler { 1742 @Override 1743 public Object[] getTestObjects() { 1744 return new CompactDecimalFormat[0]; 1745 } 1746 } 1747 1748 public static class MessageFormatHandler implements SerializableTestUtility.Handler 1749 { 1750 @Override 1751 public Object[] getTestObjects() 1752 { 1753 MessageFormat formats[] = {new MessageFormat("pattern{0}")}; 1754 1755 return formats; 1756 } 1757 1758 @Override 1759 public boolean hasSameBehavior(Object a, Object b) 1760 { 1761 MessageFormat mfa = (MessageFormat) a; 1762 MessageFormat mfb = (MessageFormat) b; 1763 Object arguments[] = {new Integer(123456)}; 1764 1765 return mfa.format(arguments) != mfb.format(arguments); 1766 } 1767 } 1768 1769 public static class MessageFormatFieldHandler implements SerializableTestUtility.Handler 1770 { 1771 @Override 1772 public Object[] getTestObjects() 1773 { 1774 return new Object[] {MessageFormat.Field.ARGUMENT}; 1775 } 1776 1777 @Override 1778 public boolean hasSameBehavior(Object a, Object b) 1779 { 1780 return (a == b); 1781 } 1782 } 1783 1784 public static class DateFormatHandler implements SerializableTestUtility.Handler 1785 { 1786 static HashMap cannedPatterns = new HashMap(); 1787 static Date fixedDate; 1788 1789 { 1790 cannedPatterns.put("en_CA", "EEEE, MMMM d, yyyy h:mm:ss a z"); 1791 cannedPatterns.put("fr_CA", "EEEE d MMMM yyyy HH' h 'mm' min 'ss' s 'z"); 1792 cannedPatterns.put("zh_Hans_CN", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE ahh'\u65F6'mm'\u5206'ss'\u79D2' z"); 1793 cannedPatterns.put("zh_CN", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE ahh'\u65F6'mm'\u5206'ss'\u79D2' z"); 1794 cannedPatterns.put("zh", "EEEE, yyyy MMMM dd HH:mm:ss z"); 1795 cannedPatterns.put("en", "EEEE, MMMM d, yyyy h:mm:ss a z"); 1796 cannedPatterns.put("fr_FR", "EEEE d MMMM yyyy HH' h 'mm z"); 1797 cannedPatterns.put("fr", "EEEE d MMMM yyyy HH' h 'mm z"); 1798 cannedPatterns.put("de", "EEEE, d. MMMM yyyy H:mm' Uhr 'z"); 1799 cannedPatterns.put("de_DE", "EEEE, d. MMMM yyyy H:mm' Uhr 'z"); 1800 cannedPatterns.put("it", "EEEE d MMMM yyyy HH:mm:ss z"); 1801 cannedPatterns.put("it_IT", "EEEE d MMMM yyyy HH:mm:ss z"); 1802 cannedPatterns.put("ja_JP", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE H'\u6642'mm'\u5206'ss'\u79D2'z"); 1803 cannedPatterns.put("ja", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE H'\u6642'mm'\u5206'ss'\u79D2'z"); 1804 cannedPatterns.put("ko_KR", "yyyy'\uB144' M'\uC6D4' d'\uC77C' EEEE a hh'\uC2DC' mm'\uBD84' ss'\uCD08' z"); 1805 cannedPatterns.put("ko", "yyyy'\uB144' M'\uC6D4' d'\uC77C' EEEE a hh'\uC2DC' mm'\uBD84' ss'\uCD08' z"); 1806 cannedPatterns.put("zh_Hant_TW", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE ahh'\u6642'mm'\u5206'ss'\u79D2' z"); 1807 cannedPatterns.put("zh_TW", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE ahh'\u6642'mm'\u5206'ss'\u79D2' z"); 1808 cannedPatterns.put("en_GB", "EEEE, d MMMM yyyy HH:mm:ss z"); 1809 cannedPatterns.put("en_US", "EEEE, MMMM d, yyyy h:mm:ss a z"); 1810 1811 // Get a date that will likely not move in or out of Daylight savings time... 1812 Calendar cal = Calendar.getInstance(Locale.US); 1813 1814 cal.clear(); 1815 cal.set(2007, Calendar.JANUARY, 1, 12, 0, 0); // January 1, 2007 12:00:00 PM. 1816 fixedDate = cal.getTime(); 1817 } 1818 1819 @Override 1820 public Object[] getTestObjects() 1821 { 1822 Locale locales[] = SerializableTestUtility.getLocales(); 1823 DateFormat formats[] = new DateFormat[locales.length]; 1824 1825 for (int i = 0; i < locales.length; i += 1) { 1826 ULocale uloc = ULocale.forLocale(locales[i]); 1827 1828 //formats[i] = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locales[i]); 1829 formats[i] = getCannedSimpleDateFormat((String)cannedPatterns.get(uloc.toString()), uloc); 1830 } 1831 1832 return formats; 1833 } 1834 1835 @Override 1836 public boolean hasSameBehavior(Object a, Object b) 1837 { 1838 DateFormat dfa = (DateFormat) a; 1839 DateFormat dfb = (DateFormat) b; 1840 1841 // We previously did not use 'canned' time zone. 1842 TimeZone tza = dfa.getTimeZone(); 1843 TimeZone tzb = dfb.getTimeZone(); 1844 if (!tza.getID().equals(tzb.getID())) { 1845 // If IDs do not match, reset TimeZone in dfa. 1846 dfa.setTimeZone(tzb); 1847 } 1848 1849 String sfa = dfa.format(fixedDate); 1850 String sfb = dfb.format(fixedDate); 1851 1852 if (!sfa.equals(sfb)) { 1853 // TODO 1854 // In ICU3.8, localized GMT format pattern was added in 1855 // DateFormatSymbols, which has no public setter. 1856 // The difference of locale data for localized GMT format 1857 // will produce different format result. This is a temporary 1858 // workaround for the issue. 1859 DateFormatSymbols dfsa = ((SimpleDateFormat)dfa).getDateFormatSymbols(); 1860 DateFormatSymbols tmp = (DateFormatSymbols)((SimpleDateFormat)dfb).getDateFormatSymbols().clone(); 1861 1862 TimeZoneFormat tmptzf = (TimeZoneFormat)((SimpleDateFormat)dfb).getTimeZoneFormat().clone(); 1863 1864 tmp.setMonths(dfsa.getMonths()); 1865 tmp.setShortMonths(dfsa.getShortMonths()); 1866 tmp.setWeekdays(dfsa.getWeekdays()); 1867 tmp.setShortWeekdays(dfsa.getShortWeekdays()); 1868 tmp.setAmPmStrings(dfsa.getAmPmStrings()); 1869 1870 ((SimpleDateFormat)dfa).setDateFormatSymbols(tmp); 1871 ((SimpleDateFormat)dfa).setTimeZoneFormat(tmptzf); 1872 1873 sfa = dfa.format(fixedDate); 1874 } 1875 1876 //return sfa.equals(sfb); 1877 if (!sfa.equals(sfb)) { 1878 return false; 1879 } 1880 return true; 1881 } 1882 1883 } 1884 1885 public static class DateFormatFieldHandler implements SerializableTestUtility.Handler 1886 { 1887 @Override 1888 public Object[] getTestObjects() { 1889 return new Object[] { 1890 DateFormat.Field.AM_PM, 1891 DateFormat.Field.DAY_OF_MONTH, 1892 DateFormat.Field.DAY_OF_WEEK, 1893 DateFormat.Field.DAY_OF_WEEK_IN_MONTH, 1894 DateFormat.Field.DAY_OF_YEAR, 1895 DateFormat.Field.ERA, 1896 DateFormat.Field.HOUR_OF_DAY0, 1897 DateFormat.Field.HOUR_OF_DAY1, 1898 DateFormat.Field.HOUR0, 1899 DateFormat.Field.HOUR1, 1900 DateFormat.Field.MILLISECOND, 1901 DateFormat.Field.MINUTE, 1902 DateFormat.Field.MONTH, 1903 DateFormat.Field.SECOND, 1904 DateFormat.Field.TIME_ZONE, 1905 DateFormat.Field.WEEK_OF_MONTH, 1906 DateFormat.Field.WEEK_OF_YEAR, 1907 DateFormat.Field.YEAR, 1908 DateFormat.Field.DOW_LOCAL, 1909 DateFormat.Field.EXTENDED_YEAR, 1910 DateFormat.Field.JULIAN_DAY, 1911 DateFormat.Field.MILLISECONDS_IN_DAY, 1912 DateFormat.Field.YEAR_WOY, 1913 DateFormat.Field.QUARTER 1914 }; 1915 } 1916 @Override 1917 public boolean hasSameBehavior(Object a, Object b) 1918 { 1919 return (a == b); 1920 } 1921 } 1922 1923 public static class DateFormatSymbolsHandler implements SerializableTestUtility.Handler 1924 { 1925 1926 @Override 1927 public Object[] getTestObjects() 1928 { 1929 Locale locales[] = SerializableTestUtility.getLocales(); 1930 DateFormatSymbols dfs[] = new DateFormatSymbols[locales.length]; 1931 1932 for (int i = 0; i < locales.length; i += 1) { 1933 ULocale uloc = ULocale.forLocale(locales[i]); 1934 1935 dfs[i] = getCannedDateFormatSymbols(uloc); 1936 } 1937 1938 return dfs; 1939 } 1940 1941 @Override 1942 public boolean hasSameBehavior(Object a, Object b) 1943 { 1944 DateFormatSymbols dfs_a = (DateFormatSymbols) a; 1945 DateFormatSymbols dfs_b = (DateFormatSymbols) b; 1946 String months_a[] = dfs_a.getMonths(); 1947 String months_b[] = dfs_b.getMonths(); 1948 1949 return SerializableTestUtility.compareStrings(months_a, months_b); 1950 } 1951 } 1952 1953 public static class SimpleDateFormatHandler extends DateFormatHandler 1954 { 1955 String patterns[] = { 1956 "EEEE, yyyy MMMM dd", 1957 "yyyy MMMM d", 1958 "yyyy MMM d", 1959 "yy/MM/dd" 1960 }; 1961 1962 @Override 1963 public Object[] getTestObjects() 1964 { 1965 Locale locales[] = SerializableTestUtility.getLocales(); 1966 SimpleDateFormat dateFormats[] = new SimpleDateFormat[patterns.length * locales.length]; 1967 int i = 0; 1968 1969 for (int p = 0; p < patterns.length; p += 1) { 1970 for (int l = 0; l < locales.length; l += 1) { 1971 dateFormats[i++] = getCannedSimpleDateFormat(patterns[p], ULocale.forLocale(locales[l])); 1972 } 1973 } 1974 1975 return dateFormats; 1976 } 1977 } 1978 1979 public static class DateIntervalFormatHandler implements SerializableTestUtility.Handler 1980 { 1981 @Override 1982 public Object[] getTestObjects() 1983 { 1984 DateIntervalFormat dateIntervalFormats[] = { 1985 DateIntervalFormat.getInstance("yMMMMEEEEd") 1986 }; 1987 return dateIntervalFormats; 1988 } 1989 1990 @Override 1991 public boolean hasSameBehavior(Object a, Object b) 1992 { 1993 DateIntervalFormat dfa = (DateIntervalFormat) a; 1994 DateIntervalFormat dfb = (DateIntervalFormat) b; 1995 DateInterval dateInterval = new DateInterval(1, System.currentTimeMillis()); 1996 String sfa = dfa.format(dateInterval); 1997 String sfb = dfb.format(dateInterval); 1998 1999 return sfa.equals(sfb); 2000 } 2001 } 2002 2003 2004 public static class DateIntervalInfoHandler implements SerializableTestUtility.Handler 2005 { 2006 @Override 2007 public Object[] getTestObjects() 2008 { 2009 DateIntervalInfo dateIntervalInfo[] = { 2010 new DateIntervalInfo() 2011 }; 2012 dateIntervalInfo[0].setIntervalPattern("yMd", Calendar.YEAR, "yy/MM/dd - yy/MM/dd"); 2013 dateIntervalInfo[0].setIntervalPattern("yMd", Calendar.MONTH, "yy/MM - MM/dd"); 2014 return dateIntervalInfo; 2015 } 2016 2017 @Override 2018 public boolean hasSameBehavior(Object a, Object b) 2019 { 2020 return a.equals(b); 2021 } 2022 } 2023 2024 2025 public static class PatternInfoHandler implements SerializableTestUtility.Handler 2026 { 2027 @Override 2028 public Object[] getTestObjects() 2029 { 2030 DateIntervalInfo.PatternInfo patternInfo[] = { 2031 new DateIntervalInfo.PatternInfo("yyyy MMM dd - ", 2032 "dd", 2033 false) 2034 }; 2035 return patternInfo; 2036 } 2037 2038 @Override 2039 public boolean hasSameBehavior(Object a, Object b) 2040 { 2041 return a.equals(b); 2042 } 2043 } 2044 2045 public static class ChineseDateFormatHandler extends DateFormatHandler 2046 { 2047 String patterns[] = { 2048 "EEEE y'x'G-Ml-d", 2049 "y'x'G-Ml-d", 2050 "y'x'G-Ml-d", 2051 "y'x'G-Ml-d" 2052 }; 2053 2054 @Override 2055 public Object[] getTestObjects() 2056 { 2057 Locale locales[] = SerializableTestUtility.getLocales(); 2058 ChineseDateFormat dateFormats[] = new ChineseDateFormat[patterns.length * locales.length]; 2059 int i = 0; 2060 2061 for (int p = 0; p < patterns.length; p += 1) { 2062 for (int l = 0; l < locales.length; l += 1) { 2063 ULocale locale = new ULocale(locales[l].toString() + "@calendar=chinese"); 2064 2065 dateFormats[i++] = new ChineseDateFormat(patterns[p], locale); 2066 } 2067 } 2068 2069 return dateFormats; 2070 } 2071 } 2072 2073 public static class ChineseDateFormatFieldHandler implements SerializableTestUtility.Handler 2074 { 2075 @Override 2076 public Object[] getTestObjects() { 2077 return new Object[] { 2078 ChineseDateFormat.Field.IS_LEAP_MONTH 2079 }; 2080 } 2081 @Override 2082 public boolean hasSameBehavior(Object a, Object b) 2083 { 2084 return (a == b); 2085 } 2086 } 2087 2088 public static class ChineseDateFormatSymbolsHandler extends DateFormatSymbolsHandler 2089 { 2090 @Override 2091 public Object[] getTestObjects() 2092 { 2093 Locale locales[] = SerializableTestUtility.getLocales(); 2094 ChineseDateFormatSymbols cdfs[] = new ChineseDateFormatSymbols[locales.length]; 2095 2096 for (int i = 0; i < locales.length; i += 1) { 2097 ULocale uloc = ULocale.forLocale(locales[i]); 2098 2099 cdfs[i] = new ChineseDateFormatSymbols(uloc); 2100 cdfs[i].setMonths((String[]) cannedMonthNames.get(uloc.toString())); 2101 } 2102 2103 return cdfs; 2104 } 2105 2106 @Override 2107 public boolean hasSameBehavior(Object a, Object b) 2108 { 2109 if (! super.hasSameBehavior(a, b)) { 2110 return false; 2111 } 2112 2113 ChineseDateFormatSymbols cdfs_a = (ChineseDateFormatSymbols) a; 2114 ChineseDateFormatSymbols cdfs_b = (ChineseDateFormatSymbols) b; 2115 2116 // The old test did this, which tested that the leap month marker never 2117 // changed from one ICU version to the next; this is not a valid test. 2118 //return cdfs_a.getLeapMonth(0).equals(cdfs_b.getLeapMonth(0)) && 2119 // cdfs_a.getLeapMonth(1).equals(cdfs_b.getLeapMonth(1)); 2120 // 2121 // A more valid test is that from one version to the next, the 2122 // marker for getLeapMonth(0) does not change and is empty, while 2123 // the marker for getLeapMonth(1) is non-empty in both versions: 2124 return cdfs_a.getLeapMonth(0).equals(cdfs_b.getLeapMonth(0)) && 2125 cdfs_a.getLeapMonth(0).length() == 0 && 2126 cdfs_a.getLeapMonth(1).length() > 0 && 2127 cdfs_b.getLeapMonth(1).length() > 0; 2128 } 2129 } 2130 2131 public static class NumberFormatFieldHandler implements SerializableTestUtility.Handler 2132 { 2133 @Override 2134 public Object[] getTestObjects() 2135 { 2136 NumberFormat.Field fields[] = { 2137 NumberFormat.Field.CURRENCY, NumberFormat.Field.DECIMAL_SEPARATOR, NumberFormat.Field.EXPONENT, 2138 NumberFormat.Field.EXPONENT_SIGN, NumberFormat.Field.EXPONENT_SYMBOL, NumberFormat.Field.FRACTION, 2139 NumberFormat.Field.GROUPING_SEPARATOR, NumberFormat.Field.INTEGER, NumberFormat.Field.PERCENT, 2140 NumberFormat.Field.PERMILLE, NumberFormat.Field.SIGN 2141 }; 2142 2143 return fields; 2144 } 2145 2146 @Override 2147 public boolean hasSameBehavior(Object a, Object b) 2148 { 2149 NumberFormat.Field field_a = (NumberFormat.Field) a; 2150 NumberFormat.Field field_b = (NumberFormat.Field) b; 2151 2152 return field_a.toString().equals(field_b.toString()); 2153 } 2154 } 2155 2156 public static class DateNumberFormatHandler implements SerializableTestUtility.Handler 2157 { 2158 @Override 2159 public Object[] getTestObjects() 2160 { 2161 Locale locales[] = SerializableTestUtility.getLocales(); 2162 DateNumberFormat[] dnfmts = new DateNumberFormat[locales.length]; 2163 for (int i = 0; i < locales.length; i++) { 2164 ULocale uloc = ULocale.forLocale(locales[i]); 2165 dnfmts[i] = new DateNumberFormat(uloc,'0',"latn"); 2166 } 2167 return dnfmts; 2168 } 2169 2170 @Override 2171 public boolean hasSameBehavior(Object a, Object b) { 2172 return a.equals(b); 2173 } 2174 } 2175 2176 public static class SelectFormatHandler implements SerializableTestUtility.Handler { 2177 2178 @Override 2179 public Object[] getTestObjects() { 2180 SelectFormat[] selfmts = {new SelectFormat("keyword{phrase} other{otherPhrase}")}; 2181 2182 return selfmts; 2183 } 2184 2185 @Override 2186 public boolean hasSameBehavior(Object a, Object b) { 2187 SelectFormat sfa = (SelectFormat) a; 2188 SelectFormat sfb = (SelectFormat) b; 2189 String argument = "keyword"; 2190 2191 return sfa.format(argument) != sfb.format(argument); 2192 } 2193 } 2194 2195 public static class PluralFormatHandler implements SerializableTestUtility.Handler { 2196 @Override 2197 public Object[] getTestObjects() { 2198 Locale[] locales = { Locale.US }; // main test is in plural rules handler 2199 PluralFormat[] plfmts = new PluralFormat[locales.length]; 2200 for (int i = 0; i < locales.length; i++) { 2201 ULocale uloc = ULocale.forLocale(locales[i]); 2202 try { 2203 plfmts[i] = new PluralFormat(uloc, "one{1 foo} other{# foo}"); 2204 } catch (Exception e) { 2205 e.printStackTrace(); 2206 } 2207 } 2208 return plfmts; 2209 } 2210 @Override 2211 public boolean hasSameBehavior(Object a, Object b) { 2212 PluralFormat pfa = (PluralFormat)a; 2213 PluralFormat pfb = (PluralFormat)b; 2214 boolean isSame = true; 2215 for (int i = 0; i < 10; i++) { 2216 String texta = pfa.format(i); 2217 String textb = pfb.format(i); 2218 if (!texta.equals(textb)) { 2219 isSame = false; 2220 break; 2221 } 2222 } 2223 return isSame; 2224 } 2225 } 2226 2227 public static class PluralRulesHandler implements SerializableTestUtility.Handler { 2228 // canned rules as of 4.2 2229 final String[] cannedRules = { 2230 "", // ja 2231 "one: n is 1", // da 2232 "one: n within 0..2 and n is not 2", // fr 2233 "one: n mod 10 is 1 and n mod 100 is not 11; zero: n is 0", // lv 2234 "one: n is 1; two: n is 2", // ga 2235 "few: n is 0 OR n is not 1 AND n mod 100 in 1..19; one: n is 1", // ro 2236 "few: n mod 10 in 2..9 and n mod 100 not in 11..19; one: n mod 10 is 1 and n mod 100 not in 11..19", // lt 2237 "few: n mod 10 in 2..4 and n mod 100 not in 12..14; many: n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14; one: n mod 10 is 1 and n mod 100 is not 11", // hr 2238 "few: n in 2..4; one: n is 1", // cs 2239 "few: n mod 10 in 2..4 and n mod 100 not in 12..14 and n mod 100 not in 22..24; one: n is 1", // pl 2240 "few: n mod 100 in 3..4; one: n mod 100 is 1; two: n mod 100 is 2", // sl 2241 }; 2242 2243 @Override 2244 public Object[] getTestObjects() { 2245 PluralRules[] plrulz = new PluralRules[cannedRules.length]; 2246 for (int i = 0; i < cannedRules.length; i++) { 2247 try { 2248 plrulz[i] = PluralRules.parseDescription(cannedRules[i]); 2249 } catch (Exception e) { 2250 e.printStackTrace(); 2251 } 2252 } 2253 return plrulz; 2254 } 2255 @Override 2256 public boolean hasSameBehavior(Object a, Object b) { 2257 return a.equals(b); 2258 } 2259 } 2260 2261 public static class PluralRulesSerialProxyHandler implements SerializableTestUtility.Handler { 2262 // Tested through PluralRules, so just a stub here to keep CoverageTest happy 2263 final String[] cannedRules = {}; 2264 2265 @Override 2266 public Object[] getTestObjects() { 2267 return new PluralRules[cannedRules.length]; 2268 } 2269 @Override 2270 public boolean hasSameBehavior(Object a, Object b) { 2271 return a.equals(b); 2272 } 2273 } 2274 2275 2276 2277 public static class TimeUnitFormatHandler implements SerializableTestUtility.Handler { 2278 // TODO - more test coverage! 2279 @Override 2280 public Object[] getTestObjects() { 2281 return new Object[] { new TimeUnitFormat().setLocale(ULocale.ENGLISH) }; 2282 } 2283 @Override 2284 public boolean hasSameBehavior(Object a, Object b) { 2285 TimeUnitFormat tufa = (TimeUnitFormat)a; 2286 TimeUnitFormat tufb = (TimeUnitFormat)b; 2287 2288 TimeUnitAmount amount = new TimeUnitAmount(3, TimeUnit.HOUR); 2289 String resa = tufa.format(amount); 2290 String resb = tufb.format(amount); 2291 2292 return resa.equals(resb); 2293 } 2294 } 2295 2296 public static class TimeZoneNamesHandler implements SerializableTestUtility.Handler { 2297 @Override 2298 public Object[] getTestObjects() { 2299 return new Object[] { 2300 TimeZoneNames.getInstance(ULocale.ENGLISH), 2301 TimeZoneNames.getInstance(ULocale.JAPAN) 2302 }; 2303 } 2304 @Override 2305 public boolean hasSameBehavior(Object a, Object b) { 2306 TimeZoneNames tzna = (TimeZoneNames)a; 2307 TimeZoneNames tznb = (TimeZoneNames)b; 2308 2309 final String tzid = "America/Los_Angeles"; 2310 2311 String eca = tzna.getExemplarLocationName(tzid); 2312 String ecb = tznb.getExemplarLocationName(tzid); 2313 2314 if (!eca.equals(ecb)) { 2315 return false; 2316 } 2317 2318 final String mzID = "America_Pacific"; 2319 final String region = "US"; 2320 2321 String refza = tzna.getReferenceZoneID(mzID, region); 2322 String refzb = tznb.getReferenceZoneID(mzID, region); 2323 2324 if (!refza.equals(refzb)) { 2325 return false; 2326 } 2327 2328 return true; 2329 } 2330 } 2331 2332 public static class TimeZoneGenericNamesHandler implements SerializableTestUtility.Handler { 2333 @Override 2334 public Object[] getTestObjects() { 2335 return new Object[] { 2336 TimeZoneGenericNames.getInstance(ULocale.ENGLISH), 2337 TimeZoneGenericNames.getInstance(ULocale.JAPAN) 2338 }; 2339 } 2340 @Override 2341 public boolean hasSameBehavior(Object a, Object b) { 2342 TimeZoneGenericNames tzgna = (TimeZoneGenericNames)a; 2343 TimeZoneGenericNames tzgnb = (TimeZoneGenericNames)b; 2344 2345 final String[] TZIDS = { 2346 "America/Los_Angeles", 2347 "America/Argentina/Buenos_Aires", 2348 "Etc/GMT" 2349 }; 2350 2351 final long[] DATES = { 2352 1277942400000L, // 2010-07-01 00:00:00 GMT 2353 1293840000000L, // 2011-01-01 00:00:00 GMT 2354 }; 2355 2356 for (String tzid : TZIDS) { 2357 TimeZone tz = TimeZone.getTimeZone(tzid); 2358 for (GenericNameType nt : GenericNameType.values()) { 2359 for (long date : DATES) { 2360 String nameA = tzgna.getDisplayName(tz, nt, date); 2361 String nameB = tzgnb.getDisplayName(tz, nt, date); 2362 if (!Utility.objectEquals(nameA, nameB)) { 2363 return false; 2364 } 2365 } 2366 } 2367 } 2368 2369 return true; 2370 } 2371 } 2372 2373 public static class TZDBTimeZoneNamesHandler implements SerializableTestUtility.Handler { 2374 @Override 2375 public Object[] getTestObjects() { 2376 return new Object[] { 2377 TimeZoneNames.getTZDBInstance(ULocale.ENGLISH), 2378 TimeZoneNames.getTZDBInstance(ULocale.JAPAN) 2379 }; 2380 } 2381 @Override 2382 public boolean hasSameBehavior(Object a, Object b) { 2383 TZDBTimeZoneNames tzdbna = (TZDBTimeZoneNames)a; 2384 TZDBTimeZoneNames tzdbnb = (TZDBTimeZoneNames)b; 2385 2386 final String[] TZIDS = { 2387 "America/Los_Angeles", 2388 "America/Argentina/Buenos_Aires", 2389 "Asia/Shanghai", 2390 "Etc/GMT" 2391 }; 2392 2393 final long[] DATES = { 2394 1277942400000L, // 2010-07-01 00:00:00 GMT 2395 1293840000000L, // 2011-01-01 00:00:00 GMT 2396 }; 2397 2398 final NameType[] nTypes = { 2399 NameType.SHORT_STANDARD, 2400 NameType.SHORT_DAYLIGHT 2401 }; 2402 2403 for (String tzid : TZIDS) { 2404 for (NameType nt : nTypes) { 2405 for (long date : DATES) { 2406 String nameA = tzdbna.getDisplayName(tzid, nt, date); 2407 String nameB = tzdbnb.getDisplayName(tzid, nt, date); 2408 if (!Utility.objectEquals(nameA, nameB)) { 2409 return false; 2410 } 2411 } 2412 } 2413 } 2414 2415 return true; 2416 } 2417 } 2418 2419 public static class TimeZoneFormatHandler implements SerializableTestUtility.Handler { 2420 static final String CUSTOM_GMT_PATTERN = "Offset {0} from UTC"; 2421 2422 @Override 2423 public Object[] getTestObjects() { 2424 TimeZoneFormat tzfmt = TimeZoneFormat.getInstance(ULocale.ENGLISH).cloneAsThawed(); 2425 tzfmt.setGMTPattern(CUSTOM_GMT_PATTERN); 2426 2427 return new Object[] {tzfmt}; 2428 } 2429 @Override 2430 public boolean hasSameBehavior(Object a, Object b) { 2431 TimeZoneFormat tzfa = (TimeZoneFormat)a; 2432 TimeZoneFormat tzfb = (TimeZoneFormat)b; 2433 2434 if (!tzfa.getGMTPattern().equals(tzfb.getGMTPattern())) { 2435 return false; 2436 } 2437 2438 final int offset = -5 * 60 * 60 * 1000; 2439 2440 String gmta = tzfa.formatOffsetLocalizedGMT(offset); 2441 String gmtb = tzfb.formatOffsetLocalizedGMT(offset); 2442 2443 if (!gmta.equals(gmtb)) { 2444 return false; 2445 } 2446 2447 long now = System.currentTimeMillis(); 2448 TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); 2449 2450 String genloca = tzfa.format(Style.GENERIC_LOCATION, tz, now); 2451 String genlocb = tzfb.format(Style.GENERIC_LOCATION, tz, now); 2452 2453 if (!genloca.equals(genlocb)) { 2454 return false; 2455 } 2456 2457 return true; 2458 } 2459 } 2460 2461 public static void main(String[] args) 2462 { 2463 // nothing needed... 2464 } 2465 2466} 2467//eof 2468