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