3 *******************************************************************************
4 * Copyright (C) 1996-2009, International Business Machines Corporation and *
5 * others. All Rights Reserved. *
6 *******************************************************************************
10 package com.ibm.icu.dev.test.serializable;
12 import java.text.AttributedCharacterIterator;
13 import java.util.Date;
14 import java.util.HashMap;
15 import java.util.Locale;
17 import com.ibm.icu.impl.DateNumberFormat;
18 import com.ibm.icu.text.ChineseDateFormat;
19 import com.ibm.icu.text.ChineseDateFormatSymbols;
20 import com.ibm.icu.text.DateFormat;
21 import com.ibm.icu.text.DateFormatSymbols;
22 import com.ibm.icu.text.DateIntervalFormat;
23 import com.ibm.icu.text.DateIntervalInfo;
24 import com.ibm.icu.text.DecimalFormat;
25 import com.ibm.icu.text.CurrencyPluralInfo;
26 import com.ibm.icu.text.DecimalFormatSymbols;
27 import com.ibm.icu.text.DurationFormat;
28 import com.ibm.icu.text.MessageFormat;
29 import com.ibm.icu.text.NumberFormat;
30 import com.ibm.icu.text.PluralFormat;
31 import com.ibm.icu.text.PluralRules;
32 import com.ibm.icu.text.RuleBasedNumberFormat;
33 import com.ibm.icu.text.SimpleDateFormat;
34 import com.ibm.icu.text.TimeUnitFormat;
35 import com.ibm.icu.util.Calendar;
36 import com.ibm.icu.util.DateInterval;
37 import com.ibm.icu.util.GregorianCalendar;
38 import com.ibm.icu.util.TimeUnit;
39 import com.ibm.icu.util.TimeUnitAmount;
40 import com.ibm.icu.util.ULocale;
45 * TODO To change the template for this generated type comment go to
46 * Window - Preferences - Java - Code Style - Code Templates
48 public class FormatTests
51 * The serialized form of a normally created DateFormatSymbols object
52 * will have locale-specific data in it that might change from one version
53 * of ICU4J to another. To guard against this, we store the following canned
54 * data into the test objects we create.
56 static HashMap cannedMonthNames = new HashMap();
57 static HashMap cannedShortMonthNames = new HashMap();
59 static String en_CA_MonthNames[] = {
74 static String fr_CA_MonthNames[] = {
89 static String zh_Hans_CN_MonthNames[] = {
100 "\u5341\u4E00\u6708",
101 "\u5341\u4E8C\u6708",
104 static String zh_CN_MonthNames[] = {
115 "\u5341\u4E00\u6708",
116 "\u5341\u4E8C\u6708",
119 static String zh_MonthNames[] = {
130 "\u5341\u4E00\u6708",
131 "\u5341\u4E8C\u6708",
134 static String en_MonthNames[] = {
149 static String fr_FR_MonthNames[] = {
164 static String fr_MonthNames[] = {
179 static String de_MonthNames[] = {
194 static String de_DE_MonthNames[] = {
209 static String it_MonthNames[] = {
224 static String it_IT_MonthNames[] = {
239 static String ja_JP_MonthNames[] = {
254 static String ja_MonthNames[] = {
269 static String ko_KR_MonthNames[] = {
284 static String ko_MonthNames[] = {
299 static String zh_Hant_TW_MonthNames[] = {
310 "\u5341\u4E00\u6708",
311 "\u5341\u4E8C\u6708",
314 static String zh_TW_MonthNames[] = {
325 "\u5341\u4E00\u6708",
326 "\u5341\u4E8C\u6708",
329 static String en_GB_MonthNames[] = {
344 static String en_US_MonthNames[] = {
359 static String en_CA_ShortMonthNames[] = {
374 static String fr_CA_ShortMonthNames[] = {
389 static String zh_Hans_CN_ShortMonthNames[] = {
400 "\u5341\u4E00\u6708",
401 "\u5341\u4E8C\u6708",
404 static String zh_CN_ShortMonthNames[] = {
415 "\u5341\u4E00\u6708",
416 "\u5341\u4E8C\u6708",
419 static String zh_ShortMonthNames[] = {
430 "\u5341\u4E00\u6708",
431 "\u5341\u4E8C\u6708",
434 static String en_ShortMonthNames[] = {
449 static String fr_FR_ShortMonthNames[] = {
464 static String fr_ShortMonthNames[] = {
479 static String de_ShortMonthNames[] = {
494 static String de_DE_ShortMonthNames[] = {
509 static String it_ShortMonthNames[] = {
524 static String it_IT_ShortMonthNames[] = {
539 static String ja_JP_ShortMonthNames[] = {
554 static String ja_ShortMonthNames[] = {
569 static String ko_KR_ShortMonthNames[] = {
584 static String ko_ShortMonthNames[] = {
599 static String zh_Hant_TW_ShortMonthNames[] = {
610 "\u5341\u4E00\u6708",
611 "\u5341\u4E8C\u6708",
614 static String zh_TW_ShortMonthNames[] = {
625 "\u5341\u4E00\u6708",
626 "\u5341\u4E8C\u6708",
629 static String en_GB_ShortMonthNames[] = {
644 static String en_US_ShortMonthNames[] = {
660 cannedMonthNames.put("en_CA", en_CA_MonthNames);
661 cannedMonthNames.put("fr_CA", fr_CA_MonthNames);
662 cannedMonthNames.put("zh_Hans_CN", zh_Hans_CN_MonthNames);
663 cannedMonthNames.put("zh_CN", zh_CN_MonthNames);
664 cannedMonthNames.put("zh", zh_MonthNames);
665 cannedMonthNames.put("en", en_MonthNames);
666 cannedMonthNames.put("fr_FR", fr_FR_MonthNames);
667 cannedMonthNames.put("fr", fr_MonthNames);
668 cannedMonthNames.put("de", de_MonthNames);
669 cannedMonthNames.put("de_DE", de_DE_MonthNames);
670 cannedMonthNames.put("it", it_MonthNames);
671 cannedMonthNames.put("it_IT", it_IT_MonthNames);
672 cannedMonthNames.put("ja_JP", ja_JP_MonthNames);
673 cannedMonthNames.put("ja", ja_MonthNames);
674 cannedMonthNames.put("ko_KR", ko_KR_MonthNames);
675 cannedMonthNames.put("ko", ko_MonthNames);
676 cannedMonthNames.put("zh_Hant_TW", zh_Hant_TW_MonthNames);
677 cannedMonthNames.put("zh_TW", zh_TW_MonthNames);
678 cannedMonthNames.put("en_GB", en_GB_MonthNames);
679 cannedMonthNames.put("en_US", en_US_MonthNames);
681 cannedShortMonthNames.put("en_CA", en_CA_ShortMonthNames);
682 cannedShortMonthNames.put("fr_CA", fr_CA_ShortMonthNames);
683 cannedShortMonthNames.put("zh_Hans_CN", zh_Hans_CN_ShortMonthNames);
684 cannedShortMonthNames.put("zh_CN", zh_CN_ShortMonthNames);
685 cannedShortMonthNames.put("zh", zh_ShortMonthNames);
686 cannedShortMonthNames.put("en", en_ShortMonthNames);
687 cannedShortMonthNames.put("fr_FR", fr_FR_ShortMonthNames);
688 cannedShortMonthNames.put("fr", fr_ShortMonthNames);
689 cannedShortMonthNames.put("de", de_ShortMonthNames);
690 cannedShortMonthNames.put("de_DE", de_DE_ShortMonthNames);
691 cannedShortMonthNames.put("it", it_ShortMonthNames);
692 cannedShortMonthNames.put("it_IT", it_IT_ShortMonthNames);
693 cannedShortMonthNames.put("ja_JP", ja_JP_ShortMonthNames);
694 cannedShortMonthNames.put("ja", ja_ShortMonthNames);
695 cannedShortMonthNames.put("ko_KR", ko_KR_ShortMonthNames);
696 cannedShortMonthNames.put("ko", ko_ShortMonthNames);
697 cannedShortMonthNames.put("zh_Hant_TW", zh_Hant_TW_ShortMonthNames);
698 cannedShortMonthNames.put("zh_TW", zh_TW_ShortMonthNames);
699 cannedShortMonthNames.put("en_GB", en_GB_ShortMonthNames);
700 cannedShortMonthNames.put("en_US", en_US_ShortMonthNames);
703 private static DateFormatSymbols getCannedDateFormatSymbols(ULocale uloc)
705 DateFormatSymbols dfs =new DateFormatSymbols(GregorianCalendar.class, uloc);
706 String key = uloc.toString();
708 dfs.setMonths((String[]) cannedMonthNames.get(key));
709 dfs.setShortMonths((String[]) cannedShortMonthNames.get(key));
714 private static SimpleDateFormat getCannedSimpleDateFormat(String pattern, ULocale uloc)
716 DateFormatSymbols dfs = getCannedDateFormatSymbols(uloc);
718 return new SimpleDateFormat(pattern, dfs, uloc);
722 * The serialized form of a normally created DecimalFormatSymbols object
723 * will have locale-specific data in it that might change from one version
724 * of ICU4J to another. To guard against this, we store the following canned
725 * data into the test objects we create.
727 static HashMap cannedDecimalFormatSymbols = new HashMap();
729 static String en_CA_StringSymbols[] = {
738 static String fr_CA_StringSymbols[] = {
744 ",#\u00A0-,*;%\u2030+@0"
747 static String zh_CN_StringSymbols[] = {
756 static String zh_StringSymbols[] = {
765 static String en_StringSymbols[] = {
774 static String fr_FR_StringSymbols[] = {
780 ",#\u00A0-,*;%\u2030+@0"
783 static String fr_StringSymbols[] = {
789 ",#\u00A0-,*;%\u2030+@0"
792 static String de_StringSymbols[] = {
801 static String de_DE_StringSymbols[] = {
810 static String it_StringSymbols[] = {
819 static String it_IT_StringSymbols[] = {
828 static String ja_JP_StringSymbols[] = {
837 static String ja_StringSymbols[] = {
846 static String ko_KR_StringSymbols[] = {
855 static String ko_StringSymbols[] = {
864 static String zh_Hans_CN_StringSymbols[] = {
873 static String zh_Hant_TW_StringSymbols[] = {
882 static String zh_TW_StringSymbols[] = {
891 static String en_GB_StringSymbols[] = {
900 static String en_US_StringSymbols[] = {
910 cannedDecimalFormatSymbols.put("en_CA", en_CA_StringSymbols);
911 cannedDecimalFormatSymbols.put("fr_CA", fr_CA_StringSymbols);
912 cannedDecimalFormatSymbols.put("zh_CN", zh_CN_StringSymbols);
913 cannedDecimalFormatSymbols.put("zh", zh_StringSymbols);
914 cannedDecimalFormatSymbols.put("en", en_StringSymbols);
915 cannedDecimalFormatSymbols.put("fr_FR", fr_FR_StringSymbols);
916 cannedDecimalFormatSymbols.put("fr", fr_StringSymbols);
917 cannedDecimalFormatSymbols.put("de", de_StringSymbols);
918 cannedDecimalFormatSymbols.put("de_DE", de_DE_StringSymbols);
919 cannedDecimalFormatSymbols.put("it", it_StringSymbols);
920 cannedDecimalFormatSymbols.put("it_IT", it_IT_StringSymbols);
921 cannedDecimalFormatSymbols.put("ja_JP", ja_JP_StringSymbols);
922 cannedDecimalFormatSymbols.put("ja", ja_StringSymbols);
923 cannedDecimalFormatSymbols.put("ko_KR", ko_KR_StringSymbols);
924 cannedDecimalFormatSymbols.put("ko", ko_StringSymbols);
925 cannedDecimalFormatSymbols.put("zh_Hans_CN", zh_Hans_CN_StringSymbols);
926 cannedDecimalFormatSymbols.put("zh_Hant_TW", zh_Hant_TW_StringSymbols);
927 cannedDecimalFormatSymbols.put("zh_TW", zh_TW_StringSymbols);
928 cannedDecimalFormatSymbols.put("en_GB", en_GB_StringSymbols);
929 cannedDecimalFormatSymbols.put("en_US", en_US_StringSymbols);
932 private static char[] getCharSymbols(DecimalFormatSymbols dfs)
935 dfs.getDecimalSeparator(),
937 dfs.getGroupingSeparator(),
939 dfs.getMonetaryDecimalSeparator(),
941 dfs.getPatternSeparator(),
945 dfs.getSignificantDigit(),
952 private static void setCharSymbols(DecimalFormatSymbols dfs, char symbols[])
954 dfs.setDecimalSeparator(symbols[0]);
955 dfs.setDigit(symbols[1]);
956 dfs.setGroupingSeparator(symbols[2]);
957 dfs.setMinusSign(symbols[3]);
958 dfs.setMonetaryDecimalSeparator(symbols[4]);
959 dfs.setPadEscape(symbols[5]);
960 dfs.setPatternSeparator(symbols[6]);
961 dfs.setPercent(symbols[7]);
962 dfs.setPerMill(symbols[8]);
963 dfs.setPlusSign(symbols[9]);
964 dfs.setSignificantDigit(symbols[10]);
965 dfs.setZeroDigit(symbols[11]);
968 private static String[] getStringSymbols(DecimalFormatSymbols dfs)
971 dfs.getCurrencySymbol(),
972 dfs.getExponentSeparator(),
974 dfs.getInternationalCurrencySymbol(),
981 private static DecimalFormatSymbols getCannedDecimalFormatSymbols(ULocale uloc)
983 DecimalFormatSymbols dfs = new DecimalFormatSymbols(uloc);
985 setSymbols(dfs, (String[]) cannedDecimalFormatSymbols.get(uloc.toString()));
990 private static DecimalFormat getCannedDecimalFormat(String pattern, ULocale uloc)
992 return new DecimalFormat(pattern, getCannedDecimalFormatSymbols(uloc));
995 private static void setSymbols(DecimalFormatSymbols dfs, String symbols[])
997 dfs.setCurrencySymbol(symbols[0]);
998 dfs.setExponentSeparator(symbols[1]);
999 dfs.setInfinity(symbols[2]);
1000 dfs.setInternationalCurrencySymbol(symbols[3]);
1001 dfs.setNaN(symbols[4]);
1003 setCharSymbols(dfs, symbols[5].toCharArray());
1006 public static class RelativeDateFormatHandler implements SerializableTest.Handler
1008 public Object[] getTestObjects()
1010 DateFormat formats[] = {
1011 DateFormat.getDateInstance(DateFormat.RELATIVE_LONG,new ULocale("en")),
1012 DateFormat.getDateInstance(DateFormat.RELATIVE_SHORT,new ULocale("ru")),
1018 public boolean hasSameBehavior(Object a, Object b) {
1019 DateFormat da = (DateFormat)a;
1020 DateFormat db = (DateFormat)b;
1022 Date d = new Date(System.currentTimeMillis());
1023 return da.format(d).equals(db.format(d));
1027 public static class BasicDurationFormatHandler implements SerializableTest.Handler
1029 public Object[] getTestObjects()
1031 DurationFormat formats[] = {
1032 DurationFormat.getInstance(new ULocale("en"))
1039 //TODO: Revisit this after 3.8
1040 public boolean hasSameBehavior(Object a, Object b) {
1041 //DurationFormat da = (DurationFormat)a;
1042 //DurationFormat db = (DurationFormat)b;
1044 //Date d = new Date(12345);
1045 //System.err.println("Warning: BasicDurationFormat test is being skipped for now.");
1047 //return da.format(d).equals(db.format(d));
1051 public static class NumberFormatHandler implements SerializableTest.Handler
1053 public Object[] getTestObjects()
1055 ULocale uloc = ULocale.forLocale(Locale.US);
1056 NumberFormat formats[] = {
1058 * The code below was used to genereate the
1059 * serialized NumberFormat objects in ICU 3.6:
1061 * NumberFormat.getInstance(Locale.US)
1062 * NumberFormat.getCurrencyInstance(Locale.US)
1063 * NumberFormat.getPercentInstance(Locale.US)
1064 * NumberFormat.getScientificInstance(Locale.US)
1066 * Because the locale data might now be different that it was in
1067 * ICU 3.6, the only way to guarantee that the object we generate
1068 * will match the ICU 3.6 objects is to generate DecimalFormat objects
1069 * that use the same patterns and DecimalFormatSymbols that
1070 * were used in ICU 3.6.
1072 getCannedDecimalFormat("#,##0.###", uloc),
1073 getCannedDecimalFormat("\u00A4#,##0.00;(\u00A4#,##0.00)", uloc),
1074 getCannedDecimalFormat("#,##0%", uloc),
1075 getCannedDecimalFormat("#E0", uloc)
1082 public boolean hasSameBehavior(Object a, Object b)
1084 NumberFormat format_a = (NumberFormat) a;
1085 NumberFormat format_b = (NumberFormat) b;
1086 double number = 1234.56;
1088 return format_a.format(number).equals(format_b.format(number));
1092 public static class DecimalFormatHandler extends NumberFormatHandler
1094 public Object[] getTestObjects()
1096 Locale locales[] = SerializableTest.getLocales();
1097 DecimalFormat formats[] = new DecimalFormat[locales.length];
1099 for (int i = 0; i < locales.length; i += 1) {
1100 ULocale uloc = ULocale.forLocale(locales[i]);
1102 formats[i] = getCannedDecimalFormat("#,##0.###", uloc);
1104 //#if defined(FOUNDATION10) || defined(J2SE13)
1106 if (formats[0] != null) {
1108 // Once formatToCharacterIterator is called, NumberFormat.Field
1109 // instances are created and stored in the private List field.
1110 // NumberForamt.Field is not a serializable, so serializing such
1111 // instances end up NotSerializableException. This problem was
1112 // reproduced since formatToCharacterIterator was introduced,
1115 AttributedCharacterIterator aci = formats[0].formatToCharacterIterator(new Double(12.345D));
1116 if (aci == null) {} // NOP - for resolving 'Unused local variable' warning.
1123 public static class RuleBasedNumberFormatHandler extends NumberFormatHandler
1125 // default rules, from root.txt
1126 String xx_SpelloutRules = "=#,##0.######=;\n";
1127 String xx_OrdinalRules = "=#,##0=;\n";
1128 String xx_DurationRules = "=#,##0=;\n";
1130 String ja_spelloutRules =
1132 "\u96f6; \u58f1; \u5f10; \u53c2; \u56db; \u4f0d; \u516d; \u4e03; \u516b; \u4e5d;\n" +
1134 "20: <<\u62fe[>>];\n" +
1135 "100: <<\u767e[>>];\n" +
1136 "1000: <<\u5343[>>];\n" +
1137 "10,000: <<\u4e07[>>];\n" +
1138 "100,000,000: <<\u5104[>>];\n" +
1139 "1,000,000,000,000: <<\u5146[>>];\n" +
1140 "10,000,000,000,000,000: =#,##0=;\n" +
1143 "\u96f6; \u4e00; \u4e8c; \u4e09; \u56db; \u4e94; \u516d; \u4e03; \u516b; \u4e5d;\n" +
1145 "20: <<\u5341[>>];\n" +
1146 "100: <<\u767e[>>];\n" +
1147 "1000: <<\u5343[>>];\n" +
1148 "10,000: <<\u4e07[>>];\n" +
1149 "100,000,000: <<\u5104[>>];\n" +
1150 "1,000,000,000,000: <<\u5146[>>];\n" +
1151 "10,000,000,000,000,000: =#,##0=;";
1153 String en_SpelloutRules =
1154 // This rule set shows the normal simple formatting rules for English
1156 // negative number rule. This rule is used to format negative
1157 // numbers. The result of formatting the number's absolute
1158 // value is placed where the >> is.
1160 // faction rule. This rule is used for formatting numbers
1161 // with fractional parts. The result of formatting the
1162 // number's integral part is substituted for the <<, and
1163 // the result of formatting the number's fractional part
1164 // (one digit at a time, e.g., 0.123 is "zero point one two
1165 // three") replaces the >>.
1166 "x.x: << point >>;\n" +
1167 // the rules for the values from 0 to 19 are simply the
1168 // words for those numbers
1169 "zero; one; two; three; four; five; six; seven; eight; nine;\n" +
1170 "ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" +
1171 "seventeen; eighteen; nineteen;\n" +
1172 // beginning at 20, we use the >> to mark the position where
1173 // the result of formatting the number's ones digit. Thus,
1174 // we only need a new rule at every multiple of 10. Text in
1175 // backets is omitted if the value being formatted is an
1176 // even multiple of 10.
1177 "20: twenty[->>];\n" +
1178 "30: thirty[->>];\n" +
1179 "40: forty[->>];\n" +
1180 "50: fifty[->>];\n" +
1181 "60: sixty[->>];\n" +
1182 "70: seventy[->>];\n" +
1183 "80: eighty[->>];\n" +
1184 "90: ninety[->>];\n" +
1185 // beginning at 100, we can use << to mark the position where
1186 // the result of formatting the multiple of 100 is to be
1187 // inserted. Notice also that the meaning of >> has shifted:
1188 // here, it refers to both the ones place and the tens place.
1189 // The meanings of the << and >> tokens depend on the base value
1190 // of the rule. A rule's divisor is (usually) the highest
1191 // power of 10 that is less than or equal to the rule's base
1192 // value. The value being formatted is divided by the rule's
1193 // divisor, and the integral quotient is used to get the text
1194 // for <<, while the remainder is used to produce the text
1195 // for >>. Again, text in brackets is omitted if the value
1196 // being formatted is an even multiple of the rule's divisor
1197 // (in this case, an even multiple of 100)
1198 "100: << hundred[ >>];\n" +
1199 // The rules for the higher numbers work the same way as the
1200 // rule for 100: Again, the << and >> tokens depend on the
1201 // rule's divisor, which for all these rules is also the rule's
1202 // base value. To group by thousand, we simply don't have any
1203 // rules between 1,000 and 1,000,000.
1204 "1000: << thousand[ >>];\n" +
1205 "1,000,000: << million[ >>];\n" +
1206 "1,000,000,000: << billion[ >>];\n" +
1207 "1,000,000,000,000: << trillion[ >>];\n" +
1208 // overflow rule. This rule specifies that values of a
1209 // quadrillion or more are shown in numerals rather than words.
1210 // The == token means to format (with new rules) the value
1211 // being formatted by this rule and place the result where
1212 // the == is. The #,##0 inside the == signs is a
1213 // DecimalFormat pattern. It specifies that the value should
1214 // be formatted with a DecimalFormat object, and that it
1215 // should be formatted with no decimal places, at least one
1216 // digit, and a thousands separator.
1217 "1,000,000,000,000,000: =#,##0=;\n" +
1219 // %default is a more elaborate form of %simplified; It is basically
1220 // the same, except that it introduces "and" before the ones digit
1221 // when appropriate (basically, between the tens and ones digits) and
1222 // separates the thousands groups with commas in values over 100,000.
1224 // negative-number and fraction rules. These are the same
1225 // as those for %simplified, but have to be stated here too
1226 // because this is an entry point
1228 "x.x: << point >>;\n" +
1229 // just use %simplified for values below 100
1230 "=%simplified=;\n" +
1231 // for values from 100 to 9,999 use %%and to decide whether or
1232 // not to interpose the "and"
1233 "100: << hundred[ >%%and>];\n" +
1234 "1000: << thousand[ >%%and>];\n" +
1235 // for values of 100,000 and up, use %%commas to interpose the
1236 // commas in the right places (and also to interpose the "and")
1237 "100,000>>: << thousand[>%%commas>];\n" +
1238 "1,000,000: << million[>%%commas>];\n" +
1239 "1,000,000,000: << billion[>%%commas>];\n" +
1240 "1,000,000,000,000: << trillion[>%%commas>];\n" +
1241 "1,000,000,000,000,000: =#,##0=;\n" +
1242 // if the value passed to this rule set is greater than 100, don't
1243 // add the "and"; if it's less than 100, add "and" before the last
1246 "and =%default=;\n" +
1247 "100: =%default=;\n" +
1248 // this rule set is used to place the commas
1250 // for values below 100, add "and" (the apostrophe at the
1251 // beginning is ignored, but causes the space that follows it
1252 // to be significant: this is necessary because the rules
1253 // calling %%commas don't put a space before it)
1254 "' and =%default=;\n" +
1255 // put a comma after the thousands (or whatever preceded the
1257 "100: , =%default=;\n" +
1258 // put a comma after the millions (or whatever precedes the
1260 "1000: , <%default< thousand, >%default>;\n" +
1262 "1,000,000: , =%default=;" +
1263 // %%lenient-parse isn't really a set of number formatting rules;
1264 // it's a set of collation rules. Lenient-parse mode uses a Collator
1265 // object to compare fragments of the text being parsed to the text
1266 // in the rules, allowing more leeway in the matching text. This set
1267 // of rules tells the formatter to ignore commas when parsing (it
1268 // already ignores spaces, which is why we refer to the space; it also
1269 // ignores hyphens, making "twenty one" and "twenty-one" parse
1271 "%%lenient-parse:\n" +
1272 // "& ' ' , ',' ;\n" +
1273 " &\u0000 << ' ' << ',' << '-'; \n";
1275 String en_GB_SpelloutRules =
1278 "x.x: << point >>;\n" +
1279 "zero; one; two; three; four; five; six; seven; eight; nine;\n" +
1280 "ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n" +
1281 " seventeen; eighteen; nineteen;\n" +
1282 "20: twenty[->>];\n" +
1283 "30: thirty[->>];\n" +
1284 "40: forty[->>];\n" +
1285 "50: fifty[->>];\n" +
1286 "60: sixty[->>];\n" +
1287 "70: seventy[->>];\n" +
1288 "80: eighty[->>];\n" +
1289 "90: ninety[->>];\n" +
1290 "100: << hundred[ >>];\n" +
1291 "1000: << thousand[ >>];\n" +
1292 "1,000,000: << million[ >>];\n" +
1293 "1,000,000,000,000: << billion[ >>];\n" +
1294 "1,000,000,000,000,000: =#,##0=;\n" +
1297 "x.x: << point >>;\n" +
1298 "=%simplified=;\n" +
1299 "100: << hundred[ >%%and>];\n" +
1300 "1000: << thousand[ >%%and>];\n" +
1301 "100,000>>: << thousand[>%%commas>];\n" +
1302 "1,000,000: << million[>%%commas>];\n" +
1303 "1,000,000,000,000: << billion[>%%commas>];\n" +
1304 "1,000,000,000,000,000: =#,##0=;\n" +
1306 "and =%default=;\n" +
1307 "100: =%default=;\n" +
1309 "' and =%default=;\n" +
1310 "100: , =%default=;\n" +
1311 "1000: , <%default< thousand, >%default>;\n" +
1312 "1,000,000: , =%default=;" +
1313 "%%lenient-parse:\n" +
1316 String fr_SpelloutRules =
1317 // the main rule set
1320 "x.x: << virgule >>;\n" +
1321 // words for numbers from 0 to 10
1322 "z\u00e9ro; un; deux; trois; quatre; cinq; six; sept; huit; neuf;\n" +
1323 "dix; onze; douze; treize; quatorze; quinze; seize;\n" +
1324 " dix-sept; dix-huit; dix-neuf;\n" +
1325 // ords for the multiples of 10: %%alt-ones inserts "et"
1327 "20: vingt[->%%alt-ones>];\n" +
1328 "30: trente[->%%alt-ones>];\n" +
1329 "40: quarante[->%%alt-ones>];\n" +
1330 "50: cinquante[->%%alt-ones>];\n" +
1331 // rule for 60. The /20 causes this rule's multiplier to be
1332 // 20 rather than 10, allowinhg us to recurse for all values
1334 "60/20: soixante[->%%alt-ones>];\n" +
1335 // ...except for 71, which must be special-cased
1336 "71: soixante et onze;\n" +
1337 // at 72, we have to repeat the rule for 60 to get us to 79
1338 "72/20: soixante->%%alt-ones>;\n" +
1339 // at 80, we state a new rule with the phrase for 80. Since
1340 // it changes form when there's a ones digit, we need a second
1341 // rule at 81. This rule also includes "/20," allowing it to
1342 // be used correctly for all values up to 99
1343 "80: quatre-vingts; 81/20: quatre-vingt->>;\n" +
1344 // "cent" becomes plural when preceded by a multiplier, and
1345 // the multiplier is omitted from the singular form
1346 "100: cent[ >>];\n" +
1347 "200: << cents[ >>];\n" +
1348 "1000: mille[ >>];\n" +
1349 // values from 1,100 to 1,199 are rendered as "onze cents..."
1350 // instead of "mille cent..." The > after "1000" decreases
1351 // the rule's exponent, causing its multiplier to be 100 instead
1352 // of 1,000. This prevents us from getting "onze cents cent
1353 // vingt-deux" ("eleven hundred one hundred twenty-two").
1354 "1100>: onze cents[ >>];\n" +
1355 // at 1,200, we go back to formating in thousands, so we
1356 // repeat the rule for 1,000
1357 "1200: mille >>;\n" +
1358 // at 2,000, the multiplier is added
1359 "2000: << mille[ >>];\n" +
1360 "1,000,000: << million[ >>];\n" +
1361 "1,000,000,000: << milliard[ >>];\n" +
1362 "1,000,000,000,000: << billion[ >>];\n" +
1363 "1,000,000,000,000,000: =#,##0=;\n" +
1364 // %%alt-ones is used to insert "et" when the ones digit is 1
1366 "; et-un; =%main=;\n" +
1367 "%%lenient-parse:\n" +
1368 "&\u0000 << ' ' << ',' << '-';\n";
1370 String de_SpelloutRules =
1371 // 1 is "eins" when by itself, but turns into "ein" in most
1375 "x.x: << komma >>;\n" +
1376 "null; eins; =%%main=;\n" +
1378 // words for numbers from 0 to 12. Notice that the values
1379 // from 13 to 19 can derived algorithmically, unlike in most
1381 "null; ein; zwei; drei; vier; f\u00fcnf; sechs; sieben; acht; neun;\n" +
1382 "zehn; elf; zw\u00f6lf; >>zehn;\n" +
1383 // rules for the multiples of 10. Notice that the ones digit
1384 // goes on the front
1385 "20: [>>und]zwanzig;\n" +
1386 "30: [>>und]drei\u00dfig;\n" +
1387 "40: [>>und]vierzig;\n" +
1388 "50: [>>und]f\u00fcnfzig;\n" +
1389 "60: [>>und]sechzig;\n" +
1390 "70: [>>und]siebzig;\n" +
1391 "80: [>>und]achtzig;\n" +
1392 "90: [>>und]neunzig;\n" +
1393 "100: hundert[>%alt-ones>];\n" +
1394 "200: <<hundert[>%alt-ones>];\n" +
1395 "1000: tausend[>%alt-ones>];\n" +
1396 "2000: <<tausend[>%alt-ones>];\n" +
1397 "1,000,000: eine Million[ >%alt-ones>];\n" +
1398 "2,000,000: << Millionen[ >%alt-ones>];\n" +
1399 "1,000,000,000: eine Milliarde[ >%alt-ones>];\n" +
1400 "2,000,000,000: << Milliarden[ >%alt-ones>];\n" +
1401 "1,000,000,000,000: eine Billion[ >%alt-ones>];\n" +
1402 "2,000,000,000,000: << Billionen[ >%alt-ones>];\n" +
1403 "1,000,000,000,000,000: =#,##0=;" +
1404 "%%lenient-parse:\n" +
1405 "&\u0000 << ' ' << '-'\n" +
1406 "& ae , \u00e4 & ae , \u00c4\n" +
1407 "& oe , \u00f6 & oe , \u00d6\n" +
1408 "& ue , \u00fc & ue , \u00dc\n";
1410 String it_SpelloutRules =
1411 // main rule set. Follows the patterns of the preceding rule sets,
1412 // except that the final vowel is omitted from words ending in
1413 // vowels when they are followed by another word; instead, we have
1414 // separate rule sets that are identical to this one, except that
1415 // all the words that don't begin with a vowel have a vowel tacked
1416 // onto them at the front. A word ending in a vowel calls a
1417 // substitution that will supply that vowel, unless that vowel is to
1421 "x.x: << virgola >>;\n" +
1422 "zero; uno; due; tre; quattro; cinque; sei; sette; otto; nove;\n" +
1423 "dieci; undici; dodici; tredici; quattordici; quindici; sedici;\n" +
1424 " diciasette; diciotto; diciannove;\n" +
1425 "20: venti; vent>%%with-i>;\n" +
1426 "30: trenta; trent>%%with-i>;\n" +
1427 "40: quaranta; quarant>%%with-a>;\n" +
1428 "50: cinquanta; cinquant>%%with-a>;\n" +
1429 "60: sessanta; sessant>%%with-a>;\n" +
1430 "70: settanta; settant>%%with-a>;\n" +
1431 "80: ottanta; ottant>%%with-a>;\n" +
1432 "90: novanta; novant>%%with-a>;\n" +
1433 "100: cento; cent[>%%with-o>];\n" +
1434 "200: <<cento; <<cent[>%%with-o>];\n" +
1435 "1000: mille; mill[>%%with-i>];\n" +
1436 "2000: <<mila; <<mil[>%%with-a>];\n" +
1437 "100,000>>: <<mila[ >>];\n" +
1438 "1,000,000: =#,##0= (incomplete data);\n" +
1440 "azero; uno; adue; atre; aquattro; acinque; asei; asette; otto; anove;\n" +
1441 "adieci; undici; adodici; atredici; aquattordici; aquindici; asedici;\n" +
1442 " adiciasette; adiciotto; adiciannove;\n" +
1443 "20: aventi; avent>%%with-i>;\n" +
1444 "30: atrenta; atrent>%%with-i>;\n" +
1445 "40: aquaranta; aquarant>%%with-a>;\n" +
1446 "50: acinquanta; acinquant>%%with-a>;\n" +
1447 "60: asessanta; asessant>%%with-a>;\n" +
1448 "70: asettanta; asettant>%%with-a>;\n" +
1449 "80: ottanta; ottant>%%with-a>;\n" +
1450 "90: anovanta; anovant>%%with-a>;\n" +
1451 "100: acento; acent[>%%with-o>];\n" +
1452 "200: <%%with-a<cento; <%%with-a<cent[>%%with-o>];\n" +
1453 "1000: amille; amill[>%%with-i>];\n" +
1454 "2000: <%%with-a<mila; <%%with-a<mil[>%%with-a>];\n" +
1455 "100,000: =%main=;\n" +
1457 "izero; uno; idue; itre; iquattro; icinque; isei; isette; otto; inove;\n" +
1458 "idieci; undici; idodici; itredici; iquattordici; iquindici; isedici;\n" +
1459 " idiciasette; idiciotto; idiciannove;\n" +
1460 "20: iventi; ivent>%%with-i>;\n" +
1461 "30: itrenta; itrent>%%with-i>;\n" +
1462 "40: iquaranta; iquarant>%%with-a>;\n" +
1463 "50: icinquanta; icinquant>%%with-a>;\n" +
1464 "60: isessanta; isessant>%%with-a>;\n" +
1465 "70: isettanta; isettant>%%with-a>;\n" +
1466 "80: ottanta; ottant>%%with-a>;\n" +
1467 "90: inovanta; inovant>%%with-a>;\n" +
1468 "100: icento; icent[>%%with-o>];\n" +
1469 "200: <%%with-i<cento; <%%with-i<cent[>%%with-o>];\n" +
1470 "1000: imille; imill[>%%with-i>];\n" +
1471 "2000: <%%with-i<mila; <%%with-i<mil[>%%with-a>];\n" +
1472 "100,000: =%main=;\n" +
1474 "ozero; uno; odue; otre; oquattro; ocinque; osei; osette; otto; onove;\n" +
1475 "odieci; undici; ododici; otredici; oquattordici; oquindici; osedici;\n" +
1476 " odiciasette; odiciotto; odiciannove;\n" +
1477 "20: oventi; ovent>%%with-i>;\n" +
1478 "30: otrenta; otrent>%%with-i>;\n" +
1479 "40: oquaranta; oquarant>%%with-a>;\n" +
1480 "50: ocinquanta; ocinquant>%%with-a>;\n" +
1481 "60: osessanta; osessant>%%with-a>;\n" +
1482 "70: osettanta; osettant>%%with-a>;\n" +
1483 "80: ottanta; ottant>%%with-a>;\n" +
1484 "90: onovanta; onovant>%%with-a>;\n" +
1485 "100: ocento; ocent[>%%with-o>];\n" +
1486 "200: <%%with-o<cento; <%%with-o<cent[>%%with-o>];\n" +
1487 "1000: omille; omill[>%%with-i>];\n" +
1488 "2000: <%%with-o<mila; <%%with-o<mil[>%%with-a>];\n" +
1489 "100,000: =%main=;\n" ;
1491 String en_OrdinalRules =
1492 // this rule set formats the numeral and calls %%abbrev to
1493 // supply the abbreviation
1495 "=#,##0==%%abbrev=;\n" +
1496 // this rule set supplies the abbreviation
1498 // the abbreviations. Everything from 4 to 19 ends in "th"
1499 "th; st; nd; rd; th;\n" +
1500 // at 20, we begin repeating the cycle every 10 (13 is "13th",
1501 // but 23 and 33 are "23rd" and "33rd") We do this by
1502 // ignoring all bug the ones digit in selecting the abbreviation
1504 // at 100, we repeat the whole cycle by considering only the
1505 // tens and ones digits in picking an abbreviation
1508 String en_DurationRules =
1509 // main rule set for formatting with words
1511 // take care of singular and plural forms of "second"
1512 "0 seconds; 1 second; =0= seconds;\n" +
1513 // use %%min to format values greater than 60 seconds
1514 "60/60: <%%min<[, >>];\n" +
1515 // use %%hr to format values greater than 3,600 seconds
1516 // (the ">>>" below causes us to see the number of minutes
1517 // when when there are zero minutes)
1518 "3600/60: <%%hr<[, >>>];\n" +
1519 // this rule set takes care of the singular and plural forms
1522 "0 minutes; 1 minute; =0= minutes;\n" +
1523 // this rule set takes care of the singular and plural forms
1526 "0 hours; 1 hour; =0= hours;\n" +
1528 // main rule set for formatting in numerals
1530 // values below 60 seconds are shown with "sec."
1532 // higher values are shown with colons: %%min-sec is used for
1533 // values below 3,600 seconds...
1534 "60: =%%min-sec=;\n" +
1535 // ...and %%hr-min-sec is used for values of 3,600 seconds
1537 "3600: =%%hr-min-sec=;\n" +
1538 // this rule causes values of less than 10 minutes to show without
1543 // this rule set is used for values of 3,600 or more. Minutes are always
1544 // shown, and always shown with two digits
1547 "60/60: <00<>>;\n" +
1548 "3600/60: <#,##0<:>>>;\n" +
1549 // the lenient-parse rules allow several different characters to be used
1550 // as delimiters between hours, minutes, and seconds
1551 "%%lenient-parse:\n" +
1552 "& ':' = '.' = ' ' = '-';\n";
1554 HashMap cannedData = new HashMap();
1557 cannedData.put("en_CA/SpelloutRules", en_SpelloutRules);
1558 cannedData.put("en_CA/OrdinalRules", en_OrdinalRules);
1559 cannedData.put("en_CA/DurationRules", en_DurationRules);
1561 cannedData.put("fr_CA/SpelloutRules", fr_SpelloutRules);
1562 cannedData.put("fr_CA/OrdinalRules", xx_OrdinalRules);
1563 cannedData.put("fr_CA/DurationRules", xx_DurationRules);
1565 cannedData.put("zh_CN/SpelloutRules", en_SpelloutRules);
1566 cannedData.put("zh_CN/OrdinalRules", en_OrdinalRules);
1567 cannedData.put("zh_CH/DurationRules", xx_DurationRules);
1569 cannedData.put("zh/SpelloutRules", en_SpelloutRules);
1570 cannedData.put("zh/OrdinalRules", en_OrdinalRules);
1571 cannedData.put("zh_DurationRules", xx_DurationRules);
1573 cannedData.put("en/SpelloutRules", en_SpelloutRules);
1574 cannedData.put("en/OrdinalRules", en_OrdinalRules);
1575 cannedData.put("en/DurationRules", en_DurationRules);
1577 cannedData.put("fr_FR/SpelloutRules", fr_SpelloutRules);
1578 cannedData.put("fr_FR/OrdinalRules", xx_OrdinalRules);
1579 cannedData.put("fr_FR/DurationRules", xx_DurationRules);
1581 cannedData.put("fr/SpelloutRules", fr_SpelloutRules);
1582 cannedData.put("fr/OrdinalRules", xx_OrdinalRules);
1583 cannedData.put("fr/DurationRules", xx_DurationRules);
1585 cannedData.put("de/SpelloutRules", de_SpelloutRules);
1586 cannedData.put("de/OrdinalRules", xx_OrdinalRules);
1587 cannedData.put("de/DurationRules", xx_DurationRules);
1589 cannedData.put("de_DE/SpelloutRules", de_SpelloutRules);
1590 cannedData.put("de_DE/OrdinalRules", xx_OrdinalRules);
1591 cannedData.put("de_DE/DurationRules", xx_DurationRules);
1593 cannedData.put("it/SpelloutRules", it_SpelloutRules);
1594 cannedData.put("it/OrdinalRules", xx_OrdinalRules);
1595 cannedData.put("it/DurationRules", xx_DurationRules);
1597 cannedData.put("it_IT/SpelloutRules", it_SpelloutRules);
1598 cannedData.put("it_IT/OrdinalRules", xx_OrdinalRules);
1599 cannedData.put("it_IT/DuratonRules", xx_DurationRules);
1601 cannedData.put("ko_KR/SpelloutRules", en_SpelloutRules);
1602 cannedData.put("ko_KR/OrdinalRules", en_OrdinalRules);
1603 cannedData.put("ko_KR/DurationRules", en_DurationRules);
1605 cannedData.put("ko/SpelloutRules", en_SpelloutRules);
1606 cannedData.put("ko/OrdinalRules", en_OrdinalRules);
1607 cannedData.put("ko/DurationRules", en_DurationRules);
1609 cannedData.put("zh_Hans_CN/SpelloutRules", en_SpelloutRules);
1610 cannedData.put("zh_Hans_CN/OrdinalRules", en_OrdinalRules);
1611 cannedData.put("zh_Hans_CH/DurationRules", xx_DurationRules);
1613 cannedData.put("zh_Hant_TW/SpelloutRules", en_SpelloutRules);
1614 cannedData.put("zh_Hant_TW/OrdinalRules", en_OrdinalRules);
1615 cannedData.put("zh_Hant_TW/DurationRules", en_DurationRules);
1617 cannedData.put("zh_TW/SpelloutRules", en_SpelloutRules);
1618 cannedData.put("zh_TW/OrdinalRules", en_OrdinalRules);
1619 cannedData.put("zh_TW/DurationRules", en_DurationRules);
1621 cannedData.put("en_GB/SpelloutRules", en_GB_SpelloutRules);
1622 cannedData.put("en_GB/OrdinalRules", en_OrdinalRules);
1623 cannedData.put("en_GB/DurationRules", en_DurationRules);
1625 cannedData.put("en_US/SpelloutRules", en_SpelloutRules);
1626 cannedData.put("en_US/OrdinalRules", en_OrdinalRules);
1627 cannedData.put("en_US/DurationRules", en_DurationRules);
1629 cannedData.put("ja/SpelloutRules", ja_spelloutRules);
1630 cannedData.put("ja/OrdinalRules", xx_OrdinalRules);
1631 cannedData.put("ja/DurationRules", xx_DurationRules);
1633 cannedData.put("ja_JP/SpelloutRules", ja_spelloutRules);
1634 cannedData.put("ja_JP/OrdinalRules", xx_OrdinalRules);
1635 cannedData.put("ja_JP/DurationRules", xx_DurationRules);
1638 int types[] = {RuleBasedNumberFormat.SPELLOUT, RuleBasedNumberFormat.ORDINAL, RuleBasedNumberFormat.DURATION};
1639 String typeNames[] = {"SpelloutRules", "OrdinalRules", "DurationRules"};
1641 public Object[] getTestObjects()
1643 Locale locales[] = SerializableTest.getLocales();
1644 RuleBasedNumberFormat formats[] = new RuleBasedNumberFormat[types.length * locales.length];
1647 for (int t = 0; t < types.length; t += 1) {
1648 for (int l = 0; l < locales.length; l += 1) {
1649 String cannedRules = (String) cannedData.get(locales[l].toString() + "/" + typeNames[t]);
1651 if (cannedRules != null) {
1652 formats[i++] = new RuleBasedNumberFormat(cannedRules, locales[l]);
1654 formats[i++] = new RuleBasedNumberFormat(locales[l], types[t]);
1663 public static class DecimalFormatSymbolsHandler implements SerializableTest.Handler
1665 public Object[] getTestObjects()
1667 Locale locales[] = SerializableTest.getLocales();
1668 DecimalFormatSymbols dfs[] = new DecimalFormatSymbols[locales.length];
1670 for (int i = 0; i < locales.length; i += 1) {
1671 ULocale uloc = ULocale.forLocale(locales[i]);
1673 dfs[i] = getCannedDecimalFormatSymbols(uloc);
1675 // System.out.println("\n " + uloc.toString() + " = \"" +
1676 // com.ibm.icu.impl.Utility.escape(String.valueOf(getCharSymbols(dfs[i]), 0, 12)) + "\"");
1682 public boolean hasSameBehavior(Object a, Object b)
1684 DecimalFormatSymbols dfs_a = (DecimalFormatSymbols) a;
1685 DecimalFormatSymbols dfs_b = (DecimalFormatSymbols) b;
1686 String strings_a[] = getStringSymbols(dfs_a);
1687 String strings_b[] = getStringSymbols(dfs_b);
1688 char chars_a[] = getCharSymbols(dfs_a);
1689 char chars_b[] = getCharSymbols(dfs_b);
1691 return SerializableTest.compareStrings(strings_a, strings_b) && SerializableTest.compareChars(chars_a, chars_b);
1695 public static class CurrencyPluralInfoHandler implements SerializableTest.Handler
1697 public Object[] getTestObjects()
1699 CurrencyPluralInfo currencyPluralInfo[] = {
1700 new CurrencyPluralInfo()
1702 currencyPluralInfo[0].setPluralRules("one: n is 1; few: n in 2..4");
1703 currencyPluralInfo[0].setCurrencyPluralPattern("few", "few currency");
1704 return currencyPluralInfo;
1707 public boolean hasSameBehavior(Object a, Object b)
1713 public static class MessageFormatHandler implements SerializableTest.Handler
1715 public Object[] getTestObjects()
1717 MessageFormat formats[] = {new MessageFormat("pattern{0}")};
1722 public boolean hasSameBehavior(Object a, Object b)
1724 MessageFormat mfa = (MessageFormat) a;
1725 MessageFormat mfb = (MessageFormat) b;
1726 Object arguments[] = {new Integer(123456)};
1728 return mfa.format(arguments) != mfb.format(arguments);
1732 //#if defined(FOUNDATION10) || defined(J2SE13)
1734 public static class MessageFormatFieldHandler implements SerializableTest.Handler
1736 public Object[] getTestObjects()
1738 return new Object[] {MessageFormat.Field.ARGUMENT};
1741 public boolean hasSameBehavior(Object a, Object b)
1748 public static class DateFormatHandler implements SerializableTest.Handler
1750 static HashMap cannedPatterns = new HashMap();
1751 static Date fixedDate;
1754 cannedPatterns.put("en_CA", "EEEE, MMMM d, yyyy h:mm:ss a z");
1755 cannedPatterns.put("fr_CA", "EEEE d MMMM yyyy HH' h 'mm' min 'ss' s 'z");
1756 cannedPatterns.put("zh_Hans_CN", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE ahh'\u65F6'mm'\u5206'ss'\u79D2' z");
1757 cannedPatterns.put("zh_CN", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE ahh'\u65F6'mm'\u5206'ss'\u79D2' z");
1758 cannedPatterns.put("zh", "EEEE, yyyy MMMM dd HH:mm:ss z");
1759 cannedPatterns.put("en", "EEEE, MMMM d, yyyy h:mm:ss a z");
1760 cannedPatterns.put("fr_FR", "EEEE d MMMM yyyy HH' h 'mm z");
1761 cannedPatterns.put("fr", "EEEE d MMMM yyyy HH' h 'mm z");
1762 cannedPatterns.put("de", "EEEE, d. MMMM yyyy H:mm' Uhr 'z");
1763 cannedPatterns.put("de_DE", "EEEE, d. MMMM yyyy H:mm' Uhr 'z");
1764 cannedPatterns.put("it", "EEEE d MMMM yyyy HH:mm:ss z");
1765 cannedPatterns.put("it_IT", "EEEE d MMMM yyyy HH:mm:ss z");
1766 cannedPatterns.put("ja_JP", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE H'\u6642'mm'\u5206'ss'\u79D2'z");
1767 cannedPatterns.put("ja", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE H'\u6642'mm'\u5206'ss'\u79D2'z");
1768 cannedPatterns.put("ko_KR", "yyyy'\uB144' M'\uC6D4' d'\uC77C' EEEE a hh'\uC2DC' mm'\uBD84' ss'\uCD08' z");
1769 cannedPatterns.put("ko", "yyyy'\uB144' M'\uC6D4' d'\uC77C' EEEE a hh'\uC2DC' mm'\uBD84' ss'\uCD08' z");
1770 cannedPatterns.put("zh_Hant_TW", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE ahh'\u6642'mm'\u5206'ss'\u79D2' z");
1771 cannedPatterns.put("zh_TW", "yyyy'\u5E74'M'\u6708'd'\u65E5'EEEE ahh'\u6642'mm'\u5206'ss'\u79D2' z");
1772 cannedPatterns.put("en_GB", "EEEE, d MMMM yyyy HH:mm:ss z");
1773 cannedPatterns.put("en_US", "EEEE, MMMM d, yyyy h:mm:ss a z");
1775 // Get a date that will likely not move in or out of Daylight savings time...
1776 Calendar cal = Calendar.getInstance(Locale.US);
1779 cal.set(2007, Calendar.JANUARY, 1, 12, 0, 0); // January 1, 2007 12:00:00 PM.
1780 fixedDate = cal.getTime();
1783 public Object[] getTestObjects()
1785 Locale locales[] = SerializableTest.getLocales();
1786 DateFormat formats[] = new DateFormat[locales.length];
1788 for (int i = 0; i < locales.length; i += 1) {
1789 ULocale uloc = ULocale.forLocale(locales[i]);
1791 //formats[i] = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locales[i]);
1792 formats[i] = getCannedSimpleDateFormat((String)cannedPatterns.get(uloc.toString()), uloc);
1798 public boolean hasSameBehavior(Object a, Object b)
1800 DateFormat dfa = (DateFormat) a;
1801 DateFormat dfb = (DateFormat) b;
1802 //Date date = new Date(System.currentTimeMillis());
1803 String sfa = dfa.format(fixedDate);
1804 String sfb = dfb.format(fixedDate);
1806 if (!sfa.equals(sfb)) {
1808 // In ICU3.8, localized GMT format pattern was added in
1809 // DateFormatSymbols, which has no public setter.
1810 // The difference of locale data for localized GMT format
1811 // will produce different format result. This is a temporary
1812 // workaround for the issue.
1813 DateFormatSymbols dfsa = ((SimpleDateFormat)dfa).getDateFormatSymbols();
1814 DateFormatSymbols tmp = (DateFormatSymbols)((SimpleDateFormat)dfb).getDateFormatSymbols().clone();
1816 tmp.setMonths(dfsa.getMonths());
1817 tmp.setShortMonths(dfsa.getShortMonths());
1818 tmp.setWeekdays(dfsa.getWeekdays());
1819 tmp.setShortWeekdays(dfsa.getShortWeekdays());
1820 tmp.setAmPmStrings(dfsa.getAmPmStrings());
1822 ((SimpleDateFormat)dfa).setDateFormatSymbols(tmp);
1824 sfa = dfa.format(fixedDate);
1827 return sfa.equals(sfb);
1832 //#if defined(FOUNDATION10) || defined(J2SE13)
1834 public static class DateFormatFieldHandler implements SerializableTest.Handler
1836 public Object[] getTestObjects() {
1837 return new Object[] {
1838 DateFormat.Field.AM_PM,
1839 DateFormat.Field.DAY_OF_MONTH,
1840 DateFormat.Field.DAY_OF_WEEK,
1841 DateFormat.Field.DAY_OF_WEEK_IN_MONTH,
1842 DateFormat.Field.DAY_OF_YEAR,
1843 DateFormat.Field.ERA,
1844 DateFormat.Field.HOUR_OF_DAY0,
1845 DateFormat.Field.HOUR_OF_DAY1,
1846 DateFormat.Field.HOUR0,
1847 DateFormat.Field.HOUR1,
1848 DateFormat.Field.MILLISECOND,
1849 DateFormat.Field.MINUTE,
1850 DateFormat.Field.MONTH,
1851 DateFormat.Field.SECOND,
1852 DateFormat.Field.TIME_ZONE,
1853 DateFormat.Field.WEEK_OF_MONTH,
1854 DateFormat.Field.WEEK_OF_YEAR,
1855 DateFormat.Field.YEAR,
1856 DateFormat.Field.DOW_LOCAL,
1857 DateFormat.Field.EXTENDED_YEAR,
1858 DateFormat.Field.JULIAN_DAY,
1859 DateFormat.Field.MILLISECONDS_IN_DAY,
1860 DateFormat.Field.YEAR_WOY,
1861 DateFormat.Field.QUARTER
1864 public boolean hasSameBehavior(Object a, Object b)
1871 public static class DateFormatSymbolsHandler implements SerializableTest.Handler
1874 public Object[] getTestObjects()
1876 Locale locales[] = SerializableTest.getLocales();
1877 DateFormatSymbols dfs[] = new DateFormatSymbols[locales.length];
1879 for (int i = 0; i < locales.length; i += 1) {
1880 ULocale uloc = ULocale.forLocale(locales[i]);
1882 dfs[i] = getCannedDateFormatSymbols(uloc);
1888 public boolean hasSameBehavior(Object a, Object b)
1890 DateFormatSymbols dfs_a = (DateFormatSymbols) a;
1891 DateFormatSymbols dfs_b = (DateFormatSymbols) b;
1892 String months_a[] = dfs_a.getMonths();
1893 String months_b[] = dfs_b.getMonths();
1895 return SerializableTest.compareStrings(months_a, months_b);
1899 public static class SimpleDateFormatHandler extends DateFormatHandler
1901 String patterns[] = {
1902 "EEEE, yyyy MMMM dd",
1908 public Object[] getTestObjects()
1910 Locale locales[] = SerializableTest.getLocales();
1911 SimpleDateFormat dateFormats[] = new SimpleDateFormat[patterns.length * locales.length];
1914 for (int p = 0; p < patterns.length; p += 1) {
1915 for (int l = 0; l < locales.length; l += 1) {
1916 dateFormats[i++] = getCannedSimpleDateFormat(patterns[p], ULocale.forLocale(locales[l]));
1924 public static class DateIntervalFormatHandler implements SerializableTest.Handler
1926 public Object[] getTestObjects()
1928 DateIntervalFormat dateIntervalFormats[] = {
1929 DateIntervalFormat.getInstance("yMMMMEEEEd")
1931 return dateIntervalFormats;
1934 public boolean hasSameBehavior(Object a, Object b)
1936 DateIntervalFormat dfa = (DateIntervalFormat) a;
1937 DateIntervalFormat dfb = (DateIntervalFormat) b;
1938 DateInterval dateInterval = new DateInterval(1, System.currentTimeMillis());
1939 String sfa = dfa.format(dateInterval);
1940 String sfb = dfb.format(dateInterval);
1942 return sfa.equals(sfb);
1947 public static class DateIntervalInfoHandler implements SerializableTest.Handler
1949 public Object[] getTestObjects()
1951 DateIntervalInfo dateIntervalInfo[] = {
1952 new DateIntervalInfo()
1954 dateIntervalInfo[0].setIntervalPattern("yMd", Calendar.YEAR, "yy/MM/dd - yy/MM/dd");
1955 dateIntervalInfo[0].setIntervalPattern("yMd", Calendar.MONTH, "yy/MM - MM/dd");
1956 return dateIntervalInfo;
1959 public boolean hasSameBehavior(Object a, Object b)
1966 public static class PatternInfoHandler implements SerializableTest.Handler
1968 public Object[] getTestObjects()
1970 DateIntervalInfo.PatternInfo patternInfo[] = {
1971 new DateIntervalInfo.PatternInfo("yyyy MMM dd - ",
1978 public boolean hasSameBehavior(Object a, Object b)
1984 public static class ChineseDateFormatHandler extends DateFormatHandler
1986 String patterns[] = {
1993 public Object[] getTestObjects()
1995 Locale locales[] = SerializableTest.getLocales();
1996 ChineseDateFormat dateFormats[] = new ChineseDateFormat[patterns.length * locales.length];
1999 for (int p = 0; p < patterns.length; p += 1) {
2000 for (int l = 0; l < locales.length; l += 1) {
2001 ULocale locale = new ULocale(locales[l].toString() + "@calendar=chinese");
2003 dateFormats[i++] = new ChineseDateFormat(patterns[p], locale);
2011 //#if defined(FOUNDATION10) || defined(J2SE13)
2013 public static class ChineseDateFormatFieldHandler implements SerializableTest.Handler
2015 public Object[] getTestObjects() {
2016 return new Object[] {
2017 ChineseDateFormat.Field.IS_LEAP_MONTH
2020 public boolean hasSameBehavior(Object a, Object b)
2027 public static class ChineseDateFormatSymbolsHandler extends DateFormatSymbolsHandler
2029 public Object[] getTestObjects()
2031 Locale locales[] = SerializableTest.getLocales();
2032 ChineseDateFormatSymbols cdfs[] = new ChineseDateFormatSymbols[locales.length];
2034 for (int i = 0; i < locales.length; i += 1) {
2035 ULocale uloc = ULocale.forLocale(locales[i]);
2037 cdfs[i] = new ChineseDateFormatSymbols(uloc);
2038 cdfs[i].setMonths((String[]) cannedMonthNames.get(uloc.toString()));
2044 public boolean hasSameBehavior(Object a, Object b)
2046 if (! super.hasSameBehavior(a, b)) {
2050 ChineseDateFormatSymbols cdfs_a = (ChineseDateFormatSymbols) a;
2051 ChineseDateFormatSymbols cdfs_b = (ChineseDateFormatSymbols) b;
2053 return cdfs_a.getLeapMonth(0).equals(cdfs_b.getLeapMonth(0)) &&
2054 cdfs_a.getLeapMonth(1).equals(cdfs_b.getLeapMonth(1));
2058 //#if defined(FOUNDATION10) || defined(J2SE13)
2060 public static class NumberFormatFieldHandler implements SerializableTest.Handler
2062 public Object[] getTestObjects()
2064 NumberFormat.Field fields[] = {
2065 NumberFormat.Field.CURRENCY, NumberFormat.Field.DECIMAL_SEPARATOR, NumberFormat.Field.EXPONENT,
2066 NumberFormat.Field.EXPONENT_SIGN, NumberFormat.Field.EXPONENT_SYMBOL, NumberFormat.Field.FRACTION,
2067 NumberFormat.Field.GROUPING_SEPARATOR, NumberFormat.Field.INTEGER, NumberFormat.Field.PERCENT,
2068 NumberFormat.Field.PERMILLE, NumberFormat.Field.SIGN
2074 public boolean hasSameBehavior(Object a, Object b)
2076 NumberFormat.Field field_a = (NumberFormat.Field) a;
2077 NumberFormat.Field field_b = (NumberFormat.Field) b;
2079 return field_a.toString().equals(field_b.toString());
2084 public static class DateNumberFormatHandler implements SerializableTest.Handler
2086 public Object[] getTestObjects()
2088 Locale locales[] = SerializableTest.getLocales();
2089 DateNumberFormat[] dnfmts = new DateNumberFormat[locales.length];
2090 for (int i = 0; i < locales.length; i++) {
2091 ULocale uloc = ULocale.forLocale(locales[i]);
2092 dnfmts[i] = new DateNumberFormat(uloc,'0');
2097 public boolean hasSameBehavior(Object a, Object b) {
2102 public static class PluralFormatHandler implements SerializableTest.Handler {
2103 public Object[] getTestObjects() {
2104 Locale[] locales = { Locale.US }; // main test is in plural rules handler
2105 PluralFormat[] plfmts = new PluralFormat[locales.length];
2106 for (int i = 0; i < locales.length; i++) {
2107 ULocale uloc = ULocale.forLocale(locales[i]);
2109 plfmts[i] = new PluralFormat(uloc, "one{1 foo} other{# foo}");
2110 } catch (Exception e) {
2111 e.printStackTrace();
2116 public boolean hasSameBehavior(Object a, Object b) {
2117 PluralFormat pfa = (PluralFormat)a;
2118 PluralFormat pfb = (PluralFormat)b;
2119 boolean isSame = true;
2120 for (int i = 0; i < 10; i++) {
2121 String texta = pfa.format(i);
2122 String textb = pfb.format(i);
2123 if (!texta.equals(textb)) {
2132 public static class PluralRulesHandler implements SerializableTest.Handler {
2133 public Object[] getTestObjects() {
2134 String[] localeNames = {"ja","da","fr","lv","ga","ro","lt","hr","cs","pl","sl"};
2135 PluralRules[] plrulz = new PluralRules[localeNames.length];
2136 for (int i = 0; i < localeNames.length; i++) {
2137 ULocale uloc = ULocale.createCanonical(localeNames[i]);
2139 plrulz[i] = PluralRules.forLocale(uloc);
2140 } catch (Exception e) {
2141 e.printStackTrace();
2146 public boolean hasSameBehavior(Object a, Object b) {
2151 public static class TimeUnitFormatHandler implements SerializableTest.Handler {
2152 // TODO - more test coverage!
2153 public Object[] getTestObjects() {
2154 return new Object[] { new TimeUnitFormat().setLocale(ULocale.ENGLISH) };
2156 public boolean hasSameBehavior(Object a, Object b) {
2157 TimeUnitFormat tufa = (TimeUnitFormat)a;
2158 TimeUnitFormat tufb = (TimeUnitFormat)b;
2160 TimeUnitAmount amount = new TimeUnitAmount(3, TimeUnit.HOUR);
2161 String resa = tufa.format(amount);
2162 String resb = tufb.format(amount);
2164 return resa.equals(resb);
2168 public static void main(String[] args)
2170 // nothing needed...