2 *******************************************************************************
\r
3 * Copyright (c) 2004-2010, International Business Machines
\r
4 * Corporation and others. All Rights Reserved.
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.dev.test.serializable;
\r
10 import java.text.AttributedCharacterIterator;
\r
11 import java.util.Date;
\r
12 import java.util.HashMap;
\r
13 import java.util.Locale;
\r
15 import com.ibm.icu.impl.DateNumberFormat;
\r
16 import com.ibm.icu.text.ChineseDateFormat;
\r
17 import com.ibm.icu.text.ChineseDateFormatSymbols;
\r
18 import com.ibm.icu.text.CurrencyPluralInfo;
\r
19 import com.ibm.icu.text.DateFormat;
\r
20 import com.ibm.icu.text.DateFormatSymbols;
\r
21 import com.ibm.icu.text.DateIntervalFormat;
\r
22 import com.ibm.icu.text.DateIntervalInfo;
\r
23 import com.ibm.icu.text.DecimalFormat;
\r
24 import com.ibm.icu.text.DecimalFormatSymbols;
\r
25 import com.ibm.icu.text.DurationFormat;
\r
26 import com.ibm.icu.text.MessageFormat;
\r
27 import com.ibm.icu.text.NumberFormat;
\r
28 import com.ibm.icu.text.PluralFormat;
\r
29 import com.ibm.icu.text.PluralRules;
\r
30 import com.ibm.icu.text.RuleBasedNumberFormat;
\r
31 import com.ibm.icu.text.SelectFormat;
\r
32 import com.ibm.icu.text.SimpleDateFormat;
\r
33 import com.ibm.icu.text.TimeUnitFormat;
\r
34 import com.ibm.icu.util.Calendar;
\r
35 import com.ibm.icu.util.DateInterval;
\r
36 import com.ibm.icu.util.GregorianCalendar;
\r
37 import com.ibm.icu.util.TimeUnit;
\r
38 import com.ibm.icu.util.TimeUnitAmount;
\r
39 import com.ibm.icu.util.ULocale;
\r
44 * TODO To change the template for this generated type comment go to
\r
45 * Window - Preferences - Java - Code Style - Code Templates
\r
47 public class FormatTests
\r
50 * The serialized form of a normally created DateFormatSymbols object
\r
51 * will have locale-specific data in it that might change from one version
\r
52 * of ICU4J to another. To guard against this, we store the following canned
\r
53 * data into the test objects we create.
\r
55 static HashMap cannedMonthNames = new HashMap();
\r
56 static HashMap cannedShortMonthNames = new HashMap();
\r
58 static String en_CA_MonthNames[] = {
\r
73 static String fr_CA_MonthNames[] = {
\r
88 static String zh_Hans_CN_MonthNames[] = {
\r
99 "\u5341\u4E00\u6708",
\r
100 "\u5341\u4E8C\u6708",
\r
103 static String zh_CN_MonthNames[] = {
\r
114 "\u5341\u4E00\u6708",
\r
115 "\u5341\u4E8C\u6708",
\r
118 static String zh_MonthNames[] = {
\r
129 "\u5341\u4E00\u6708",
\r
130 "\u5341\u4E8C\u6708",
\r
133 static String en_MonthNames[] = {
\r
148 static String fr_FR_MonthNames[] = {
\r
163 static String fr_MonthNames[] = {
\r
178 static String de_MonthNames[] = {
\r
193 static String de_DE_MonthNames[] = {
\r
208 static String it_MonthNames[] = {
\r
223 static String it_IT_MonthNames[] = {
\r
238 static String ja_JP_MonthNames[] = {
\r
253 static String ja_MonthNames[] = {
\r
268 static String ko_KR_MonthNames[] = {
\r
283 static String ko_MonthNames[] = {
\r
298 static String zh_Hant_TW_MonthNames[] = {
\r
309 "\u5341\u4E00\u6708",
\r
310 "\u5341\u4E8C\u6708",
\r
313 static String zh_TW_MonthNames[] = {
\r
324 "\u5341\u4E00\u6708",
\r
325 "\u5341\u4E8C\u6708",
\r
328 static String en_GB_MonthNames[] = {
\r
343 static String en_US_MonthNames[] = {
\r
358 static String en_CA_ShortMonthNames[] = {
\r
373 static String fr_CA_ShortMonthNames[] = {
\r
388 static String zh_Hans_CN_ShortMonthNames[] = {
\r
399 "\u5341\u4E00\u6708",
\r
400 "\u5341\u4E8C\u6708",
\r
403 static String zh_CN_ShortMonthNames[] = {
\r
414 "\u5341\u4E00\u6708",
\r
415 "\u5341\u4E8C\u6708",
\r
418 static String zh_ShortMonthNames[] = {
\r
429 "\u5341\u4E00\u6708",
\r
430 "\u5341\u4E8C\u6708",
\r
433 static String en_ShortMonthNames[] = {
\r
448 static String fr_FR_ShortMonthNames[] = {
\r
463 static String fr_ShortMonthNames[] = {
\r
478 static String de_ShortMonthNames[] = {
\r
493 static String de_DE_ShortMonthNames[] = {
\r
508 static String it_ShortMonthNames[] = {
\r
523 static String it_IT_ShortMonthNames[] = {
\r
538 static String ja_JP_ShortMonthNames[] = {
\r
553 static String ja_ShortMonthNames[] = {
\r
568 static String ko_KR_ShortMonthNames[] = {
\r
583 static String ko_ShortMonthNames[] = {
\r
598 static String zh_Hant_TW_ShortMonthNames[] = {
\r
609 "\u5341\u4E00\u6708",
\r
610 "\u5341\u4E8C\u6708",
\r
613 static String zh_TW_ShortMonthNames[] = {
\r
624 "\u5341\u4E00\u6708",
\r
625 "\u5341\u4E8C\u6708",
\r
628 static String en_GB_ShortMonthNames[] = {
\r
643 static String en_US_ShortMonthNames[] = {
\r
659 cannedMonthNames.put("en_CA", en_CA_MonthNames);
\r
660 cannedMonthNames.put("fr_CA", fr_CA_MonthNames);
\r
661 cannedMonthNames.put("zh_Hans_CN", zh_Hans_CN_MonthNames);
\r
662 cannedMonthNames.put("zh_CN", zh_CN_MonthNames);
\r
663 cannedMonthNames.put("zh", zh_MonthNames);
\r
664 cannedMonthNames.put("en", en_MonthNames);
\r
665 cannedMonthNames.put("fr_FR", fr_FR_MonthNames);
\r
666 cannedMonthNames.put("fr", fr_MonthNames);
\r
667 cannedMonthNames.put("de", de_MonthNames);
\r
668 cannedMonthNames.put("de_DE", de_DE_MonthNames);
\r
669 cannedMonthNames.put("it", it_MonthNames);
\r
670 cannedMonthNames.put("it_IT", it_IT_MonthNames);
\r
671 cannedMonthNames.put("ja_JP", ja_JP_MonthNames);
\r
672 cannedMonthNames.put("ja", ja_MonthNames);
\r
673 cannedMonthNames.put("ko_KR", ko_KR_MonthNames);
\r
674 cannedMonthNames.put("ko", ko_MonthNames);
\r
675 cannedMonthNames.put("zh_Hant_TW", zh_Hant_TW_MonthNames);
\r
676 cannedMonthNames.put("zh_TW", zh_TW_MonthNames);
\r
677 cannedMonthNames.put("en_GB", en_GB_MonthNames);
\r
678 cannedMonthNames.put("en_US", en_US_MonthNames);
\r
680 cannedShortMonthNames.put("en_CA", en_CA_ShortMonthNames);
\r
681 cannedShortMonthNames.put("fr_CA", fr_CA_ShortMonthNames);
\r
682 cannedShortMonthNames.put("zh_Hans_CN", zh_Hans_CN_ShortMonthNames);
\r
683 cannedShortMonthNames.put("zh_CN", zh_CN_ShortMonthNames);
\r
684 cannedShortMonthNames.put("zh", zh_ShortMonthNames);
\r
685 cannedShortMonthNames.put("en", en_ShortMonthNames);
\r
686 cannedShortMonthNames.put("fr_FR", fr_FR_ShortMonthNames);
\r
687 cannedShortMonthNames.put("fr", fr_ShortMonthNames);
\r
688 cannedShortMonthNames.put("de", de_ShortMonthNames);
\r
689 cannedShortMonthNames.put("de_DE", de_DE_ShortMonthNames);
\r
690 cannedShortMonthNames.put("it", it_ShortMonthNames);
\r
691 cannedShortMonthNames.put("it_IT", it_IT_ShortMonthNames);
\r
692 cannedShortMonthNames.put("ja_JP", ja_JP_ShortMonthNames);
\r
693 cannedShortMonthNames.put("ja", ja_ShortMonthNames);
\r
694 cannedShortMonthNames.put("ko_KR", ko_KR_ShortMonthNames);
\r
695 cannedShortMonthNames.put("ko", ko_ShortMonthNames);
\r
696 cannedShortMonthNames.put("zh_Hant_TW", zh_Hant_TW_ShortMonthNames);
\r
697 cannedShortMonthNames.put("zh_TW", zh_TW_ShortMonthNames);
\r
698 cannedShortMonthNames.put("en_GB", en_GB_ShortMonthNames);
\r
699 cannedShortMonthNames.put("en_US", en_US_ShortMonthNames);
\r
702 private static DateFormatSymbols getCannedDateFormatSymbols(ULocale uloc)
\r
704 DateFormatSymbols dfs =new DateFormatSymbols(GregorianCalendar.class, uloc);
\r
705 String key = uloc.toString();
\r
707 dfs.setMonths((String[]) cannedMonthNames.get(key));
\r
708 dfs.setShortMonths((String[]) cannedShortMonthNames.get(key));
\r
713 private static SimpleDateFormat getCannedSimpleDateFormat(String pattern, ULocale uloc)
\r
715 DateFormatSymbols dfs = getCannedDateFormatSymbols(uloc);
\r
717 return new SimpleDateFormat(pattern, dfs, uloc);
\r
721 * The serialized form of a normally created DecimalFormatSymbols object
\r
722 * will have locale-specific data in it that might change from one version
\r
723 * of ICU4J to another. To guard against this, we store the following canned
\r
724 * data into the test objects we create.
\r
726 static HashMap cannedDecimalFormatSymbols = new HashMap();
\r
728 static String en_CA_StringSymbols[] = {
\r
734 ".#,-.*;%\u2030+@0"
\r
737 static String fr_CA_StringSymbols[] = {
\r
743 ",#\u00A0-,*;%\u2030+@0"
\r
746 static String zh_CN_StringSymbols[] = {
\r
752 ".#,-.*;%\u2030+@0"
\r
755 static String zh_StringSymbols[] = {
\r
761 ".#,-.*;%\u2030+@0"
\r
764 static String en_StringSymbols[] = {
\r
770 ".#,-.*;%\u2030+@0"
\r
773 static String fr_FR_StringSymbols[] = {
\r
779 ",#\u00A0-,*;%\u2030+@0"
\r
782 static String fr_StringSymbols[] = {
\r
788 ",#\u00A0-,*;%\u2030+@0"
\r
791 static String de_StringSymbols[] = {
\r
797 ",#.-,*;%\u2030+@0"
\r
800 static String de_DE_StringSymbols[] = {
\r
806 ",#.-,*;%\u2030+@0"
\r
809 static String it_StringSymbols[] = {
\r
815 ",#.-,*;%\u2030+@0"
\r
818 static String it_IT_StringSymbols[] = {
\r
824 ",#.-,*;%\u2030+@0"
\r
827 static String ja_JP_StringSymbols[] = {
\r
833 ".#,-.*;%\u2030+@0"
\r
836 static String ja_StringSymbols[] = {
\r
842 ".#,-.*;%\u2030+@0"
\r
845 static String ko_KR_StringSymbols[] = {
\r
851 ".#,-.*;%\u2030+@0"
\r
854 static String ko_StringSymbols[] = {
\r
860 ".#,-.*;%\u2030+@0"
\r
863 static String zh_Hans_CN_StringSymbols[] = {
\r
869 ".#,-.*;%\u2030+@0"
\r
872 static String zh_Hant_TW_StringSymbols[] = {
\r
878 ".#,-.*;%\u2030+@0"
\r
881 static String zh_TW_StringSymbols[] = {
\r
887 ".#,-.*;%\u2030+@0"
\r
890 static String en_GB_StringSymbols[] = {
\r
896 ".#,-.*;%\u2030+@0"
\r
899 static String en_US_StringSymbols[] = {
\r
905 ".#,-.*;%\u2030+@0"
\r
909 cannedDecimalFormatSymbols.put("en_CA", en_CA_StringSymbols);
\r
910 cannedDecimalFormatSymbols.put("fr_CA", fr_CA_StringSymbols);
\r
911 cannedDecimalFormatSymbols.put("zh_CN", zh_CN_StringSymbols);
\r
912 cannedDecimalFormatSymbols.put("zh", zh_StringSymbols);
\r
913 cannedDecimalFormatSymbols.put("en", en_StringSymbols);
\r
914 cannedDecimalFormatSymbols.put("fr_FR", fr_FR_StringSymbols);
\r
915 cannedDecimalFormatSymbols.put("fr", fr_StringSymbols);
\r
916 cannedDecimalFormatSymbols.put("de", de_StringSymbols);
\r
917 cannedDecimalFormatSymbols.put("de_DE", de_DE_StringSymbols);
\r
918 cannedDecimalFormatSymbols.put("it", it_StringSymbols);
\r
919 cannedDecimalFormatSymbols.put("it_IT", it_IT_StringSymbols);
\r
920 cannedDecimalFormatSymbols.put("ja_JP", ja_JP_StringSymbols);
\r
921 cannedDecimalFormatSymbols.put("ja", ja_StringSymbols);
\r
922 cannedDecimalFormatSymbols.put("ko_KR", ko_KR_StringSymbols);
\r
923 cannedDecimalFormatSymbols.put("ko", ko_StringSymbols);
\r
924 cannedDecimalFormatSymbols.put("zh_Hans_CN", zh_Hans_CN_StringSymbols);
\r
925 cannedDecimalFormatSymbols.put("zh_Hant_TW", zh_Hant_TW_StringSymbols);
\r
926 cannedDecimalFormatSymbols.put("zh_TW", zh_TW_StringSymbols);
\r
927 cannedDecimalFormatSymbols.put("en_GB", en_GB_StringSymbols);
\r
928 cannedDecimalFormatSymbols.put("en_US", en_US_StringSymbols);
\r
931 private static char[] getCharSymbols(DecimalFormatSymbols dfs)
\r
934 dfs.getDecimalSeparator(),
\r
936 dfs.getGroupingSeparator(),
\r
937 dfs.getMinusSign(),
\r
938 dfs.getMonetaryDecimalSeparator(),
\r
939 dfs.getPadEscape(),
\r
940 dfs.getPatternSeparator(),
\r
944 dfs.getSignificantDigit(),
\r
951 private static void setCharSymbols(DecimalFormatSymbols dfs, char symbols[])
\r
953 dfs.setDecimalSeparator(symbols[0]);
\r
954 dfs.setDigit(symbols[1]);
\r
955 dfs.setGroupingSeparator(symbols[2]);
\r
956 dfs.setMinusSign(symbols[3]);
\r
957 dfs.setMonetaryDecimalSeparator(symbols[4]);
\r
958 dfs.setPadEscape(symbols[5]);
\r
959 dfs.setPatternSeparator(symbols[6]);
\r
960 dfs.setPercent(symbols[7]);
\r
961 dfs.setPerMill(symbols[8]);
\r
962 dfs.setPlusSign(symbols[9]);
\r
963 dfs.setSignificantDigit(symbols[10]);
\r
964 dfs.setZeroDigit(symbols[11]);
\r
967 private static String[] getStringSymbols(DecimalFormatSymbols dfs)
\r
969 String symbols[] = {
\r
970 dfs.getCurrencySymbol(),
\r
971 dfs.getExponentSeparator(),
\r
973 dfs.getInternationalCurrencySymbol(),
\r
980 private static DecimalFormatSymbols getCannedDecimalFormatSymbols(ULocale uloc)
\r
982 DecimalFormatSymbols dfs = new DecimalFormatSymbols(uloc);
\r
984 setSymbols(dfs, (String[]) cannedDecimalFormatSymbols.get(uloc.toString()));
\r
989 private static DecimalFormat getCannedDecimalFormat(String pattern, ULocale uloc)
\r
991 return new DecimalFormat(pattern, getCannedDecimalFormatSymbols(uloc));
\r
994 private static void setSymbols(DecimalFormatSymbols dfs, String symbols[])
\r
996 dfs.setCurrencySymbol(symbols[0]);
\r
997 dfs.setExponentSeparator(symbols[1]);
\r
998 dfs.setInfinity(symbols[2]);
\r
999 dfs.setInternationalCurrencySymbol(symbols[3]);
\r
1000 dfs.setNaN(symbols[4]);
\r
1002 setCharSymbols(dfs, symbols[5].toCharArray());
\r
1005 public static class RelativeDateFormatHandler implements SerializableTest.Handler
\r
1007 public Object[] getTestObjects()
\r
1009 DateFormat formats[] = {
\r
1010 DateFormat.getDateInstance(DateFormat.RELATIVE_LONG,new ULocale("en")),
\r
1011 DateFormat.getDateInstance(DateFormat.RELATIVE_SHORT,new ULocale("ru")),
\r
1017 public boolean hasSameBehavior(Object a, Object b) {
\r
1018 DateFormat da = (DateFormat)a;
\r
1019 DateFormat db = (DateFormat)b;
\r
1021 Date d = new Date(System.currentTimeMillis());
\r
1022 return da.format(d).equals(db.format(d));
\r
1026 public static class BasicDurationFormatHandler implements SerializableTest.Handler
\r
1028 public Object[] getTestObjects()
\r
1030 DurationFormat formats[] = {
\r
1031 DurationFormat.getInstance(new ULocale("en"))
\r
1038 //TODO: Revisit this after 3.8
\r
1039 public boolean hasSameBehavior(Object a, Object b) {
\r
1040 //DurationFormat da = (DurationFormat)a;
\r
1041 //DurationFormat db = (DurationFormat)b;
\r
1043 //Date d = new Date(12345);
\r
1044 //System.err.println("Warning: BasicDurationFormat test is being skipped for now.");
\r
1046 //return da.format(d).equals(db.format(d));
\r
1050 public static class NumberFormatHandler implements SerializableTest.Handler
\r
1052 public Object[] getTestObjects()
\r
1054 ULocale uloc = ULocale.forLocale(Locale.US);
\r
1055 NumberFormat formats[] = {
\r
1057 * The code below was used to genereate the
\r
1058 * serialized NumberFormat objects in ICU 3.6:
\r
1060 * NumberFormat.getInstance(Locale.US)
\r
1061 * NumberFormat.getCurrencyInstance(Locale.US)
\r
1062 * NumberFormat.getPercentInstance(Locale.US)
\r
1063 * NumberFormat.getScientificInstance(Locale.US)
\r
1065 * Because the locale data might now be different that it was in
\r
1066 * ICU 3.6, the only way to guarantee that the object we generate
\r
1067 * will match the ICU 3.6 objects is to generate DecimalFormat objects
\r
1068 * that use the same patterns and DecimalFormatSymbols that
\r
1069 * were used in ICU 3.6.
\r
1071 getCannedDecimalFormat("#,##0.###", uloc),
\r
1072 getCannedDecimalFormat("\u00A4#,##0.00;(\u00A4#,##0.00)", uloc),
\r
1073 getCannedDecimalFormat("#,##0%", uloc),
\r
1074 getCannedDecimalFormat("#E0", uloc)
\r
1081 public boolean hasSameBehavior(Object a, Object b)
\r
1083 NumberFormat format_a = (NumberFormat) a;
\r
1084 NumberFormat format_b = (NumberFormat) b;
\r
1085 double number = 1234.56;
\r
1087 return format_a.format(number).equals(format_b.format(number));
\r
1091 public static class DecimalFormatHandler extends NumberFormatHandler
\r
1093 public Object[] getTestObjects()
\r
1095 Locale locales[] = SerializableTest.getLocales();
\r
1096 DecimalFormat formats[] = new DecimalFormat[locales.length];
\r
1098 for (int i = 0; i < locales.length; i += 1) {
\r
1099 ULocale uloc = ULocale.forLocale(locales[i]);
\r
1101 formats[i] = getCannedDecimalFormat("#,##0.###", uloc);
\r
1103 if (formats[0] != null) {
\r
1105 // Once formatToCharacterIterator is called, NumberFormat.Field
\r
1106 // instances are created and stored in the private List field.
\r
1107 // NumberForamt.Field is not a serializable, so serializing such
\r
1108 // instances end up NotSerializableException. This problem was
\r
1109 // reproduced since formatToCharacterIterator was introduced,
\r
1112 AttributedCharacterIterator aci = formats[0].formatToCharacterIterator(new Double(12.345D));
\r
1113 if (aci == null) {} // NOP - for resolving 'Unused local variable' warning.
\r
1119 public static class RuleBasedNumberFormatHandler extends NumberFormatHandler
\r
1121 // default rules, from root.txt
\r
1122 String xx_SpelloutRules = "=#,##0.######=;\n";
\r
1123 String xx_OrdinalRules = "=#,##0=;\n";
\r
1124 String xx_DurationRules = "=#,##0=;\n";
\r
1126 String ja_spelloutRules =
\r
1128 "\u96f6; \u58f1; \u5f10; \u53c2; \u56db; \u4f0d; \u516d; \u4e03; \u516b; \u4e5d;\n" +
\r
1130 "20: <<\u62fe[>>];\n" +
\r
1131 "100: <<\u767e[>>];\n" +
\r
1132 "1000: <<\u5343[>>];\n" +
\r
1133 "10,000: <<\u4e07[>>];\n" +
\r
1134 "100,000,000: <<\u5104[>>];\n" +
\r
1135 "1,000,000,000,000: <<\u5146[>>];\n" +
\r
1136 "10,000,000,000,000,000: =#,##0=;\n" +
\r
1138 "%traditional:\n" +
\r
1139 "\u96f6; \u4e00; \u4e8c; \u4e09; \u56db; \u4e94; \u516d; \u4e03; \u516b; \u4e5d;\n" +
\r
1141 "20: <<\u5341[>>];\n" +
\r
1142 "100: <<\u767e[>>];\n" +
\r
1143 "1000: <<\u5343[>>];\n" +
\r
1144 "10,000: <<\u4e07[>>];\n" +
\r
1145 "100,000,000: <<\u5104[>>];\n" +
\r
1146 "1,000,000,000,000: <<\u5146[>>];\n" +
\r
1147 "10,000,000,000,000,000: =#,##0=;";
\r
1149 String en_SpelloutRules =
\r
1150 // This rule set shows the normal simple formatting rules for English
\r
1151 "%simplified:\n" +
\r
1152 // negative number rule. This rule is used to format negative
\r
1153 // numbers. The result of formatting the number's absolute
\r
1154 // value is placed where the >> is.
\r
1155 "-x: minus >>;\n" +
\r
1156 // faction rule. This rule is used for formatting numbers
\r
1157 // with fractional parts. The result of formatting the
\r
1158 // number's integral part is substituted for the <<, and
\r
1159 // the result of formatting the number's fractional part
\r
1160 // (one digit at a time, e.g., 0.123 is "zero point one two
\r
1161 // three") replaces the >>.
\r
1162 "x.x: << point >>;\n" +
\r
1163 // the rules for the values from 0 to 19 are simply the
\r
1164 // words for those numbers
\r
1165 "zero; one; two; three; four; five; six; seven; eight; nine;\n" +
\r
1166 "ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" +
\r
1167 "seventeen; eighteen; nineteen;\n" +
\r
1168 // beginning at 20, we use the >> to mark the position where
\r
1169 // the result of formatting the number's ones digit. Thus,
\r
1170 // we only need a new rule at every multiple of 10. Text in
\r
1171 // backets is omitted if the value being formatted is an
\r
1172 // even multiple of 10.
\r
1173 "20: twenty[->>];\n" +
\r
1174 "30: thirty[->>];\n" +
\r
1175 "40: forty[->>];\n" +
\r
1176 "50: fifty[->>];\n" +
\r
1177 "60: sixty[->>];\n" +
\r
1178 "70: seventy[->>];\n" +
\r
1179 "80: eighty[->>];\n" +
\r
1180 "90: ninety[->>];\n" +
\r
1181 // beginning at 100, we can use << to mark the position where
\r
1182 // the result of formatting the multiple of 100 is to be
\r
1183 // inserted. Notice also that the meaning of >> has shifted:
\r
1184 // here, it refers to both the ones place and the tens place.
\r
1185 // The meanings of the << and >> tokens depend on the base value
\r
1186 // of the rule. A rule's divisor is (usually) the highest
\r
1187 // power of 10 that is less than or equal to the rule's base
\r
1188 // value. The value being formatted is divided by the rule's
\r
1189 // divisor, and the integral quotient is used to get the text
\r
1190 // for <<, while the remainder is used to produce the text
\r
1191 // for >>. Again, text in brackets is omitted if the value
\r
1192 // being formatted is an even multiple of the rule's divisor
\r
1193 // (in this case, an even multiple of 100)
\r
1194 "100: << hundred[ >>];\n" +
\r
1195 // The rules for the higher numbers work the same way as the
\r
1196 // rule for 100: Again, the << and >> tokens depend on the
\r
1197 // rule's divisor, which for all these rules is also the rule's
\r
1198 // base value. To group by thousand, we simply don't have any
\r
1199 // rules between 1,000 and 1,000,000.
\r
1200 "1000: << thousand[ >>];\n" +
\r
1201 "1,000,000: << million[ >>];\n" +
\r
1202 "1,000,000,000: << billion[ >>];\n" +
\r
1203 "1,000,000,000,000: << trillion[ >>];\n" +
\r
1204 // overflow rule. This rule specifies that values of a
\r
1205 // quadrillion or more are shown in numerals rather than words.
\r
1206 // The == token means to format (with new rules) the value
\r
1207 // being formatted by this rule and place the result where
\r
1208 // the == is. The #,##0 inside the == signs is a
\r
1209 // DecimalFormat pattern. It specifies that the value should
\r
1210 // be formatted with a DecimalFormat object, and that it
\r
1211 // should be formatted with no decimal places, at least one
\r
1212 // digit, and a thousands separator.
\r
1213 "1,000,000,000,000,000: =#,##0=;\n" +
\r
1215 // %default is a more elaborate form of %simplified; It is basically
\r
1216 // the same, except that it introduces "and" before the ones digit
\r
1217 // when appropriate (basically, between the tens and ones digits) and
\r
1218 // separates the thousands groups with commas in values over 100,000.
\r
1220 // negative-number and fraction rules. These are the same
\r
1221 // as those for %simplified, but have to be stated here too
\r
1222 // because this is an entry point
\r
1223 "-x: minus >>;\n" +
\r
1224 "x.x: << point >>;\n" +
\r
1225 // just use %simplified for values below 100
\r
1226 "=%simplified=;\n" +
\r
1227 // for values from 100 to 9,999 use %%and to decide whether or
\r
1228 // not to interpose the "and"
\r
1229 "100: << hundred[ >%%and>];\n" +
\r
1230 "1000: << thousand[ >%%and>];\n" +
\r
1231 // for values of 100,000 and up, use %%commas to interpose the
\r
1232 // commas in the right places (and also to interpose the "and")
\r
1233 "100,000>>: << thousand[>%%commas>];\n" +
\r
1234 "1,000,000: << million[>%%commas>];\n" +
\r
1235 "1,000,000,000: << billion[>%%commas>];\n" +
\r
1236 "1,000,000,000,000: << trillion[>%%commas>];\n" +
\r
1237 "1,000,000,000,000,000: =#,##0=;\n" +
\r
1238 // if the value passed to this rule set is greater than 100, don't
\r
1239 // add the "and"; if it's less than 100, add "and" before the last
\r
1242 "and =%default=;\n" +
\r
1243 "100: =%default=;\n" +
\r
1244 // this rule set is used to place the commas
\r
1246 // for values below 100, add "and" (the apostrophe at the
\r
1247 // beginning is ignored, but causes the space that follows it
\r
1248 // to be significant: this is necessary because the rules
\r
1249 // calling %%commas don't put a space before it)
\r
1250 "' and =%default=;\n" +
\r
1251 // put a comma after the thousands (or whatever preceded the
\r
1253 "100: , =%default=;\n" +
\r
1254 // put a comma after the millions (or whatever precedes the
\r
1256 "1000: , <%default< thousand, >%default>;\n" +
\r
1258 "1,000,000: , =%default=;" +
\r
1259 // %%lenient-parse isn't really a set of number formatting rules;
\r
1260 // it's a set of collation rules. Lenient-parse mode uses a Collator
\r
1261 // object to compare fragments of the text being parsed to the text
\r
1262 // in the rules, allowing more leeway in the matching text. This set
\r
1263 // of rules tells the formatter to ignore commas when parsing (it
\r
1264 // already ignores spaces, which is why we refer to the space; it also
\r
1265 // ignores hyphens, making "twenty one" and "twenty-one" parse
\r
1267 "%%lenient-parse:\n" +
\r
1268 // "& ' ' , ',' ;\n" +
\r
1269 " &\u0000 << ' ' << ',' << '-'; \n";
\r
1271 String en_GB_SpelloutRules =
\r
1272 "%simplified:\n" +
\r
1273 "-x: minus >>;\n" +
\r
1274 "x.x: << point >>;\n" +
\r
1275 "zero; one; two; three; four; five; six; seven; eight; nine;\n" +
\r
1276 "ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" +
\r
1277 " seventeen; eighteen; nineteen;\n" +
\r
1278 "20: twenty[->>];\n" +
\r
1279 "30: thirty[->>];\n" +
\r
1280 "40: forty[->>];\n" +
\r
1281 "50: fifty[->>];\n" +
\r
1282 "60: sixty[->>];\n" +
\r
1283 "70: seventy[->>];\n" +
\r
1284 "80: eighty[->>];\n" +
\r
1285 "90: ninety[->>];\n" +
\r
1286 "100: << hundred[ >>];\n" +
\r
1287 "1000: << thousand[ >>];\n" +
\r
1288 "1,000,000: << million[ >>];\n" +
\r
1289 "1,000,000,000,000: << billion[ >>];\n" +
\r
1290 "1,000,000,000,000,000: =#,##0=;\n" +
\r
1292 "-x: minus >>;\n" +
\r
1293 "x.x: << point >>;\n" +
\r
1294 "=%simplified=;\n" +
\r
1295 "100: << hundred[ >%%and>];\n" +
\r
1296 "1000: << thousand[ >%%and>];\n" +
\r
1297 "100,000>>: << thousand[>%%commas>];\n" +
\r
1298 "1,000,000: << million[>%%commas>];\n" +
\r
1299 "1,000,000,000,000: << billion[>%%commas>];\n" +
\r
1300 "1,000,000,000,000,000: =#,##0=;\n" +
\r
1302 "and =%default=;\n" +
\r
1303 "100: =%default=;\n" +
\r
1305 "' and =%default=;\n" +
\r
1306 "100: , =%default=;\n" +
\r
1307 "1000: , <%default< thousand, >%default>;\n" +
\r
1308 "1,000,000: , =%default=;" +
\r
1309 "%%lenient-parse:\n" +
\r
1310 "& ' ' , ',' ;\n";
\r
1312 String fr_SpelloutRules =
\r
1313 // the main rule set
\r
1315 "-x: moins >>;\n" +
\r
1316 "x.x: << virgule >>;\n" +
\r
1317 // words for numbers from 0 to 10
\r
1318 "z\u00e9ro; un; deux; trois; quatre; cinq; six; sept; huit; neuf;\n" +
\r
1319 "dix; onze; douze; treize; quatorze; quinze; seize;\n" +
\r
1320 " dix-sept; dix-huit; dix-neuf;\n" +
\r
1321 // ords for the multiples of 10: %%alt-ones inserts "et"
\r
1323 "20: vingt[->%%alt-ones>];\n" +
\r
1324 "30: trente[->%%alt-ones>];\n" +
\r
1325 "40: quarante[->%%alt-ones>];\n" +
\r
1326 "50: cinquante[->%%alt-ones>];\n" +
\r
1327 // rule for 60. The /20 causes this rule's multiplier to be
\r
1328 // 20 rather than 10, allowinhg us to recurse for all values
\r
1329 // from 60 to 79...
\r
1330 "60/20: soixante[->%%alt-ones>];\n" +
\r
1331 // ...except for 71, which must be special-cased
\r
1332 "71: soixante et onze;\n" +
\r
1333 // at 72, we have to repeat the rule for 60 to get us to 79
\r
1334 "72/20: soixante->%%alt-ones>;\n" +
\r
1335 // at 80, we state a new rule with the phrase for 80. Since
\r
1336 // it changes form when there's a ones digit, we need a second
\r
1337 // rule at 81. This rule also includes "/20," allowing it to
\r
1338 // be used correctly for all values up to 99
\r
1339 "80: quatre-vingts; 81/20: quatre-vingt->>;\n" +
\r
1340 // "cent" becomes plural when preceded by a multiplier, and
\r
1341 // the multiplier is omitted from the singular form
\r
1342 "100: cent[ >>];\n" +
\r
1343 "200: << cents[ >>];\n" +
\r
1344 "1000: mille[ >>];\n" +
\r
1345 // values from 1,100 to 1,199 are rendered as "onze cents..."
\r
1346 // instead of "mille cent..." The > after "1000" decreases
\r
1347 // the rule's exponent, causing its multiplier to be 100 instead
\r
1348 // of 1,000. This prevents us from getting "onze cents cent
\r
1349 // vingt-deux" ("eleven hundred one hundred twenty-two").
\r
1350 "1100>: onze cents[ >>];\n" +
\r
1351 // at 1,200, we go back to formating in thousands, so we
\r
1352 // repeat the rule for 1,000
\r
1353 "1200: mille >>;\n" +
\r
1354 // at 2,000, the multiplier is added
\r
1355 "2000: << mille[ >>];\n" +
\r
1356 "1,000,000: << million[ >>];\n" +
\r
1357 "1,000,000,000: << milliard[ >>];\n" +
\r
1358 "1,000,000,000,000: << billion[ >>];\n" +
\r
1359 "1,000,000,000,000,000: =#,##0=;\n" +
\r
1360 // %%alt-ones is used to insert "et" when the ones digit is 1
\r
1362 "; et-un; =%main=;\n" +
\r
1363 "%%lenient-parse:\n" +
\r
1364 "&\u0000 << ' ' << ',' << '-';\n";
\r
1366 String de_SpelloutRules =
\r
1367 // 1 is "eins" when by itself, but turns into "ein" in most
\r
1370 "-x: minus >>;\n" +
\r
1371 "x.x: << komma >>;\n" +
\r
1372 "null; eins; =%%main=;\n" +
\r
1374 // words for numbers from 0 to 12. Notice that the values
\r
1375 // from 13 to 19 can derived algorithmically, unlike in most
\r
1376 // other languages
\r
1377 "null; ein; zwei; drei; vier; f\u00fcnf; sechs; sieben; acht; neun;\n" +
\r
1378 "zehn; elf; zw\u00f6lf; >>zehn;\n" +
\r
1379 // rules for the multiples of 10. Notice that the ones digit
\r
1380 // goes on the front
\r
1381 "20: [>>und]zwanzig;\n" +
\r
1382 "30: [>>und]drei\u00dfig;\n" +
\r
1383 "40: [>>und]vierzig;\n" +
\r
1384 "50: [>>und]f\u00fcnfzig;\n" +
\r
1385 "60: [>>und]sechzig;\n" +
\r
1386 "70: [>>und]siebzig;\n" +
\r
1387 "80: [>>und]achtzig;\n" +
\r
1388 "90: [>>und]neunzig;\n" +
\r
1389 "100: hundert[>%alt-ones>];\n" +
\r
1390 "200: <<hundert[>%alt-ones>];\n" +
\r
1391 "1000: tausend[>%alt-ones>];\n" +
\r
1392 "2000: <<tausend[>%alt-ones>];\n" +
\r
1393 "1,000,000: eine Million[ >%alt-ones>];\n" +
\r
1394 "2,000,000: << Millionen[ >%alt-ones>];\n" +
\r
1395 "1,000,000,000: eine Milliarde[ >%alt-ones>];\n" +
\r
1396 "2,000,000,000: << Milliarden[ >%alt-ones>];\n" +
\r
1397 "1,000,000,000,000: eine Billion[ >%alt-ones>];\n" +
\r
1398 "2,000,000,000,000: << Billionen[ >%alt-ones>];\n" +
\r
1399 "1,000,000,000,000,000: =#,##0=;" +
\r
1400 "%%lenient-parse:\n" +
\r
1401 "&\u0000 << ' ' << '-'\n" +
\r
1402 "& ae , \u00e4 & ae , \u00c4\n" +
\r
1403 "& oe , \u00f6 & oe , \u00d6\n" +
\r
1404 "& ue , \u00fc & ue , \u00dc\n";
\r
1406 String it_SpelloutRules =
\r
1407 // main rule set. Follows the patterns of the preceding rule sets,
\r
1408 // except that the final vowel is omitted from words ending in
\r
1409 // vowels when they are followed by another word; instead, we have
\r
1410 // separate rule sets that are identical to this one, except that
\r
1411 // all the words that don't begin with a vowel have a vowel tacked
\r
1412 // onto them at the front. A word ending in a vowel calls a
\r
1413 // substitution that will supply that vowel, unless that vowel is to
\r
1416 "-x: meno >>;\n" +
\r
1417 "x.x: << virgola >>;\n" +
\r
1418 "zero; uno; due; tre; quattro; cinque; sei; sette; otto; nove;\n" +
\r
1419 "dieci; undici; dodici; tredici; quattordici; quindici; sedici;\n" +
\r
1420 " diciasette; diciotto; diciannove;\n" +
\r
1421 "20: venti; vent>%%with-i>;\n" +
\r
1422 "30: trenta; trent>%%with-i>;\n" +
\r
1423 "40: quaranta; quarant>%%with-a>;\n" +
\r
1424 "50: cinquanta; cinquant>%%with-a>;\n" +
\r
1425 "60: sessanta; sessant>%%with-a>;\n" +
\r
1426 "70: settanta; settant>%%with-a>;\n" +
\r
1427 "80: ottanta; ottant>%%with-a>;\n" +
\r
1428 "90: novanta; novant>%%with-a>;\n" +
\r
1429 "100: cento; cent[>%%with-o>];\n" +
\r
1430 "200: <<cento; <<cent[>%%with-o>];\n" +
\r
1431 "1000: mille; mill[>%%with-i>];\n" +
\r
1432 "2000: <<mila; <<mil[>%%with-a>];\n" +
\r
1433 "100,000>>: <<mila[ >>];\n" +
\r
1434 "1,000,000: =#,##0= (incomplete data);\n" +
\r
1436 "azero; uno; adue; atre; aquattro; acinque; asei; asette; otto; anove;\n" +
\r
1437 "adieci; undici; adodici; atredici; aquattordici; aquindici; asedici;\n" +
\r
1438 " adiciasette; adiciotto; adiciannove;\n" +
\r
1439 "20: aventi; avent>%%with-i>;\n" +
\r
1440 "30: atrenta; atrent>%%with-i>;\n" +
\r
1441 "40: aquaranta; aquarant>%%with-a>;\n" +
\r
1442 "50: acinquanta; acinquant>%%with-a>;\n" +
\r
1443 "60: asessanta; asessant>%%with-a>;\n" +
\r
1444 "70: asettanta; asettant>%%with-a>;\n" +
\r
1445 "80: ottanta; ottant>%%with-a>;\n" +
\r
1446 "90: anovanta; anovant>%%with-a>;\n" +
\r
1447 "100: acento; acent[>%%with-o>];\n" +
\r
1448 "200: <%%with-a<cento; <%%with-a<cent[>%%with-o>];\n" +
\r
1449 "1000: amille; amill[>%%with-i>];\n" +
\r
1450 "2000: <%%with-a<mila; <%%with-a<mil[>%%with-a>];\n" +
\r
1451 "100,000: =%main=;\n" +
\r
1453 "izero; uno; idue; itre; iquattro; icinque; isei; isette; otto; inove;\n" +
\r
1454 "idieci; undici; idodici; itredici; iquattordici; iquindici; isedici;\n" +
\r
1455 " idiciasette; idiciotto; idiciannove;\n" +
\r
1456 "20: iventi; ivent>%%with-i>;\n" +
\r
1457 "30: itrenta; itrent>%%with-i>;\n" +
\r
1458 "40: iquaranta; iquarant>%%with-a>;\n" +
\r
1459 "50: icinquanta; icinquant>%%with-a>;\n" +
\r
1460 "60: isessanta; isessant>%%with-a>;\n" +
\r
1461 "70: isettanta; isettant>%%with-a>;\n" +
\r
1462 "80: ottanta; ottant>%%with-a>;\n" +
\r
1463 "90: inovanta; inovant>%%with-a>;\n" +
\r
1464 "100: icento; icent[>%%with-o>];\n" +
\r
1465 "200: <%%with-i<cento; <%%with-i<cent[>%%with-o>];\n" +
\r
1466 "1000: imille; imill[>%%with-i>];\n" +
\r
1467 "2000: <%%with-i<mila; <%%with-i<mil[>%%with-a>];\n" +
\r
1468 "100,000: =%main=;\n" +
\r
1470 "ozero; uno; odue; otre; oquattro; ocinque; osei; osette; otto; onove;\n" +
\r
1471 "odieci; undici; ododici; otredici; oquattordici; oquindici; osedici;\n" +
\r
1472 " odiciasette; odiciotto; odiciannove;\n" +
\r
1473 "20: oventi; ovent>%%with-i>;\n" +
\r
1474 "30: otrenta; otrent>%%with-i>;\n" +
\r
1475 "40: oquaranta; oquarant>%%with-a>;\n" +
\r
1476 "50: ocinquanta; ocinquant>%%with-a>;\n" +
\r
1477 "60: osessanta; osessant>%%with-a>;\n" +
\r
1478 "70: osettanta; osettant>%%with-a>;\n" +
\r
1479 "80: ottanta; ottant>%%with-a>;\n" +
\r
1480 "90: onovanta; onovant>%%with-a>;\n" +
\r
1481 "100: ocento; ocent[>%%with-o>];\n" +
\r
1482 "200: <%%with-o<cento; <%%with-o<cent[>%%with-o>];\n" +
\r
1483 "1000: omille; omill[>%%with-i>];\n" +
\r
1484 "2000: <%%with-o<mila; <%%with-o<mil[>%%with-a>];\n" +
\r
1485 "100,000: =%main=;\n" ;
\r
1487 String en_OrdinalRules =
\r
1488 // this rule set formats the numeral and calls %%abbrev to
\r
1489 // supply the abbreviation
\r
1491 "=#,##0==%%abbrev=;\n" +
\r
1492 // this rule set supplies the abbreviation
\r
1494 // the abbreviations. Everything from 4 to 19 ends in "th"
\r
1495 "th; st; nd; rd; th;\n" +
\r
1496 // at 20, we begin repeating the cycle every 10 (13 is "13th",
\r
1497 // but 23 and 33 are "23rd" and "33rd") We do this by
\r
1498 // ignoring all bug the ones digit in selecting the abbreviation
\r
1500 // at 100, we repeat the whole cycle by considering only the
\r
1501 // tens and ones digits in picking an abbreviation
\r
1504 String en_DurationRules =
\r
1505 // main rule set for formatting with words
\r
1506 "%with-words:\n" +
\r
1507 // take care of singular and plural forms of "second"
\r
1508 "0 seconds; 1 second; =0= seconds;\n" +
\r
1509 // use %%min to format values greater than 60 seconds
\r
1510 "60/60: <%%min<[, >>];\n" +
\r
1511 // use %%hr to format values greater than 3,600 seconds
\r
1512 // (the ">>>" below causes us to see the number of minutes
\r
1513 // when when there are zero minutes)
\r
1514 "3600/60: <%%hr<[, >>>];\n" +
\r
1515 // this rule set takes care of the singular and plural forms
\r
1518 "0 minutes; 1 minute; =0= minutes;\n" +
\r
1519 // this rule set takes care of the singular and plural forms
\r
1522 "0 hours; 1 hour; =0= hours;\n" +
\r
1524 // main rule set for formatting in numerals
\r
1525 "%in-numerals:\n" +
\r
1526 // values below 60 seconds are shown with "sec."
\r
1528 // higher values are shown with colons: %%min-sec is used for
\r
1529 // values below 3,600 seconds...
\r
1530 "60: =%%min-sec=;\n" +
\r
1531 // ...and %%hr-min-sec is used for values of 3,600 seconds
\r
1533 "3600: =%%hr-min-sec=;\n" +
\r
1534 // this rule causes values of less than 10 minutes to show without
\r
1538 "60/60: <0<>>;\n" +
\r
1539 // this rule set is used for values of 3,600 or more. Minutes are always
\r
1540 // shown, and always shown with two digits
\r
1541 "%%hr-min-sec:\n" +
\r
1543 "60/60: <00<>>;\n" +
\r
1544 "3600/60: <#,##0<:>>>;\n" +
\r
1545 // the lenient-parse rules allow several different characters to be used
\r
1546 // as delimiters between hours, minutes, and seconds
\r
1547 "%%lenient-parse:\n" +
\r
1548 "& ':' = '.' = ' ' = '-';\n";
\r
1550 HashMap cannedData = new HashMap();
\r
1553 cannedData.put("en_CA/SpelloutRules", en_SpelloutRules);
\r
1554 cannedData.put("en_CA/OrdinalRules", en_OrdinalRules);
\r
1555 cannedData.put("en_CA/DurationRules", en_DurationRules);
\r
1557 cannedData.put("fr_CA/SpelloutRules", fr_SpelloutRules);
\r
1558 cannedData.put("fr_CA/OrdinalRules", xx_OrdinalRules);
\r
1559 cannedData.put("fr_CA/DurationRules", xx_DurationRules);
\r
1561 cannedData.put("zh_CN/SpelloutRules", en_SpelloutRules);
\r
1562 cannedData.put("zh_CN/OrdinalRules", en_OrdinalRules);
\r
1563 cannedData.put("zh_CH/DurationRules", xx_DurationRules);
\r
1565 cannedData.put("zh/SpelloutRules", en_SpelloutRules);
\r
1566 cannedData.put("zh/OrdinalRules", en_OrdinalRules);
\r
1567 cannedData.put("zh_DurationRules", xx_DurationRules);
\r
1569 cannedData.put("en/SpelloutRules", en_SpelloutRules);
\r
1570 cannedData.put("en/OrdinalRules", en_OrdinalRules);
\r
1571 cannedData.put("en/DurationRules", en_DurationRules);
\r
1573 cannedData.put("fr_FR/SpelloutRules", fr_SpelloutRules);
\r
1574 cannedData.put("fr_FR/OrdinalRules", xx_OrdinalRules);
\r
1575 cannedData.put("fr_FR/DurationRules", xx_DurationRules);
\r
1577 cannedData.put("fr/SpelloutRules", fr_SpelloutRules);
\r
1578 cannedData.put("fr/OrdinalRules", xx_OrdinalRules);
\r
1579 cannedData.put("fr/DurationRules", xx_DurationRules);
\r
1581 cannedData.put("de/SpelloutRules", de_SpelloutRules);
\r
1582 cannedData.put("de/OrdinalRules", xx_OrdinalRules);
\r
1583 cannedData.put("de/DurationRules", xx_DurationRules);
\r
1585 cannedData.put("de_DE/SpelloutRules", de_SpelloutRules);
\r
1586 cannedData.put("de_DE/OrdinalRules", xx_OrdinalRules);
\r
1587 cannedData.put("de_DE/DurationRules", xx_DurationRules);
\r
1589 cannedData.put("it/SpelloutRules", it_SpelloutRules);
\r
1590 cannedData.put("it/OrdinalRules", xx_OrdinalRules);
\r
1591 cannedData.put("it/DurationRules", xx_DurationRules);
\r
1593 cannedData.put("it_IT/SpelloutRules", it_SpelloutRules);
\r
1594 cannedData.put("it_IT/OrdinalRules", xx_OrdinalRules);
\r
1595 cannedData.put("it_IT/DuratonRules", xx_DurationRules);
\r
1597 cannedData.put("ko_KR/SpelloutRules", en_SpelloutRules);
\r
1598 cannedData.put("ko_KR/OrdinalRules", en_OrdinalRules);
\r
1599 cannedData.put("ko_KR/DurationRules", en_DurationRules);
\r
1601 cannedData.put("ko/SpelloutRules", en_SpelloutRules);
\r
1602 cannedData.put("ko/OrdinalRules", en_OrdinalRules);
\r
1603 cannedData.put("ko/DurationRules", en_DurationRules);
\r
1605 cannedData.put("zh_Hans_CN/SpelloutRules", en_SpelloutRules);
\r
1606 cannedData.put("zh_Hans_CN/OrdinalRules", en_OrdinalRules);
\r
1607 cannedData.put("zh_Hans_CH/DurationRules", xx_DurationRules);
\r
1609 cannedData.put("zh_Hant_TW/SpelloutRules", en_SpelloutRules);
\r
1610 cannedData.put("zh_Hant_TW/OrdinalRules", en_OrdinalRules);
\r
1611 cannedData.put("zh_Hant_TW/DurationRules", en_DurationRules);
\r
1613 cannedData.put("zh_TW/SpelloutRules", en_SpelloutRules);
\r
1614 cannedData.put("zh_TW/OrdinalRules", en_OrdinalRules);
\r
1615 cannedData.put("zh_TW/DurationRules", en_DurationRules);
\r
1617 cannedData.put("en_GB/SpelloutRules", en_GB_SpelloutRules);
\r
1618 cannedData.put("en_GB/OrdinalRules", en_OrdinalRules);
\r
1619 cannedData.put("en_GB/DurationRules", en_DurationRules);
\r
1621 cannedData.put("en_US/SpelloutRules", en_SpelloutRules);
\r
1622 cannedData.put("en_US/OrdinalRules", en_OrdinalRules);
\r
1623 cannedData.put("en_US/DurationRules", en_DurationRules);
\r
1625 cannedData.put("ja/SpelloutRules", ja_spelloutRules);
\r
1626 cannedData.put("ja/OrdinalRules", xx_OrdinalRules);
\r
1627 cannedData.put("ja/DurationRules", xx_DurationRules);
\r
1629 cannedData.put("ja_JP/SpelloutRules", ja_spelloutRules);
\r
1630 cannedData.put("ja_JP/OrdinalRules", xx_OrdinalRules);
\r
1631 cannedData.put("ja_JP/DurationRules", xx_DurationRules);
\r
1634 int types[] = {RuleBasedNumberFormat.SPELLOUT, RuleBasedNumberFormat.ORDINAL, RuleBasedNumberFormat.DURATION};
\r
1635 String typeNames[] = {"SpelloutRules", "OrdinalRules", "DurationRules"};
\r
1637 public Object[] getTestObjects()
\r
1639 Locale locales[] = SerializableTest.getLocales();
\r
1640 RuleBasedNumberFormat formats[] = new RuleBasedNumberFormat[types.length * locales.length];
\r
1643 for (int t = 0; t < types.length; t += 1) {
\r
1644 for (int l = 0; l < locales.length; l += 1) {
\r
1645 String cannedRules = (String) cannedData.get(locales[l].toString() + "/" + typeNames[t]);
\r
1647 if (cannedRules != null) {
\r
1648 formats[i++] = new RuleBasedNumberFormat(cannedRules, locales[l]);
\r
1650 formats[i++] = new RuleBasedNumberFormat(locales[l], types[t]);
\r
1659 public static class DecimalFormatSymbolsHandler implements SerializableTest.Handler
\r
1661 public Object[] getTestObjects()
\r
1663 Locale locales[] = SerializableTest.getLocales();
\r
1664 DecimalFormatSymbols dfs[] = new DecimalFormatSymbols[locales.length];
\r
1666 for (int i = 0; i < locales.length; i += 1) {
\r
1667 ULocale uloc = ULocale.forLocale(locales[i]);
\r
1669 dfs[i] = getCannedDecimalFormatSymbols(uloc);
\r
1671 // System.out.println("\n " + uloc.toString() + " = \"" +
\r
1672 // com.ibm.icu.impl.Utility.escape(String.valueOf(getCharSymbols(dfs[i]), 0, 12)) + "\"");
\r
1678 public boolean hasSameBehavior(Object a, Object b)
\r
1680 DecimalFormatSymbols dfs_a = (DecimalFormatSymbols) a;
\r
1681 DecimalFormatSymbols dfs_b = (DecimalFormatSymbols) b;
\r
1682 String strings_a[] = getStringSymbols(dfs_a);
\r
1683 String strings_b[] = getStringSymbols(dfs_b);
\r
1684 char chars_a[] = getCharSymbols(dfs_a);
\r
1685 char chars_b[] = getCharSymbols(dfs_b);
\r
1687 return SerializableTest.compareStrings(strings_a, strings_b) && SerializableTest.compareChars(chars_a, chars_b);
\r
1691 public static class CurrencyPluralInfoHandler implements SerializableTest.Handler
\r
1693 public Object[] getTestObjects()
\r
1695 CurrencyPluralInfo currencyPluralInfo[] = {
\r
1696 new CurrencyPluralInfo(), new CurrencyPluralInfo(new ULocale("en_US")),
\r
1697 CurrencyPluralInfo.getInstance(), CurrencyPluralInfo.getInstance(new Locale("en_US")),
\r
1698 CurrencyPluralInfo.getInstance(new ULocale("en_US"))
\r
1700 for(int i=0; i<currencyPluralInfo.length; i++){
\r
1701 currencyPluralInfo[i].setPluralRules("one: n is 1; few: n in 2..4");
\r
1702 currencyPluralInfo[i].setCurrencyPluralPattern("few", "few currency");
\r
1704 return currencyPluralInfo;
\r
1707 public boolean hasSameBehavior(Object a, Object b)
\r
1709 return a.equals(b);
\r
1713 public static class MessageFormatHandler implements SerializableTest.Handler
\r
1715 public Object[] getTestObjects()
\r
1717 MessageFormat formats[] = {new MessageFormat("pattern{0}")};
\r
1722 public boolean hasSameBehavior(Object a, Object b)
\r
1724 MessageFormat mfa = (MessageFormat) a;
\r
1725 MessageFormat mfb = (MessageFormat) b;
\r
1726 Object arguments[] = {new Integer(123456)};
\r
1728 return mfa.format(arguments) != mfb.format(arguments);
\r
1732 public static class MessageFormatFieldHandler implements SerializableTest.Handler
\r
1734 public Object[] getTestObjects()
\r
1736 return new Object[] {MessageFormat.Field.ARGUMENT};
\r
1739 public boolean hasSameBehavior(Object a, Object b)
\r
1745 public static class DateFormatHandler implements SerializableTest.Handler
\r
1747 static HashMap cannedPatterns = new HashMap();
\r
1748 static Date fixedDate;
\r
1751 cannedPatterns.put("en_CA", "EEEE, MMMM d, yyyy h:mm:ss a z");
\r
1752 cannedPatterns.put("fr_CA", "EEEE d MMMM yyyy HH' h 'mm' min 'ss' s 'z");
\r
1753 cannedPatterns.put("zh_Hans_CN", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE ahh'\u65F6'mm'\u5206'ss'\u79D2' z");
\r
1754 cannedPatterns.put("zh_CN", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE ahh'\u65F6'mm'\u5206'ss'\u79D2' z");
\r
1755 cannedPatterns.put("zh", "EEEE, yyyy MMMM dd HH:mm:ss z");
\r
1756 cannedPatterns.put("en", "EEEE, MMMM d, yyyy h:mm:ss a z");
\r
1757 cannedPatterns.put("fr_FR", "EEEE d MMMM yyyy HH' h 'mm z");
\r
1758 cannedPatterns.put("fr", "EEEE d MMMM yyyy HH' h 'mm z");
\r
1759 cannedPatterns.put("de", "EEEE, d. MMMM yyyy H:mm' Uhr 'z");
\r
1760 cannedPatterns.put("de_DE", "EEEE, d. MMMM yyyy H:mm' Uhr 'z");
\r
1761 cannedPatterns.put("it", "EEEE d MMMM yyyy HH:mm:ss z");
\r
1762 cannedPatterns.put("it_IT", "EEEE d MMMM yyyy HH:mm:ss z");
\r
1763 cannedPatterns.put("ja_JP", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE H'\u6642'mm'\u5206'ss'\u79D2'z");
\r
1764 cannedPatterns.put("ja", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE H'\u6642'mm'\u5206'ss'\u79D2'z");
\r
1765 cannedPatterns.put("ko_KR", "yyyy'\uB144' M'\uC6D4' d'\uC77C' EEEE a hh'\uC2DC' mm'\uBD84' ss'\uCD08' z");
\r
1766 cannedPatterns.put("ko", "yyyy'\uB144' M'\uC6D4' d'\uC77C' EEEE a hh'\uC2DC' mm'\uBD84' ss'\uCD08' z");
\r
1767 cannedPatterns.put("zh_Hant_TW", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE ahh'\u6642'mm'\u5206'ss'\u79D2' z");
\r
1768 cannedPatterns.put("zh_TW", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE ahh'\u6642'mm'\u5206'ss'\u79D2' z");
\r
1769 cannedPatterns.put("en_GB", "EEEE, d MMMM yyyy HH:mm:ss z");
\r
1770 cannedPatterns.put("en_US", "EEEE, MMMM d, yyyy h:mm:ss a z");
\r
1772 // Get a date that will likely not move in or out of Daylight savings time...
\r
1773 Calendar cal = Calendar.getInstance(Locale.US);
\r
1776 cal.set(2007, Calendar.JANUARY, 1, 12, 0, 0); // January 1, 2007 12:00:00 PM.
\r
1777 fixedDate = cal.getTime();
\r
1780 public Object[] getTestObjects()
\r
1782 Locale locales[] = SerializableTest.getLocales();
\r
1783 DateFormat formats[] = new DateFormat[locales.length];
\r
1785 for (int i = 0; i < locales.length; i += 1) {
\r
1786 ULocale uloc = ULocale.forLocale(locales[i]);
\r
1788 //formats[i] = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locales[i]);
\r
1789 formats[i] = getCannedSimpleDateFormat((String)cannedPatterns.get(uloc.toString()), uloc);
\r
1795 public boolean hasSameBehavior(Object a, Object b)
\r
1797 DateFormat dfa = (DateFormat) a;
\r
1798 DateFormat dfb = (DateFormat) b;
\r
1799 //Date date = new Date(System.currentTimeMillis());
\r
1800 String sfa = dfa.format(fixedDate);
\r
1801 String sfb = dfb.format(fixedDate);
\r
1803 if (!sfa.equals(sfb)) {
\r
1805 // In ICU3.8, localized GMT format pattern was added in
\r
1806 // DateFormatSymbols, which has no public setter.
\r
1807 // The difference of locale data for localized GMT format
\r
1808 // will produce different format result. This is a temporary
\r
1809 // workaround for the issue.
\r
1810 DateFormatSymbols dfsa = ((SimpleDateFormat)dfa).getDateFormatSymbols();
\r
1811 DateFormatSymbols tmp = (DateFormatSymbols)((SimpleDateFormat)dfb).getDateFormatSymbols().clone();
\r
1813 tmp.setMonths(dfsa.getMonths());
\r
1814 tmp.setShortMonths(dfsa.getShortMonths());
\r
1815 tmp.setWeekdays(dfsa.getWeekdays());
\r
1816 tmp.setShortWeekdays(dfsa.getShortWeekdays());
\r
1817 tmp.setAmPmStrings(dfsa.getAmPmStrings());
\r
1819 ((SimpleDateFormat)dfa).setDateFormatSymbols(tmp);
\r
1821 sfa = dfa.format(fixedDate);
\r
1824 return sfa.equals(sfb);
\r
1829 public static class DateFormatFieldHandler implements SerializableTest.Handler
\r
1831 public Object[] getTestObjects() {
\r
1832 return new Object[] {
\r
1833 DateFormat.Field.AM_PM,
\r
1834 DateFormat.Field.DAY_OF_MONTH,
\r
1835 DateFormat.Field.DAY_OF_WEEK,
\r
1836 DateFormat.Field.DAY_OF_WEEK_IN_MONTH,
\r
1837 DateFormat.Field.DAY_OF_YEAR,
\r
1838 DateFormat.Field.ERA,
\r
1839 DateFormat.Field.HOUR_OF_DAY0,
\r
1840 DateFormat.Field.HOUR_OF_DAY1,
\r
1841 DateFormat.Field.HOUR0,
\r
1842 DateFormat.Field.HOUR1,
\r
1843 DateFormat.Field.MILLISECOND,
\r
1844 DateFormat.Field.MINUTE,
\r
1845 DateFormat.Field.MONTH,
\r
1846 DateFormat.Field.SECOND,
\r
1847 DateFormat.Field.TIME_ZONE,
\r
1848 DateFormat.Field.WEEK_OF_MONTH,
\r
1849 DateFormat.Field.WEEK_OF_YEAR,
\r
1850 DateFormat.Field.YEAR,
\r
1851 DateFormat.Field.DOW_LOCAL,
\r
1852 DateFormat.Field.EXTENDED_YEAR,
\r
1853 DateFormat.Field.JULIAN_DAY,
\r
1854 DateFormat.Field.MILLISECONDS_IN_DAY,
\r
1855 DateFormat.Field.YEAR_WOY,
\r
1856 DateFormat.Field.QUARTER
\r
1859 public boolean hasSameBehavior(Object a, Object b)
\r
1865 public static class DateFormatSymbolsHandler implements SerializableTest.Handler
\r
1868 public Object[] getTestObjects()
\r
1870 Locale locales[] = SerializableTest.getLocales();
\r
1871 DateFormatSymbols dfs[] = new DateFormatSymbols[locales.length];
\r
1873 for (int i = 0; i < locales.length; i += 1) {
\r
1874 ULocale uloc = ULocale.forLocale(locales[i]);
\r
1876 dfs[i] = getCannedDateFormatSymbols(uloc);
\r
1882 public boolean hasSameBehavior(Object a, Object b)
\r
1884 DateFormatSymbols dfs_a = (DateFormatSymbols) a;
\r
1885 DateFormatSymbols dfs_b = (DateFormatSymbols) b;
\r
1886 String months_a[] = dfs_a.getMonths();
\r
1887 String months_b[] = dfs_b.getMonths();
\r
1889 return SerializableTest.compareStrings(months_a, months_b);
\r
1893 public static class SimpleDateFormatHandler extends DateFormatHandler
\r
1895 String patterns[] = {
\r
1896 "EEEE, yyyy MMMM dd",
\r
1902 public Object[] getTestObjects()
\r
1904 Locale locales[] = SerializableTest.getLocales();
\r
1905 SimpleDateFormat dateFormats[] = new SimpleDateFormat[patterns.length * locales.length];
\r
1908 for (int p = 0; p < patterns.length; p += 1) {
\r
1909 for (int l = 0; l < locales.length; l += 1) {
\r
1910 dateFormats[i++] = getCannedSimpleDateFormat(patterns[p], ULocale.forLocale(locales[l]));
\r
1914 return dateFormats;
\r
1918 public static class DateIntervalFormatHandler implements SerializableTest.Handler
\r
1920 public Object[] getTestObjects()
\r
1922 DateIntervalFormat dateIntervalFormats[] = {
\r
1923 DateIntervalFormat.getInstance("yMMMMEEEEd")
\r
1925 return dateIntervalFormats;
\r
1928 public boolean hasSameBehavior(Object a, Object b)
\r
1930 DateIntervalFormat dfa = (DateIntervalFormat) a;
\r
1931 DateIntervalFormat dfb = (DateIntervalFormat) b;
\r
1932 DateInterval dateInterval = new DateInterval(1, System.currentTimeMillis());
\r
1933 String sfa = dfa.format(dateInterval);
\r
1934 String sfb = dfb.format(dateInterval);
\r
1936 return sfa.equals(sfb);
\r
1941 public static class DateIntervalInfoHandler implements SerializableTest.Handler
\r
1943 public Object[] getTestObjects()
\r
1945 DateIntervalInfo dateIntervalInfo[] = {
\r
1946 new DateIntervalInfo()
\r
1948 dateIntervalInfo[0].setIntervalPattern("yMd", Calendar.YEAR, "yy/MM/dd - yy/MM/dd");
\r
1949 dateIntervalInfo[0].setIntervalPattern("yMd", Calendar.MONTH, "yy/MM - MM/dd");
\r
1950 return dateIntervalInfo;
\r
1953 public boolean hasSameBehavior(Object a, Object b)
\r
1955 return a.equals(b);
\r
1960 public static class PatternInfoHandler implements SerializableTest.Handler
\r
1962 public Object[] getTestObjects()
\r
1964 DateIntervalInfo.PatternInfo patternInfo[] = {
\r
1965 new DateIntervalInfo.PatternInfo("yyyy MMM dd - ",
\r
1969 return patternInfo;
\r
1972 public boolean hasSameBehavior(Object a, Object b)
\r
1974 return a.equals(b);
\r
1978 public static class ChineseDateFormatHandler extends DateFormatHandler
\r
1980 String patterns[] = {
\r
1981 "EEEE y'x'G-Ml-d",
\r
1987 public Object[] getTestObjects()
\r
1989 Locale locales[] = SerializableTest.getLocales();
\r
1990 ChineseDateFormat dateFormats[] = new ChineseDateFormat[patterns.length * locales.length];
\r
1993 for (int p = 0; p < patterns.length; p += 1) {
\r
1994 for (int l = 0; l < locales.length; l += 1) {
\r
1995 ULocale locale = new ULocale(locales[l].toString() + "@calendar=chinese");
\r
1997 dateFormats[i++] = new ChineseDateFormat(patterns[p], locale);
\r
2001 return dateFormats;
\r
2005 public static class ChineseDateFormatFieldHandler implements SerializableTest.Handler
\r
2007 public Object[] getTestObjects() {
\r
2008 return new Object[] {
\r
2009 ChineseDateFormat.Field.IS_LEAP_MONTH
\r
2012 public boolean hasSameBehavior(Object a, Object b)
\r
2018 public static class ChineseDateFormatSymbolsHandler extends DateFormatSymbolsHandler
\r
2020 public Object[] getTestObjects()
\r
2022 Locale locales[] = SerializableTest.getLocales();
\r
2023 ChineseDateFormatSymbols cdfs[] = new ChineseDateFormatSymbols[locales.length];
\r
2025 for (int i = 0; i < locales.length; i += 1) {
\r
2026 ULocale uloc = ULocale.forLocale(locales[i]);
\r
2028 cdfs[i] = new ChineseDateFormatSymbols(uloc);
\r
2029 cdfs[i].setMonths((String[]) cannedMonthNames.get(uloc.toString()));
\r
2035 public boolean hasSameBehavior(Object a, Object b)
\r
2037 if (! super.hasSameBehavior(a, b)) {
\r
2041 ChineseDateFormatSymbols cdfs_a = (ChineseDateFormatSymbols) a;
\r
2042 ChineseDateFormatSymbols cdfs_b = (ChineseDateFormatSymbols) b;
\r
2044 return cdfs_a.getLeapMonth(0).equals(cdfs_b.getLeapMonth(0)) &&
\r
2045 cdfs_a.getLeapMonth(1).equals(cdfs_b.getLeapMonth(1));
\r
2049 public static class NumberFormatFieldHandler implements SerializableTest.Handler
\r
2051 public Object[] getTestObjects()
\r
2053 NumberFormat.Field fields[] = {
\r
2054 NumberFormat.Field.CURRENCY, NumberFormat.Field.DECIMAL_SEPARATOR, NumberFormat.Field.EXPONENT,
\r
2055 NumberFormat.Field.EXPONENT_SIGN, NumberFormat.Field.EXPONENT_SYMBOL, NumberFormat.Field.FRACTION,
\r
2056 NumberFormat.Field.GROUPING_SEPARATOR, NumberFormat.Field.INTEGER, NumberFormat.Field.PERCENT,
\r
2057 NumberFormat.Field.PERMILLE, NumberFormat.Field.SIGN
\r
2063 public boolean hasSameBehavior(Object a, Object b)
\r
2065 NumberFormat.Field field_a = (NumberFormat.Field) a;
\r
2066 NumberFormat.Field field_b = (NumberFormat.Field) b;
\r
2068 return field_a.toString().equals(field_b.toString());
\r
2072 public static class DateNumberFormatHandler implements SerializableTest.Handler
\r
2074 public Object[] getTestObjects()
\r
2076 Locale locales[] = SerializableTest.getLocales();
\r
2077 DateNumberFormat[] dnfmts = new DateNumberFormat[locales.length];
\r
2078 for (int i = 0; i < locales.length; i++) {
\r
2079 ULocale uloc = ULocale.forLocale(locales[i]);
\r
2080 dnfmts[i] = new DateNumberFormat(uloc,'0');
\r
2085 public boolean hasSameBehavior(Object a, Object b) {
\r
2086 return a.equals(b);
\r
2090 public static class SelectFormatHandler implements SerializableTest.Handler {
\r
2092 public Object[] getTestObjects() {
\r
2093 SelectFormat[] selfmts = {new SelectFormat("keyword{phrase} other{otherPhrase}")};
\r
2098 public boolean hasSameBehavior(Object a, Object b) {
\r
2099 SelectFormat sfa = (SelectFormat) a;
\r
2100 SelectFormat sfb = (SelectFormat) b;
\r
2101 String argument = "keyword";
\r
2103 return sfa.format(argument) != sfb.format(argument);
\r
2107 public static class PluralFormatHandler implements SerializableTest.Handler {
\r
2108 public Object[] getTestObjects() {
\r
2109 Locale[] locales = { Locale.US }; // main test is in plural rules handler
\r
2110 PluralFormat[] plfmts = new PluralFormat[locales.length];
\r
2111 for (int i = 0; i < locales.length; i++) {
\r
2112 ULocale uloc = ULocale.forLocale(locales[i]);
\r
2114 plfmts[i] = new PluralFormat(uloc, "one{1 foo} other{# foo}");
\r
2115 } catch (Exception e) {
\r
2116 e.printStackTrace();
\r
2121 public boolean hasSameBehavior(Object a, Object b) {
\r
2122 PluralFormat pfa = (PluralFormat)a;
\r
2123 PluralFormat pfb = (PluralFormat)b;
\r
2124 boolean isSame = true;
\r
2125 for (int i = 0; i < 10; i++) {
\r
2126 String texta = pfa.format(i);
\r
2127 String textb = pfb.format(i);
\r
2128 if (!texta.equals(textb)) {
\r
2137 public static class PluralRulesHandler implements SerializableTest.Handler {
\r
2138 // canned rules as of 4.2
\r
2139 final String[] cannedRules = {
\r
2141 "one: n is 1", // da
\r
2142 "one: n within 0..2 and n is not 2", // fr
\r
2143 "one: n mod 10 is 1 and n mod 100 is not 11; zero: n is 0", // lv
\r
2144 "one: n is 1; two: n is 2", // ga
\r
2145 "few: n is 0 OR n is not 1 AND n mod 100 in 1..19; one: n is 1", // ro
\r
2146 "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
\r
2147 "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
\r
2148 "few: n in 2..4; one: n is 1", // cs
\r
2149 "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
\r
2150 "few: n mod 100 in 3..4; one: n mod 100 is 1; two: n mod 100 is 2", // sl
\r
2153 public Object[] getTestObjects() {
\r
2154 PluralRules[] plrulz = new PluralRules[cannedRules.length];
\r
2155 for (int i = 0; i < cannedRules.length; i++) {
\r
2157 plrulz[i] = PluralRules.parseDescription(cannedRules[i]);
\r
2158 } catch (Exception e) {
\r
2159 e.printStackTrace();
\r
2164 public boolean hasSameBehavior(Object a, Object b) {
\r
2165 return a.equals(b);
\r
2170 public static class TimeUnitFormatHandler implements SerializableTest.Handler {
\r
2171 // TODO - more test coverage!
\r
2172 public Object[] getTestObjects() {
\r
2173 return new Object[] { new TimeUnitFormat().setLocale(ULocale.ENGLISH) };
\r
2175 public boolean hasSameBehavior(Object a, Object b) {
\r
2176 TimeUnitFormat tufa = (TimeUnitFormat)a;
\r
2177 TimeUnitFormat tufb = (TimeUnitFormat)b;
\r
2179 TimeUnitAmount amount = new TimeUnitAmount(3, TimeUnit.HOUR);
\r
2180 String resa = tufa.format(amount);
\r
2181 String resb = tufb.format(amount);
\r
2183 return resa.equals(resb);
\r
2187 public static void main(String[] args)
\r
2189 // nothing needed...
\r