]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/text/DateFormatSymbols.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / text / DateFormatSymbols.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 1996-2009, International Business Machines Corporation and    *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 \r
8 package com.ibm.icu.text;\r
9 \r
10 import java.io.IOException;\r
11 import java.io.ObjectInputStream;\r
12 import java.io.Serializable;\r
13 import java.util.Locale;\r
14 import java.util.MissingResourceException;\r
15 import java.util.ResourceBundle;\r
16 \r
17 import com.ibm.icu.impl.CalendarData;\r
18 import com.ibm.icu.impl.ICUCache;\r
19 import com.ibm.icu.impl.ICUResourceBundle;\r
20 import com.ibm.icu.impl.SimpleCache;\r
21 import com.ibm.icu.impl.Utility;\r
22 import com.ibm.icu.impl.ZoneMeta;\r
23 import com.ibm.icu.impl.ZoneStringFormat;\r
24 import com.ibm.icu.util.Calendar;\r
25 import com.ibm.icu.util.ULocale;\r
26 import com.ibm.icu.util.UResourceBundle;\r
27 \r
28 /**\r
29  * <code>DateFormatSymbols</code> is a public class for encapsulating\r
30  * localizable date-time formatting data, such as the names of the\r
31  * months, the names of the days of the week, and the time zone data.\r
32  * <code>DateFormat</code> and <code>SimpleDateFormat</code> both use\r
33  * <code>DateFormatSymbols</code> to encapsulate this information.\r
34  *\r
35  * <p>\r
36  * Typically you shouldn't use <code>DateFormatSymbols</code> directly.\r
37  * Rather, you are encouraged to create a date-time formatter with the\r
38  * <code>DateFormat</code> class's factory methods: <code>getTimeInstance</code>,\r
39  * <code>getDateInstance</code>, or <code>getDateTimeInstance</code>.\r
40  * These methods automatically create a <code>DateFormatSymbols</code> for\r
41  * the formatter so that you don't have to. After the\r
42  * formatter is created, you may modify its format pattern using the\r
43  * <code>setPattern</code> method. For more information about\r
44  * creating formatters using <code>DateFormat</code>'s factory methods,\r
45  * see {@link DateFormat}.\r
46  *\r
47  * <p>\r
48  * If you decide to create a date-time formatter with a specific\r
49  * format pattern for a specific locale, you can do so with:\r
50  * <blockquote>\r
51  * <pre>\r
52  * new SimpleDateFormat(aPattern, new DateFormatSymbols(aLocale)).\r
53  * </pre>\r
54  * </blockquote>\r
55  *\r
56  * <p>\r
57  * <code>DateFormatSymbols</code> objects are clonable. When you obtain\r
58  * a <code>DateFormatSymbols</code> object, feel free to modify the\r
59  * date-time formatting data. For instance, you can replace the localized\r
60  * date-time format pattern characters with the ones that you feel easy\r
61  * to remember. Or you can change the representative cities\r
62  * to your favorite ones.\r
63  *\r
64  * <p>\r
65  * New <code>DateFormatSymbols</code> subclasses may be added to support\r
66  * <code>SimpleDateFormat</code> for date-time formatting for additional locales.\r
67 \r
68  * @see          DateFormat\r
69  * @see          SimpleDateFormat\r
70  * @see          com.ibm.icu.util.SimpleTimeZone\r
71  * @author       Chen-Lieh Huang\r
72  * @stable ICU 2.0\r
73  */\r
74 public class DateFormatSymbols implements Serializable, Cloneable {\r
75 \r
76     // TODO make sure local pattern char string is 18 characters long,\r
77     // that is, that it encompasses the new 'u' char for\r
78     // EXTENDED_YEAR.  Two options: 1. Make sure resource data is\r
79     // correct; 2. Make code add in 'u' at end if len == 17.\r
80 \r
81     // Constants for context\r
82     /**\r
83      * Constant for context.\r
84      * @stable ICU 3.6\r
85      */\r
86     public static final int FORMAT = 0;\r
87 \r
88     /**\r
89      * Constant for context.\r
90      * @stable ICU 3.6\r
91      */\r
92     public static final int STANDALONE = 1;\r
93 \r
94     /**\r
95      * Constant for context.\r
96      * @internal revisit for ICU 3.6\r
97      * @deprecated This API is ICU internal only.\r
98      */\r
99     public static final int DT_CONTEXT_COUNT = 2;\r
100 \r
101     // Constants for width\r
102 \r
103     /**\r
104      * Constant for width.\r
105      * @stable ICU 3.6\r
106      */\r
107     public static final int ABBREVIATED = 0;\r
108 \r
109     /**\r
110      * Constant for width.\r
111      * @stable ICU 3.6\r
112      */\r
113     public static final int WIDE = 1;\r
114 \r
115     /**\r
116      * Constant for width.\r
117      * @stable ICU 3.6\r
118      */\r
119     public static final int NARROW = 2;\r
120 \r
121     /**\r
122      * Constant for width.\r
123      * @internal revisit for ICU 3.6\r
124      * @deprecated This API is ICU internal only.\r
125      */\r
126     public static final int DT_WIDTH_COUNT = 3;\r
127 \r
128     /**\r
129      * Construct a DateFormatSymbols object by loading format data from\r
130      * resources for the default locale.\r
131      *\r
132      * @throws  java.util.MissingResourceException\r
133      *          if the resources for the default locale cannot be\r
134      *          found or cannot be loaded.\r
135      * @stable ICU 2.0\r
136      */\r
137     public DateFormatSymbols()\r
138     {\r
139         this(ULocale.getDefault());\r
140     }\r
141     \r
142     /**\r
143      * Construct a DateFormatSymbols object by loading format data from\r
144      * resources for the given locale.\r
145      *\r
146      * @throws  java.util.MissingResourceException\r
147      *          if the resources for the specified locale cannot be\r
148      *          found or cannot be loaded.\r
149      * @stable ICU 2.0\r
150      */\r
151     public DateFormatSymbols(Locale locale)\r
152     {\r
153         this(ULocale.forLocale(locale));\r
154     }\r
155 \r
156     /**\r
157      * Construct a DateFormatSymbols object by loading format data from\r
158      * resources for the given ulocale.\r
159      *\r
160      * @throws  java.util.MissingResourceException\r
161      *          if the resources for the specified locale cannot be\r
162      *          found or cannot be loaded.\r
163      * @stable ICU 3.2\r
164      */\r
165     public DateFormatSymbols(ULocale locale)\r
166     {\r
167         initializeData(locale, getCalendarType(locale));\r
168     }\r
169 \r
170     /**\r
171      * Gets a DateFormatSymbols instance for the default locale.\r
172      * <br><br>\r
173      * <b>Note:</b> Unlike <code>java.text.DateFormatSymbols#getInstance</code>,\r
174      * this method simply returns <code>new com.ibm.icu.text.DateFormatSymbols()</code>.\r
175      * ICU does not support <code>DateFormatSymbolsProvider</code> introduced in Java 6\r
176      * or its equivalent implementation for now.\r
177      * \r
178      * @return A DateFormatSymbols instance.\r
179      * @stable ICU 3.8\r
180      */\r
181     public static DateFormatSymbols getInstance() {\r
182         return new DateFormatSymbols();\r
183     }\r
184 \r
185     /**\r
186      * Gets a DateFormatSymbols instance for the given locale.\r
187      * <br><br>\r
188      * <b>Note:</b> Unlike <code>java.text.DateFormatSymbols#getInstance</code>,\r
189      * this method simply returns <code>new com.ibm.icu.text.DateFormatSymbols(locale)</code>.\r
190      * ICU does not support <code>DateFormatSymbolsProvider</code> introduced in Java 6\r
191      * or its equivalent implementation for now.\r
192      * \r
193      * @param locale the locale.\r
194      * @return A DateFormatSymbols instance.\r
195      * @stable ICU 3.8\r
196      */\r
197     public static DateFormatSymbols getInstance(Locale locale) {\r
198         return new DateFormatSymbols(locale);\r
199     }\r
200 \r
201     /**\r
202      * Gets a DateFormatSymbols instance for the given locale.\r
203      * <br><br>\r
204      * <b>Note:</b> Unlike <code>java.text.DateFormatSymbols#getInstance</code>,\r
205      * this method simply returns <code>new com.ibm.icu.text.DateFormatSymbols(locale)</code>.\r
206      * ICU does not support <code>DateFormatSymbolsProvider</code> introduced in Java 6\r
207      * or its equivalent implementation for now.\r
208      * \r
209      * @param locale the locale.\r
210      * @return A DateFormatSymbols instance.\r
211      * @stable ICU 3.8\r
212      */\r
213     public static DateFormatSymbols getInstance(ULocale locale) {\r
214         return new DateFormatSymbols(locale);\r
215     }\r
216 \r
217     /**\r
218      * Returns an array of all locales for which the <code>getInstance</code> methods of this\r
219      * class can return localized instances.\r
220      * <br><br>\r
221      * <b>Note:</b> Unlike <code>java.text.DateFormatSymbols#getAvailableLocales</code>,\r
222      * this method simply returns the array of <code>Locale</code>s available in this class.\r
223      * ICU does not support <code>DateFormatSymbolsProvider</code> introduced in Java 6\r
224      * or its equivalent implementation for now.\r
225      * \r
226      * @return An array of <code>Locale</code>s for which localized <code>DateFormatSymbols</code> instances are available.\r
227      * @stable ICU 3.8\r
228      */\r
229     public static Locale[] getAvailableLocales() {\r
230         return ICUResourceBundle.getAvailableLocales(ICUResourceBundle.ICU_BASE_NAME);\r
231     }\r
232 \r
233     /**\r
234      * Returns an array of all locales for which the <code>getInstance</code> methods of this\r
235      * class can return localized instances.\r
236      * <br><br>\r
237      * <b>Note:</b> Unlike <code>java.text.DateFormatSymbols#getAvailableLocales</code>,\r
238      * this method simply returns the array of <code>ULocale</code>s available in this class.\r
239      * ICU does not support <code>DateFormatSymbolsProvider</code> introduced in Java 6\r
240      * or its equivalent implementation for now.\r
241      * \r
242      * @return An array of <code>ULocale</code>s for which localized <code>DateFormatSymbols</code> instances are available.\r
243      * @draft ICU 3.8 (retain)\r
244      * @provisional This API might change or be removed in a future release.\r
245      */\r
246     public static ULocale[] getAvailableULocales() {\r
247         return ICUResourceBundle.getAvailableULocales(ICUResourceBundle.ICU_BASE_NAME);\r
248     }\r
249     \r
250     /**\r
251      * Era strings. For example: "AD" and "BC".  An array of 2 strings,\r
252      * indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.\r
253      * @serial\r
254      */\r
255     String eras[] = null;\r
256 \r
257     /**\r
258      * Era name strings. For example: "Anno Domini" and "Before Christ".  An array of 2 strings,\r
259      * indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.\r
260      * @serial\r
261      */\r
262     String eraNames[] = null;\r
263     \r
264     /**\r
265      * Narrow era names. For example: "A" and "B". An array of 2 strings,\r
266      * indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.\r
267      * @serial\r
268      */\r
269     String narrowEras[] = null;\r
270 \r
271     /**\r
272      * Month strings. For example: "January", "February", etc.  An array\r
273      * of 13 strings (some calendars have 13 months), indexed by\r
274      * <code>Calendar.JANUARY</code>, <code>Calendar.FEBRUARY</code>, etc.\r
275      * @serial\r
276      */\r
277     String months[] = null;\r
278 \r
279     /**\r
280      * Short month strings. For example: "Jan", "Feb", etc.  An array of\r
281      * 13 strings (some calendars have 13 months), indexed by\r
282      * <code>Calendar.JANUARY</code>, <code>Calendar.FEBRUARY</code>, etc.\r
283 \r
284      * @serial\r
285      */\r
286     String shortMonths[] = null;\r
287 \r
288     /**\r
289      * Narrow month strings. For example: "J", "F", etc.  An array of\r
290      * 13 strings (some calendars have 13 months), indexed by\r
291      * <code>Calendar.JANUARY</code>, <code>Calendar.FEBRUARY</code>, etc.\r
292 \r
293      * @serial\r
294      */\r
295     String narrowMonths[] = null;\r
296 \r
297     /**\r
298      * Standalone month strings. For example: "January", "February", etc.  An array\r
299      * of 13 strings (some calendars have 13 months), indexed by\r
300      * <code>Calendar.JANUARY</code>, <code>Calendar.FEBRUARY</code>, etc.\r
301      * @serial\r
302      */\r
303     String standaloneMonths[] = null;\r
304 \r
305     /**\r
306      * Standalone short month strings. For example: "Jan", "Feb", etc.  An array of\r
307      * 13 strings (some calendars have 13 months), indexed by\r
308      * <code>Calendar.JANUARY</code>, <code>Calendar.FEBRUARY</code>, etc.\r
309 \r
310      * @serial\r
311      */\r
312     String standaloneShortMonths[] = null;\r
313 \r
314     /**\r
315      * Standalone narrow month strings. For example: "J", "F", etc.  An array of\r
316      * 13 strings (some calendars have 13 months), indexed by\r
317      * <code>Calendar.JANUARY</code>, <code>Calendar.FEBRUARY</code>, etc.\r
318 \r
319      * @serial\r
320      */\r
321     String standaloneNarrowMonths[] = null;\r
322 \r
323     /**\r
324      * Weekday strings. For example: "Sunday", "Monday", etc.  An array\r
325      * of 8 strings, indexed by <code>Calendar.SUNDAY</code>,\r
326      * <code>Calendar.MONDAY</code>, etc.\r
327      * The element <code>weekdays[0]</code> is ignored.\r
328      * @serial\r
329      */\r
330     String weekdays[] = null;\r
331 \r
332     /**\r
333      * Short weekday strings. For example: "Sun", "Mon", etc.  An array\r
334      * of 8 strings, indexed by <code>Calendar.SUNDAY</code>,\r
335      * <code>Calendar.MONDAY</code>, etc.\r
336      * The element <code>shortWeekdays[0]</code> is ignored.\r
337      * @serial\r
338      */\r
339     String shortWeekdays[] = null;\r
340 \r
341     /**\r
342      * Narrow weekday strings. For example: "S", "M", etc.  An array\r
343      * of 8 strings, indexed by <code>Calendar.SUNDAY</code>,\r
344      * <code>Calendar.MONDAY</code>, etc.\r
345      * The element <code>narrowWeekdays[0]</code> is ignored.\r
346      * @serial\r
347      */\r
348     String narrowWeekdays[] = null;\r
349 \r
350     /**\r
351      * Standalone weekday strings. For example: "Sunday", "Monday", etc.  An array\r
352      * of 8 strings, indexed by <code>Calendar.SUNDAY</code>,\r
353      * <code>Calendar.MONDAY</code>, etc.\r
354      * The element <code>standaloneWeekdays[0]</code> is ignored.\r
355      * @serial\r
356      */\r
357     String standaloneWeekdays[] = null;\r
358 \r
359     /**\r
360      * Standalone short weekday strings. For example: "Sun", "Mon", etc.  An array\r
361      * of 8 strings, indexed by <code>Calendar.SUNDAY</code>,\r
362      * <code>Calendar.MONDAY</code>, etc.\r
363      * The element <code>standaloneShortWeekdays[0]</code> is ignored.\r
364      * @serial\r
365      */\r
366     String standaloneShortWeekdays[] = null;\r
367 \r
368     /**\r
369      * Standalone narrow weekday strings. For example: "S", "M", etc.  An array\r
370      * of 8 strings, indexed by <code>Calendar.SUNDAY</code>,\r
371      * <code>Calendar.MONDAY</code>, etc.\r
372      * The element <code>standaloneNarrowWeekdays[0]</code> is ignored.\r
373      * @serial\r
374      */\r
375     String standaloneNarrowWeekdays[] = null;\r
376 \r
377     /**\r
378      * AM and PM strings. For example: "AM" and "PM".  An array of\r
379      * 2 strings, indexed by <code>Calendar.AM</code> and\r
380      * <code>Calendar.PM</code>.\r
381      * @serial\r
382      */\r
383     String ampms[] = null;\r
384     \r
385     /**\r
386      * Abbreviated quarter names. For example: "Q1", "Q2", "Q3", "Q4". An array\r
387      * of 4 strings indexed by the month divided by 3.\r
388      * @serial\r
389      */\r
390     String shortQuarters[] = null;\r
391     \r
392     /**\r
393      * Full quarter names. For example: "1st Quarter", "2nd Quarter", "3rd Quarter",\r
394      * "4th Quarter". An array of 4 strings, indexed by the month divided by 3.\r
395      * @serial\r
396      */\r
397     String quarters[] = null;\r
398     \r
399     /**\r
400      * Standalone abbreviated quarter names. For example: "Q1", "Q2", "Q3", "Q4". An array\r
401      * of 4 strings indexed by the month divided by 3.\r
402      * @serial\r
403      */\r
404     String standaloneShortQuarters[] = null;\r
405     \r
406     /**\r
407      * Standalone full quarter names. For example: "1st Quarter", "2nd Quarter", "3rd Quarter",\r
408      * "4th Quarter". An array of 4 strings, indexed by the month divided by 3.\r
409      * @serial\r
410      */\r
411     String standaloneQuarters[] = null;\r
412 \r
413     /**\r
414      * Pattern string used for localized time zone GMT format.  For example, "GMT{0}"\r
415      * @serial\r
416      */\r
417     String gmtFormat = null;\r
418 \r
419     /**\r
420      * Pattern strings used for formatting zone offset in a localized time zone GMT string.\r
421      * This is 2x2 String array holding followings\r
422      * [0][0] Negative H + m + s\r
423      * [0][1] Negative H + m\r
424      * [1][0] Positive H + m + s\r
425      * [1][1] Positive H + m\r
426      * @serial\r
427      */\r
428     String gmtHourFormats[][] = null;\r
429 \r
430     /**\r
431      * Localized names of time zones in this locale.  This is a\r
432      * two-dimensional array of strings of size <em>n</em> by <em>m</em>,\r
433      * where <em>m</em> is at least 5 and up to 7.  Each of the <em>n</em> rows is an\r
434      * entry containing the localized names for a single <code>TimeZone</code>.\r
435      * Each such row contains (with <code>i</code> ranging from\r
436      * 0..<em>n</em>-1):\r
437      * <ul>\r
438      * <li><code>zoneStrings[i][0]</code> - time zone ID</li>\r
439      * <li><code>zoneStrings[i][1]</code> - long name of zone in standard\r
440      * time</li>\r
441      * <li><code>zoneStrings[i][2]</code> - short name of zone in\r
442      * standard time</li>\r
443      * <li><code>zoneStrings[i][3]</code> - long name of zone in daylight\r
444      * savings time</li>\r
445      * <li><code>zoneStrings[i][4]</code> - short name of zone in daylight\r
446      * savings time</li>\r
447      * <li><code>zoneStrings[i][5]</code> - location name of zone</li>\r
448      * <li><code>zoneStrings[i][6]</code> - long generic name of zone</li>\r
449      * <li><code>zoneStrings[i][7]</code> - short generic of zone</li>\r
450      * The zone ID is <em>not</em> localized; it corresponds to the ID\r
451      * value associated with a system time zone object.  All other entries\r
452      * are localized names.  If a zone does not implement daylight savings\r
453      * time, the daylight savings time names are ignored.\r
454      * <em>Note:</em>CLDR 1.5 introduced metazone and its historical mappings.\r
455      * This simple two-dimensional array is no longer sufficient to represent\r
456      * localized names and its historic changes.  Since ICU 3.8.1, localized\r
457      * zone names extracted from ICU locale data is stored in a ZoneStringFormat\r
458      * instance.  But we still need to support the old way of customizing\r
459      * localized zone names, so we keep this field for the purpose.\r
460      * @see com.ibm.icu.util.TimeZone\r
461      * @serial\r
462      */\r
463      private String zoneStrings[][] = null;\r
464 \r
465      /**\r
466       * Since ICU 3.8.1, we use ZoneStringFormat to access localized\r
467       * zone names.  This field remains null unless setZoneStrings is\r
468       * called.\r
469       */\r
470      private transient ZoneStringFormat zsformat = null;\r
471 \r
472      /**\r
473      * Unlocalized date-time pattern characters. For example: 'y', 'd', etc.\r
474      * All locales use the same unlocalized pattern characters.\r
475      */\r
476     static final String  patternChars = "GyMdkHmsSEDFwWahKzYeugAZvcLQqV";\r
477 \r
478     /**\r
479      * Localized date-time pattern characters. For example, a locale may\r
480      * wish to use 'u' rather than 'y' to represent years in its date format\r
481      * pattern strings.\r
482      * This string must be exactly 18 characters long, with the index of\r
483      * the characters described by <code>DateFormat.ERA_FIELD</code>,\r
484      * <code>DateFormat.YEAR_FIELD</code>, etc.  Thus, if the string were\r
485      * "Xz...", then localized patterns would use 'X' for era and 'z' for year.\r
486      * @serial\r
487      */\r
488     String  localPatternChars = null;\r
489 \r
490     /* use serialVersionUID from JDK 1.1.4 for interoperability */\r
491     private static final long serialVersionUID = -5987973545549424702L;\r
492 \r
493     /**\r
494      * Gets era strings. For example: "AD" and "BC".\r
495      * @return the era strings.\r
496      * @stable ICU 2.0\r
497      */\r
498     public String[] getEras() {\r
499         return duplicate(eras);\r
500     }\r
501 \r
502     /**\r
503      * Sets era strings. For example: "AD" and "BC".\r
504      * @param newEras the new era strings.\r
505      * @stable ICU 2.0\r
506      */\r
507     public void setEras(String[] newEras) {\r
508         eras = duplicate(newEras);\r
509     }\r
510 \r
511     /**\r
512      * Gets era name strings. For example: "Anno Domini" and "Before Christ".\r
513      * @return the era strings.\r
514      * @stable ICU 3.4\r
515      */\r
516     public String[] getEraNames() {\r
517         return duplicate(eraNames);\r
518     }\r
519 \r
520     /**\r
521      * Sets era name strings. For example: "Anno Domini" and "Before Christ".\r
522      * @param newEraNames the new era strings.\r
523      * @stable ICU 3.8\r
524      */\r
525     public void setEraNames(String[] newEraNames) {\r
526         eraNames = duplicate(newEraNames);\r
527     }\r
528 \r
529     /**\r
530      * Gets month strings. For example: "January", "February", etc.\r
531      * @return the month strings.\r
532      * @stable ICU 2.0\r
533      */\r
534     public String[] getMonths() {\r
535         return duplicate(months);\r
536     }\r
537 \r
538     /**\r
539      * Gets month strings. For example: "January", "February", etc.\r
540      * @param context    The month context, FORMAT or STANDALONE.\r
541      * @param width      The width or the returned month string,\r
542      *                   either WIDE, ABBREVIATED, or NARROW.\r
543      * @return the month strings.\r
544      * @stable ICU 3.4\r
545      */\r
546     public String[] getMonths(int context, int width) {\r
547         String [] returnValue = null;\r
548         switch (context) {\r
549            case FORMAT :\r
550               switch(width) {\r
551                  case WIDE :\r
552                     returnValue = months;\r
553                     break;\r
554                  case ABBREVIATED :\r
555                     returnValue = shortMonths;\r
556                     break;\r
557                  case NARROW :\r
558                     returnValue = narrowMonths;\r
559                     break;\r
560               }\r
561               break;\r
562            case STANDALONE :\r
563               switch(width) {\r
564                  case WIDE :\r
565                     returnValue = standaloneMonths;\r
566                     break;\r
567                  case ABBREVIATED :\r
568                     returnValue = standaloneShortMonths;\r
569                     break;\r
570                  case NARROW :\r
571                     returnValue = standaloneNarrowMonths;\r
572                     break;\r
573               }\r
574               break;\r
575         }\r
576         return duplicate(returnValue);\r
577     }\r
578 \r
579     /**\r
580      * Sets month strings. For example: "January", "February", etc.\r
581      * @param newMonths the new month strings.\r
582      * @stable ICU 2.0\r
583      */\r
584     public void setMonths(String[] newMonths) {\r
585         months = duplicate(newMonths);\r
586     }\r
587 \r
588     /**\r
589      * Sets month strings. For example: "January", "February", etc.\r
590      * @param newMonths the new month strings.\r
591      * @param context    The formatting context, FORMAT or STANDALONE.\r
592      * @param width      The width of the month string,\r
593      *                   either WIDE, ABBREVIATED, or NARROW.\r
594      * @stable ICU 3.8\r
595      */\r
596     public void setMonths(String[] newMonths, int context, int width) {\r
597         switch (context) {\r
598            case FORMAT :\r
599               switch(width) {\r
600                  case WIDE :\r
601                     months = duplicate(newMonths);\r
602                     break;\r
603                  case ABBREVIATED :\r
604                     shortMonths = duplicate(newMonths);\r
605                     break;\r
606                  case NARROW :\r
607                     narrowMonths = duplicate(newMonths);\r
608                     break;\r
609               }\r
610               break;\r
611            case STANDALONE :\r
612               switch(width) {\r
613                  case WIDE :\r
614                     standaloneMonths = duplicate(newMonths);\r
615                     break;\r
616                  case ABBREVIATED :\r
617                     standaloneShortMonths = duplicate(newMonths);\r
618                     break;\r
619                  case NARROW :\r
620                     standaloneNarrowMonths = duplicate(newMonths);\r
621                     break;\r
622               }\r
623               break;\r
624         }\r
625     }\r
626     \r
627     /**\r
628      * Gets short month strings. For example: "Jan", "Feb", etc.\r
629      * @return the short month strings.\r
630      * @stable ICU 2.0\r
631      */\r
632     public String[] getShortMonths() {\r
633         return duplicate(shortMonths);\r
634     }\r
635 \r
636     /**\r
637      * Sets short month strings. For example: "Jan", "Feb", etc.\r
638      * @param newShortMonths the new short month strings.\r
639      * @stable ICU 2.0\r
640      */\r
641     public void setShortMonths(String[] newShortMonths) {\r
642         shortMonths = duplicate(newShortMonths);\r
643     }\r
644 \r
645     /**\r
646      * Gets weekday strings. For example: "Sunday", "Monday", etc.\r
647      * @return the weekday strings. Use <code>Calendar.SUNDAY</code>,\r
648      * <code>Calendar.MONDAY</code>, etc. to index the result array.\r
649      * @stable ICU 2.0\r
650      */\r
651     public String[] getWeekdays() {\r
652         return duplicate(weekdays);\r
653     }\r
654 \r
655     /**\r
656      * Gets weekday strings. For example: "Sunday", "Monday", etc.\r
657      * @return the weekday strings. Use <code>Calendar.SUNDAY</code>,\r
658      * <code>Calendar.MONDAY</code>, etc. to index the result array.\r
659      * @param context    Formatting context, either FORMAT or STANDALONE.\r
660      * @param width      Width of strings to be returned, either\r
661      *                   WIDE, ABBREVIATED, or NARROW\r
662      * @stable ICU 3.4\r
663      */\r
664     public String[] getWeekdays(int context, int width) {\r
665         String [] returnValue = null;\r
666         switch (context) {\r
667            case FORMAT :\r
668               switch(width) {\r
669                  case WIDE :\r
670                     returnValue = weekdays;\r
671                     break;\r
672                  case ABBREVIATED :\r
673                     returnValue = shortWeekdays;\r
674                     break;\r
675                  case NARROW :\r
676                     returnValue = narrowWeekdays;\r
677                     break;\r
678               }\r
679               break;\r
680            case STANDALONE :\r
681               switch(width) {\r
682                  case WIDE :\r
683                     returnValue = standaloneWeekdays;\r
684                     break;\r
685                  case ABBREVIATED :\r
686                     returnValue = standaloneShortWeekdays;\r
687                     break;\r
688                  case NARROW :\r
689                     returnValue = standaloneNarrowWeekdays;\r
690                     break;\r
691               }\r
692               break;\r
693         }\r
694         return duplicate(returnValue);\r
695     }\r
696 \r
697     /**\r
698      * Sets weekday strings. For example: "Sunday", "Monday", etc.\r
699      * @param newWeekdays The new weekday strings.\r
700      * @param context     The formatting context, FORMAT or STANDALONE.\r
701      * @param width       The width of the strings,\r
702      *                    either WIDE, ABBREVIATED, or NARROW.\r
703      * @stable ICU 3.8\r
704      */\r
705     public void setWeekdays(String[] newWeekdays, int context, int width) {\r
706         switch (context) {\r
707            case FORMAT :\r
708               switch(width) {\r
709                  case WIDE :\r
710                     weekdays = duplicate(newWeekdays);\r
711                     break;\r
712                  case ABBREVIATED :\r
713                     shortWeekdays = duplicate(newWeekdays);\r
714                     break;\r
715                  case NARROW :\r
716                     narrowWeekdays = duplicate(newWeekdays);\r
717                     break;\r
718               }\r
719               break;\r
720            case STANDALONE :\r
721               switch(width) {\r
722                  case WIDE :\r
723                     standaloneWeekdays = duplicate(newWeekdays);\r
724                     break;\r
725                  case ABBREVIATED :\r
726                     standaloneShortWeekdays = duplicate(newWeekdays);\r
727                     break;\r
728                  case NARROW :\r
729                     standaloneNarrowWeekdays = duplicate(newWeekdays);\r
730                     break;\r
731               }\r
732               break;\r
733         }\r
734     }\r
735 \r
736     /**\r
737      * Sets weekday strings. For example: "Sunday", "Monday", etc.\r
738      * @param newWeekdays the new weekday strings. The array should\r
739      * be indexed by <code>Calendar.SUNDAY</code>,\r
740      * <code>Calendar.MONDAY</code>, etc.\r
741      * @stable ICU 2.0\r
742      */\r
743     public void setWeekdays(String[] newWeekdays) {\r
744         weekdays = duplicate(newWeekdays);\r
745     }\r
746 \r
747     /**\r
748      * Gets short weekday strings. For example: "Sun", "Mon", etc.\r
749      * @return the short weekday strings. Use <code>Calendar.SUNDAY</code>,\r
750      * <code>Calendar.MONDAY</code>, etc. to index the result array.\r
751      * @stable ICU 2.0\r
752      */\r
753     public String[] getShortWeekdays() {\r
754         return duplicate(shortWeekdays);\r
755     }\r
756 \r
757     /**\r
758      * Sets short weekday strings. For example: "Sun", "Mon", etc.\r
759      * @param newShortWeekdays the new short weekday strings. The array should\r
760      * be indexed by <code>Calendar.SUNDAY</code>,\r
761      * <code>Calendar.MONDAY</code>, etc.\r
762      * @stable ICU 2.0\r
763      */\r
764     public void setShortWeekdays(String[] newShortWeekdays) {\r
765         shortWeekdays = duplicate(newShortWeekdays);\r
766     }\r
767     /**\r
768      * Gets quarter strings. For example: "1st Quarter", "2nd Quarter", etc.\r
769      * @param context    The quarter context, FORMAT or STANDALONE.\r
770      * @param width      The width or the returned quarter string,\r
771      *                   either WIDE or ABBREVIATED. There are no NARROW quarters.\r
772      * @return the quarter strings.\r
773      * @stable ICU 3.6\r
774      */\r
775     public String[] getQuarters(int context, int width) {\r
776         String [] returnValue = null;\r
777         switch (context) {\r
778            case FORMAT :\r
779               switch(width) {\r
780                  case WIDE :\r
781                     returnValue = quarters;\r
782                     break;\r
783                  case ABBREVIATED :\r
784                     returnValue = shortQuarters;\r
785                     break;\r
786                  case NARROW :\r
787                      returnValue = null;\r
788                      break;\r
789               }\r
790               break;\r
791               \r
792            case STANDALONE :\r
793               switch(width) {\r
794                  case WIDE :\r
795                     returnValue = standaloneQuarters;\r
796                     break;\r
797                  case ABBREVIATED :\r
798                     returnValue = standaloneShortQuarters;\r
799                     break;\r
800                  case NARROW: \r
801                      returnValue = null;\r
802                      break;\r
803               }\r
804               break;\r
805         }\r
806         return duplicate(returnValue);\r
807     }\r
808 \r
809     /**\r
810      * Sets quarter strings. For example: "1st Quarter", "2nd Quarter", etc.\r
811      * @param newQuarters the new quarter strings.\r
812      * @param context    The formatting context, FORMAT or STANDALONE.\r
813      * @param width      The width of the quarter string,\r
814      *                   either WIDE or ABBREVIATED. There are no NARROW quarters.\r
815      * @stable ICU 3.8\r
816      */\r
817     public void setQuarters(String[] newQuarters, int context, int width) {\r
818         switch (context) {\r
819            case FORMAT :\r
820               switch(width) {\r
821                  case WIDE :\r
822                     quarters = duplicate(newQuarters);\r
823                     break;\r
824                  case ABBREVIATED :\r
825                     shortQuarters = duplicate(newQuarters);\r
826                     break;\r
827                  case NARROW :\r
828                     //narrowQuarters = duplicate(newQuarters);\r
829                     break;\r
830               }\r
831               break;\r
832            case STANDALONE :\r
833               switch(width) {\r
834                  case WIDE :\r
835                     standaloneQuarters = duplicate(newQuarters);\r
836                     break;\r
837                  case ABBREVIATED :\r
838                     standaloneShortQuarters = duplicate(newQuarters);\r
839                     break;\r
840                  case NARROW :\r
841                     //standaloneNarrowQuarters = duplicate(newQuarters);\r
842                     break;\r
843               }\r
844               break;\r
845         }\r
846     }\r
847 \r
848     /**\r
849      * Gets ampm strings. For example: "AM" and "PM".\r
850      * @return the weekday strings.\r
851      * @stable ICU 2.0\r
852      */\r
853     public String[] getAmPmStrings() {\r
854         return duplicate(ampms);\r
855     }\r
856 \r
857     /**\r
858      * Sets ampm strings. For example: "AM" and "PM".\r
859      * @param newAmpms the new ampm strings.\r
860      * @stable ICU 2.0\r
861      */\r
862     public void setAmPmStrings(String[] newAmpms) {\r
863         ampms = duplicate(newAmpms);\r
864     }\r
865 \r
866     /**\r
867      * Gets timezone strings.\r
868      * @return the timezone strings.\r
869      * @stable ICU 2.0\r
870      */\r
871     public String[][] getZoneStrings() {\r
872         if (zoneStrings != null) {\r
873             return duplicate(zoneStrings);\r
874         }\r
875         return ZoneStringFormat.getInstance(requestedLocale).getZoneStrings();\r
876     }\r
877 \r
878     /**\r
879      * Sets timezone strings.\r
880      * @param newZoneStrings the new timezone strings.\r
881      * @stable ICU 2.0\r
882      */\r
883     public void setZoneStrings(String[][] newZoneStrings) {\r
884         zoneStrings = duplicate(newZoneStrings);\r
885         zsformat = new ZoneStringFormat(zoneStrings);\r
886     }\r
887 \r
888     /**\r
889      * Gets localized date-time pattern characters. For example: 'u', 't', etc.\r
890      * <p>\r
891      * Note: ICU no longer provides localized date-time pattern characters for a locale\r
892      * starting ICU 3.8.  This method returns the non-localized date-time pattern\r
893      * characters unless user defined localized data is set by setLocalPatternChars.\r
894      * @return the localized date-time pattern characters.\r
895      * @stable ICU 2.0\r
896      */\r
897     public String getLocalPatternChars() {\r
898         return new String(localPatternChars);\r
899     }\r
900 \r
901     /**\r
902      * Sets localized date-time pattern characters. For example: 'u', 't', etc.\r
903      * @param newLocalPatternChars the new localized date-time\r
904      * pattern characters.\r
905      * @stable ICU 2.0\r
906      */\r
907     public void setLocalPatternChars(String newLocalPatternChars) {\r
908         localPatternChars = newLocalPatternChars;\r
909     }\r
910 \r
911     /**\r
912      * Overrides Cloneable\r
913      * @stable ICU 2.0\r
914      */\r
915     public Object clone()\r
916     {\r
917         try {\r
918             DateFormatSymbols other = (DateFormatSymbols)super.clone();\r
919             return other;\r
920         } catch (CloneNotSupportedException e) {\r
921             ///CLOVER:OFF\r
922             throw new IllegalStateException();\r
923             ///CLOVER:ON\r
924         }\r
925     }\r
926 \r
927     /**\r
928      * Override hashCode.\r
929      * Generates a hash code for the DateFormatSymbols object.\r
930      * @stable ICU 2.0\r
931      */\r
932     public int hashCode() {\r
933         // Is this sufficient?\r
934         return requestedLocale.toString().hashCode();\r
935     }\r
936 \r
937     /**\r
938      * Override equals\r
939      * @stable ICU 2.0\r
940      */\r
941     public boolean equals(Object obj)\r
942     {\r
943         if (this == obj) return true;\r
944         if (obj == null || getClass() != obj.getClass()) return false;\r
945         DateFormatSymbols that = (DateFormatSymbols) obj;\r
946         return (Utility.arrayEquals(eras, that.eras)\r
947                 && Utility.arrayEquals(eraNames, that.eraNames)\r
948                 && Utility.arrayEquals(months, that.months)\r
949                 && Utility.arrayEquals(shortMonths, that.shortMonths)\r
950                 && Utility.arrayEquals(narrowMonths, that.narrowMonths)\r
951                 && Utility.arrayEquals(standaloneMonths, that.standaloneMonths)\r
952                 && Utility.arrayEquals(standaloneShortMonths, that.standaloneShortMonths)\r
953                 && Utility.arrayEquals(standaloneNarrowMonths, that.standaloneNarrowMonths)\r
954                 && Utility.arrayEquals(weekdays, that.weekdays)\r
955                 && Utility.arrayEquals(shortWeekdays, that.shortWeekdays)\r
956                 && Utility.arrayEquals(narrowWeekdays, that.narrowWeekdays)\r
957                 && Utility.arrayEquals(standaloneWeekdays, that.standaloneWeekdays)\r
958                 && Utility.arrayEquals(standaloneShortWeekdays, that.standaloneShortWeekdays)\r
959                 && Utility.arrayEquals(standaloneNarrowWeekdays, that.standaloneNarrowWeekdays)\r
960                 && Utility.arrayEquals(ampms, that.ampms)\r
961                 && gmtFormat.equals(that.gmtFormat)\r
962                 && arrayOfArrayEquals(gmtHourFormats, that.gmtHourFormats)\r
963                 && arrayOfArrayEquals(zoneStrings, that.zoneStrings)\r
964                 // getDiplayName maps deprecated country and language codes to the current ones\r
965                 // too bad there is no way to get the current codes!\r
966                 // I thought canolicalize() would map the codes but .. alas! it doesn't.\r
967                 && requestedLocale.getDisplayName().equals(that.requestedLocale.getDisplayName())\r
968                 && Utility.arrayEquals(localPatternChars,\r
969                                        that.localPatternChars));\r
970     }\r
971 \r
972     // =======================privates===============================\r
973 \r
974     /*\r
975      * Useful constant for defining timezone offsets.\r
976      */\r
977     static final int millisPerHour = 60*60*1000;\r
978 \r
979     // DateFormatSymbols cache\r
980     private static ICUCache DFSCACHE = new SimpleCache();\r
981 \r
982     /**\r
983      * Initialize format symbols for the locale and calendar type\r
984      * @param desiredLocale The locale whose symbols are desired.\r
985      * @param type          The calendar type whose date format symbols are desired.\r
986      * @stable ICU 3.0\r
987      */\r
988     //TODO: This protected seems to be marked as @stable accidentally.\r
989     // We may need to deescalate this API to @internal.\r
990     protected void initializeData(ULocale desiredLocale, String type)\r
991     {\r
992         String key = desiredLocale.toString() + "+" + type;\r
993         DateFormatSymbols dfs = (DateFormatSymbols)DFSCACHE.get(key);\r
994         if (dfs == null) {\r
995             // Initialize data from scratch put a clone of this instance into the cache\r
996             CalendarData calData = new CalendarData(desiredLocale, type);\r
997             initializeData(desiredLocale, calData);\r
998             dfs = (DateFormatSymbols)this.clone();\r
999             DFSCACHE.put(key, dfs);\r
1000         } else {\r
1001             initializeData(dfs);\r
1002         }\r
1003     }\r
1004 \r
1005     /* \r
1006      * Initialize format symbols using another instance.\r
1007      * \r
1008      * TODO Clean up initialization methods for subclasses\r
1009      */\r
1010     void initializeData(DateFormatSymbols dfs) {\r
1011         this.eras = dfs.eras;\r
1012         this.eraNames = dfs.eraNames;\r
1013         this.narrowEras = dfs.narrowEras;\r
1014         this.months = dfs.months;\r
1015         this.shortMonths = dfs.shortMonths;\r
1016         this.narrowMonths = dfs.narrowMonths;\r
1017         this.standaloneMonths = dfs.standaloneMonths;\r
1018         this.standaloneShortMonths = dfs.standaloneShortMonths;\r
1019         this.standaloneNarrowMonths = dfs.standaloneNarrowMonths;\r
1020         this.weekdays = dfs.weekdays;\r
1021         this.shortWeekdays = dfs.shortWeekdays;\r
1022         this.narrowWeekdays = dfs.narrowWeekdays;\r
1023         this.standaloneWeekdays = dfs.standaloneWeekdays;\r
1024         this.standaloneShortWeekdays = dfs.standaloneShortWeekdays;\r
1025         this.standaloneNarrowWeekdays = dfs.standaloneNarrowWeekdays;\r
1026         this.ampms = dfs.ampms;\r
1027         this.shortQuarters = dfs.shortQuarters;\r
1028         this.quarters = dfs.quarters;\r
1029         this.standaloneShortQuarters = dfs.standaloneShortQuarters;\r
1030         this.standaloneQuarters = dfs.standaloneQuarters;\r
1031 \r
1032         this.gmtFormat = dfs.gmtFormat;\r
1033         this.gmtHourFormats = dfs.gmtHourFormats;\r
1034 \r
1035         this.zoneStrings = dfs.zoneStrings; // always null at initialization time for now\r
1036         this.localPatternChars = dfs.localPatternChars;\r
1037 \r
1038         this.actualLocale = dfs.actualLocale;\r
1039         this.validLocale = dfs.validLocale;\r
1040         this.requestedLocale = dfs.requestedLocale;\r
1041     }\r
1042 \r
1043     /**\r
1044      * Initialize format symbols for the locale and calendar type\r
1045      * @param desiredLocale The locale whose symbols are desired.\r
1046      * @param calData       The calendar resource data\r
1047      * @internal\r
1048      * @deprecated This API is ICU internal only.\r
1049      */\r
1050     // This API was accidentally marked as @stable ICU 3.0 formerly.\r
1051     protected void initializeData(ULocale desiredLocale, CalendarData calData)\r
1052     {\r
1053         // FIXME: cache only ResourceBundle. Hence every time, will do\r
1054         // getObject(). This won't be necessary if the Resource itself\r
1055         // is cached.\r
1056         eras = calData.getEras("abbreviated");\r
1057 \r
1058         try {\r
1059            eraNames = calData.getEras("wide");\r
1060         }\r
1061         catch (MissingResourceException e) {\r
1062            eraNames = calData.getEras("abbreviated");\r
1063         }\r
1064         \r
1065         // NOTE: since the above code assumes that abbreviated\r
1066         // era names exist, we make the same assumption here too.\r
1067         try {\r
1068             narrowEras = calData.getEras("narrow");\r
1069         } catch (MissingResourceException e) {\r
1070             narrowEras = calData.getEras("abbreviated");\r
1071         }\r
1072 \r
1073         months = calData.getStringArray("monthNames", "wide");\r
1074         shortMonths = calData.getStringArray("monthNames", "abbreviated");\r
1075 \r
1076         try {\r
1077            narrowMonths = calData.getStringArray("monthNames", "narrow");\r
1078         } \r
1079         catch (MissingResourceException e) {\r
1080             try {\r
1081                 narrowMonths = calData.getStringArray("monthNames", "stand-alone", "narrow");\r
1082             }\r
1083             catch (MissingResourceException e1) {\r
1084                narrowMonths = calData.getStringArray("monthNames", "abbreviated");\r
1085             }\r
1086         }\r
1087 \r
1088         try {\r
1089            standaloneMonths = calData.getStringArray("monthNames", "stand-alone", "wide");\r
1090         } \r
1091         catch (MissingResourceException e) {\r
1092            standaloneMonths = calData.getStringArray("monthNames", "format", "wide");\r
1093         }\r
1094 \r
1095         try {\r
1096            standaloneShortMonths = calData.getStringArray("monthNames", "stand-alone", "abbreviated");\r
1097         } \r
1098         catch (MissingResourceException e) {\r
1099            standaloneShortMonths = calData.getStringArray("monthNames", "format", "abbreviated");\r
1100         }\r
1101 \r
1102         try {\r
1103            standaloneNarrowMonths = calData.getStringArray("monthNames", "stand-alone", "narrow");\r
1104         } \r
1105         catch (MissingResourceException e) {\r
1106            try {\r
1107               standaloneNarrowMonths = calData.getStringArray("monthNames", "format", "narrow");\r
1108            }\r
1109            catch (MissingResourceException e1) {\r
1110               standaloneNarrowMonths = calData.getStringArray("monthNames", "format", "abbreviated");\r
1111            }\r
1112         }\r
1113 \r
1114         String[] lWeekdays = calData.getStringArray("dayNames", "wide");\r
1115         weekdays = new String[8];\r
1116         weekdays[0] = "";  // 1-based\r
1117         System.arraycopy(lWeekdays, 0, weekdays, 1, lWeekdays.length);\r
1118 \r
1119         String[] sWeekdays = calData.getStringArray("dayNames", "abbreviated");\r
1120         shortWeekdays = new String[8];\r
1121         shortWeekdays[0] = "";  // 1-based\r
1122         System.arraycopy(sWeekdays, 0, shortWeekdays, 1, sWeekdays.length);\r
1123 \r
1124         String [] nWeekdays = null;\r
1125         try {\r
1126            nWeekdays = calData.getStringArray("dayNames", "narrow");\r
1127         }\r
1128         catch (MissingResourceException e) {\r
1129             try {\r
1130                 nWeekdays = calData.getStringArray("dayNames", "stand-alone", "narrow");\r
1131             }\r
1132             catch (MissingResourceException e1) {\r
1133                 nWeekdays = calData.getStringArray("dayNames", "abbreviated");\r
1134             }\r
1135         }\r
1136         narrowWeekdays = new String[8];\r
1137         narrowWeekdays[0] = "";  // 1-based\r
1138         System.arraycopy(nWeekdays, 0, narrowWeekdays, 1, nWeekdays.length);\r
1139 \r
1140         String [] saWeekdays = null;\r
1141         try {\r
1142            saWeekdays = calData.getStringArray("dayNames", "stand-alone", "wide");\r
1143         }\r
1144         catch (MissingResourceException e) {\r
1145            saWeekdays = calData.getStringArray("dayNames", "format", "wide");\r
1146         }\r
1147         standaloneWeekdays = new String[8];\r
1148         standaloneWeekdays[0] = "";  // 1-based\r
1149         System.arraycopy(saWeekdays, 0, standaloneWeekdays, 1, saWeekdays.length);\r
1150 \r
1151         String [] ssWeekdays = null;\r
1152         try {\r
1153            ssWeekdays = calData.getStringArray("dayNames", "stand-alone", "abbreviated");\r
1154         }\r
1155         catch (MissingResourceException e) {\r
1156            ssWeekdays = calData.getStringArray("dayNames", "format", "abbreviated");\r
1157         }\r
1158         standaloneShortWeekdays = new String[8];\r
1159         standaloneShortWeekdays[0] = "";  // 1-based\r
1160         System.arraycopy(ssWeekdays, 0, standaloneShortWeekdays, 1, ssWeekdays.length);\r
1161 \r
1162         String [] snWeekdays = null;\r
1163         try {\r
1164            snWeekdays = calData.getStringArray("dayNames", "stand-alone", "narrow");\r
1165         }\r
1166         catch (MissingResourceException e) {\r
1167            try {\r
1168               snWeekdays = calData.getStringArray("dayNames", "format", "narrow");\r
1169            }\r
1170            catch (MissingResourceException e1) {\r
1171               snWeekdays = calData.getStringArray("dayNames", "format", "abbreviated");\r
1172            }\r
1173         }\r
1174         standaloneNarrowWeekdays = new String[8];\r
1175         standaloneNarrowWeekdays[0] = "";  // 1-based\r
1176         System.arraycopy(snWeekdays, 0, standaloneNarrowWeekdays, 1, snWeekdays.length);\r
1177 \r
1178         ampms = calData.getStringArray("AmPmMarkers");\r
1179         \r
1180         quarters = calData.getStringArray("quarters", "wide");\r
1181         shortQuarters = calData.getStringArray("quarters", "abbreviated");\r
1182 \r
1183         try {\r
1184            standaloneQuarters = calData.getStringArray("quarters", "stand-alone", "wide");\r
1185         } \r
1186         catch (MissingResourceException e) {\r
1187            standaloneQuarters = calData.getStringArray("quarters", "format", "wide");\r
1188         }\r
1189 \r
1190         try {\r
1191            standaloneShortQuarters = calData.getStringArray("quarters", "stand-alone", "abbreviated");\r
1192         } \r
1193         catch (MissingResourceException e) {\r
1194             standaloneShortQuarters = calData.getStringArray("quarters", "format", "abbreviated");\r
1195         }\r
1196 \r
1197         // Initialize localized GMT format patterns\r
1198         initializeGMTFormat(desiredLocale);\r
1199 \r
1200         requestedLocale = desiredLocale;\r
1201 \r
1202         ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, desiredLocale);\r
1203 \r
1204         // Because localized date/time pattern characters will be obsolete in CLDR,\r
1205         // we decided not to maintain localized pattern characters in ICU any more.\r
1206         // We always use the base pattern characters by default. (ticket#5597)\r
1207 \r
1208         //localPatternChars = rb.getString("localPatternChars");\r
1209         localPatternChars = patternChars;\r
1210 \r
1211         // TODO: obtain correct actual/valid locale later\r
1212         ULocale uloc = rb.getULocale();\r
1213         setLocale(uloc, uloc);\r
1214     }\r
1215 \r
1216     static final String DEFAULT_GMT_PATTERN = "GMT{0}";\r
1217     static final String[][] DEFAULT_GMT_HOUR_PATTERNS = {\r
1218         {"-HH:mm:ss", "-HH:mm"},\r
1219         {"+HH:mm:ss", "+HH:mm"}\r
1220     };\r
1221 \r
1222     /*\r
1223      * Initialize localized GMT format patterns\r
1224      */\r
1225     private void initializeGMTFormat(ULocale desiredLocale) {\r
1226         // TimeZone format localization is not included in CalendarData\r
1227         gmtFormat = ZoneMeta.getTZLocalizationInfo(desiredLocale, ZoneMeta.GMT);\r
1228         if (gmtFormat == null) {\r
1229             gmtFormat = DEFAULT_GMT_PATTERN;\r
1230         }\r
1231 \r
1232         try {\r
1233             String offsetHM = ZoneMeta.getTZLocalizationInfo(desiredLocale, ZoneMeta.HOUR);\r
1234             gmtHourFormats = new String[2][2];\r
1235             int sepIdx = offsetHM.indexOf(';');\r
1236             if (sepIdx != -1) {\r
1237                 gmtHourFormats[OFFSET_POSITIVE][OFFSET_HM] = offsetHM.substring(0, sepIdx);\r
1238                 gmtHourFormats[OFFSET_NEGATIVE][OFFSET_HM] = offsetHM.substring(sepIdx + 1);\r
1239             } else {\r
1240                 gmtHourFormats[OFFSET_POSITIVE][OFFSET_HM] = "+HH:mm";\r
1241                 gmtHourFormats[OFFSET_NEGATIVE][OFFSET_HM] = "-HH:mm";\r
1242             }\r
1243             // CLDR 1.5 does not have GMT offset pattern including second field.\r
1244             // For now, append "ss" to the end.\r
1245             if (gmtHourFormats[OFFSET_POSITIVE][OFFSET_HM].indexOf(':') != -1) {\r
1246                 gmtHourFormats[OFFSET_POSITIVE][OFFSET_HMS] = gmtHourFormats[OFFSET_POSITIVE][OFFSET_HM] + ":ss";\r
1247             } else if (gmtHourFormats[OFFSET_POSITIVE][OFFSET_HM].indexOf('.') != -1) {\r
1248                 gmtHourFormats[OFFSET_POSITIVE][OFFSET_HMS] = gmtHourFormats[OFFSET_POSITIVE][OFFSET_HM] + ".ss";\r
1249             } else {\r
1250                 gmtHourFormats[OFFSET_POSITIVE][OFFSET_HMS] = gmtHourFormats[OFFSET_POSITIVE][OFFSET_HM] + "ss";\r
1251             }\r
1252             if (gmtHourFormats[OFFSET_NEGATIVE][OFFSET_HM].indexOf(':') != -1) {\r
1253                 gmtHourFormats[OFFSET_NEGATIVE][OFFSET_HMS] = gmtHourFormats[OFFSET_NEGATIVE][OFFSET_HM] + ":ss";\r
1254             } else if (gmtHourFormats[OFFSET_NEGATIVE][OFFSET_HM].indexOf('.') != -1) {\r
1255                 gmtHourFormats[OFFSET_NEGATIVE][OFFSET_HMS] = gmtHourFormats[OFFSET_NEGATIVE][OFFSET_HM] + ".ss";\r
1256             } else {\r
1257                 gmtHourFormats[OFFSET_NEGATIVE][OFFSET_HMS] = gmtHourFormats[OFFSET_NEGATIVE][OFFSET_HM] + "ss";\r
1258             }\r
1259         } catch (MissingResourceException e) {\r
1260             gmtHourFormats = DEFAULT_GMT_HOUR_PATTERNS;\r
1261         }\r
1262     }\r
1263 \r
1264     private static final boolean arrayOfArrayEquals(Object[][] aa1, Object[][]aa2) {\r
1265         if (aa1 == aa2) { // both are null\r
1266             return true;\r
1267         }\r
1268         if (aa1 == null || aa2 == null) { // one is null and the other is not\r
1269             return false;\r
1270         }\r
1271         if (aa1.length != aa2.length) {\r
1272             return false;\r
1273         }\r
1274         boolean equal = true;\r
1275         for (int i = 0; i < aa1.length; i++) {\r
1276             equal = Utility.arrayEquals(aa1[i], aa2[i]);\r
1277             if (!equal) {\r
1278                 break;\r
1279             }\r
1280         }\r
1281         return equal;\r
1282     }\r
1283 \r
1284     /*\r
1285      * Package local method (for now) to get localized GMT format pattern.\r
1286      */\r
1287     String getGmtFormat() {\r
1288         return gmtFormat;\r
1289     }\r
1290 \r
1291     static final int OFFSET_HMS = 0;\r
1292     static final int OFFSET_HM = 1;\r
1293     static final int OFFSET_NEGATIVE = 0;\r
1294     static final int OFFSET_POSITIVE = 1;\r
1295 \r
1296     /*\r
1297      * Package local method (for now) to get hour format pattern used by localized\r
1298      * GMT string.\r
1299      */\r
1300     String getGmtHourFormat(int sign, int width) {\r
1301         return gmtHourFormats[sign][width];\r
1302     }\r
1303 \r
1304     /*\r
1305      * Package local method to access ZoneStringFormat used by this\r
1306      * DateFormatSymbols instance.\r
1307      */\r
1308     ZoneStringFormat getZoneStringFormat() {\r
1309         if (zsformat != null) {\r
1310             return zsformat;\r
1311         }\r
1312         if (zoneStrings != null) {\r
1313             zsformat = new ZoneStringFormat(zoneStrings);\r
1314             return zsformat;\r
1315         }\r
1316         // We do not want to hold the reference to an instance of\r
1317         // ZoneStringFormat.  An instance of ZoneStringFormat for\r
1318         // a locale is shared and cached in ZoneStringFormat class\r
1319         // itself.\r
1320         return ZoneStringFormat.getInstance(requestedLocale);\r
1321     }\r
1322 \r
1323     /*\r
1324      * save the input locale\r
1325      */\r
1326     private ULocale requestedLocale; \r
1327  \r
1328     /*\r
1329      * Clones an array of Strings.\r
1330      * @param srcArray the source array to be cloned.\r
1331      * @return a cloned array.\r
1332      */\r
1333     private final String[] duplicate(String[] srcArray)\r
1334     {\r
1335         return (String[])srcArray.clone();\r
1336     }\r
1337 \r
1338     private final String[][] duplicate(String[][] srcArray)\r
1339     {\r
1340         String[][] aCopy = new String[srcArray.length][];\r
1341         for (int i = 0; i < srcArray.length; ++i)\r
1342             aCopy[i] = duplicate(srcArray[i]);\r
1343         return aCopy;\r
1344     }\r
1345 \r
1346     /*\r
1347      * Compares the equality of the two arrays of String.\r
1348      * @param current this String array.\r
1349      * @param other that String array.\r
1350     private final boolean equals(String[] current, String[] other)\r
1351     {\r
1352         int count = current.length;\r
1353 \r
1354         for (int i = 0; i < count; ++i)\r
1355             if (!current[i].equals(other[i]))\r
1356                 return false;\r
1357         return true;\r
1358     }\r
1359      */\r
1360 \r
1361     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
1362 \r
1363     /**\r
1364      * Get the {@link DateFormatSymbols} object that should be used to format a\r
1365      * calendar system's dates in the given locale.\r
1366      * <p>\r
1367      * <b>Subclassing:</b><br>\r
1368      * When creating a new Calendar subclass, you must create the\r
1369      * {@link ResourceBundle ResourceBundle}\r
1370      * containing its {@link DateFormatSymbols DateFormatSymbols} in a specific place.\r
1371      * The resource bundle name is based on the calendar's fully-specified\r
1372      * class name, with ".resources" inserted at the end of the package name\r
1373      * (just before the class name) and "Symbols" appended to the end.\r
1374      * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar"\r
1375      * is "com.ibm.icu.impl.data.HebrewCalendarSymbols".\r
1376      * <p>\r
1377      * Within the ResourceBundle, this method searches for five keys:\r
1378      * <ul>\r
1379      * <li><b>DayNames</b> -\r
1380      *      An array of strings corresponding to each possible\r
1381      *      value of the <code>DAY_OF_WEEK</code> field.  Even though\r
1382      *      <code>DAY_OF_WEEK</code> starts with <code>SUNDAY</code> = 1,\r
1383      *      This array is 0-based; the name for Sunday goes in the\r
1384      *      first position, at index 0.  If this key is not found\r
1385      *      in the bundle, the day names are inherited from the\r
1386      *      default <code>DateFormatSymbols</code> for the requested locale.\r
1387      *\r
1388      * <li><b>DayAbbreviations</b> -\r
1389      *      An array of abbreviated day names corresponding\r
1390      *      to the values in the "DayNames" array.  If this key\r
1391      *      is not found in the resource bundle, the "DayNames"\r
1392      *      values are used instead.  If neither key is found,\r
1393      *      the day abbreviations are inherited from the default\r
1394      *      <code>DateFormatSymbols</code> for the locale.\r
1395      *\r
1396      * <li><b>MonthNames</b> -\r
1397      *      An array of strings corresponding to each possible\r
1398      *      value of the <code>MONTH</code> field.  If this key is not found\r
1399      *      in the bundle, the month names are inherited from the\r
1400      *      default <code>DateFormatSymbols</code> for the requested locale.\r
1401      *\r
1402      * <li><b>MonthAbbreviations</b> -\r
1403      *      An array of abbreviated day names corresponding\r
1404      *      to the values in the "MonthNames" array.  If this key\r
1405      *      is not found in the resource bundle, the "MonthNames"\r
1406      *      values are used instead.  If neither key is found,\r
1407      *      the day abbreviations are inherited from the default\r
1408      *      <code>DateFormatSymbols</code> for the locale.\r
1409      *\r
1410      * <li><b>Eras</b> -\r
1411      *      An array of strings corresponding to each possible\r
1412      *      value of the <code>ERA</code> field.  If this key is not found\r
1413      *      in the bundle, the era names are inherited from the\r
1414      *      default <code>DateFormatSymbols</code> for the requested locale.\r
1415      * </ul>\r
1416      * <p>\r
1417      * @param cal       The calendar system whose date format symbols are desired.\r
1418      * @param locale    The locale whose symbols are desired.\r
1419      *\r
1420      * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale)\r
1421      * @stable ICU 2.0\r
1422      */\r
1423     public DateFormatSymbols(Calendar cal, Locale locale) {\r
1424         initializeData(ULocale.forLocale(locale), cal.getType());\r
1425     }\r
1426 \r
1427     /**\r
1428      * Get the {@link DateFormatSymbols} object that should be used to format a\r
1429      * calendar system's dates in the given locale.\r
1430      * <p>\r
1431      * <b>Subclassing:</b><br>\r
1432      * When creating a new Calendar subclass, you must create the\r
1433      * {@link ResourceBundle ResourceBundle}\r
1434      * containing its {@link DateFormatSymbols DateFormatSymbols} in a specific place.\r
1435      * The resource bundle name is based on the calendar's fully-specified\r
1436      * class name, with ".resources" inserted at the end of the package name\r
1437      * (just before the class name) and "Symbols" appended to the end.\r
1438      * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar"\r
1439      * is "com.ibm.icu.impl.data.HebrewCalendarSymbols".\r
1440      * <p>\r
1441      * Within the ResourceBundle, this method searches for five keys:\r
1442      * <ul>\r
1443      * <li><b>DayNames</b> -\r
1444      *      An array of strings corresponding to each possible\r
1445      *      value of the <code>DAY_OF_WEEK</code> field.  Even though\r
1446      *      <code>DAY_OF_WEEK</code> starts with <code>SUNDAY</code> = 1,\r
1447      *      This array is 0-based; the name for Sunday goes in the\r
1448      *      first position, at index 0.  If this key is not found\r
1449      *      in the bundle, the day names are inherited from the\r
1450      *      default <code>DateFormatSymbols</code> for the requested locale.\r
1451      *\r
1452      * <li><b>DayAbbreviations</b> -\r
1453      *      An array of abbreviated day names corresponding\r
1454      *      to the values in the "DayNames" array.  If this key\r
1455      *      is not found in the resource bundle, the "DayNames"\r
1456      *      values are used instead.  If neither key is found,\r
1457      *      the day abbreviations are inherited from the default\r
1458      *      <code>DateFormatSymbols</code> for the locale.\r
1459      *\r
1460      * <li><b>MonthNames</b> -\r
1461      *      An array of strings corresponding to each possible\r
1462      *      value of the <code>MONTH</code> field.  If this key is not found\r
1463      *      in the bundle, the month names are inherited from the\r
1464      *      default <code>DateFormatSymbols</code> for the requested locale.\r
1465      *\r
1466      * <li><b>MonthAbbreviations</b> -\r
1467      *      An array of abbreviated day names corresponding\r
1468      *      to the values in the "MonthNames" array.  If this key\r
1469      *      is not found in the resource bundle, the "MonthNames"\r
1470      *      values are used instead.  If neither key is found,\r
1471      *      the day abbreviations are inherited from the default\r
1472      *      <code>DateFormatSymbols</code> for the locale.\r
1473      *\r
1474      * <li><b>Eras</b> -\r
1475      *      An array of strings corresponding to each possible\r
1476      *      value of the <code>ERA</code> field.  If this key is not found\r
1477      *      in the bundle, the era names are inherited from the\r
1478      *      default <code>DateFormatSymbols</code> for the requested locale.\r
1479      * </ul>\r
1480      * <p>\r
1481      * @param cal       The calendar system whose date format symbols are desired.\r
1482      * @param locale    The ulocale whose symbols are desired.\r
1483      *\r
1484      * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale)\r
1485      * @stable ICU 3.2\r
1486      */\r
1487     public DateFormatSymbols(Calendar cal, ULocale locale) {\r
1488         initializeData(locale, cal.getType());\r
1489     }\r
1490 \r
1491     /**\r
1492      * Variant of DateFormatSymbols(Calendar, Locale) that takes the Calendar class\r
1493      * instead of a Calandar instance.\r
1494      * @see #DateFormatSymbols(Calendar, Locale)\r
1495      * @stable ICU 2.2\r
1496      */\r
1497     public DateFormatSymbols(Class calendarClass, Locale locale) {\r
1498         this(calendarClass, ULocale.forLocale(locale));\r
1499     }\r
1500 \r
1501     /**\r
1502      * Variant of DateFormatSymbols(Calendar, ULocale) that takes the Calendar class\r
1503      * instead of a Calandar instance.\r
1504      * @see #DateFormatSymbols(Calendar, Locale)\r
1505      * @stable ICU 3.2\r
1506      */\r
1507     public DateFormatSymbols(Class calendarClass, ULocale locale) {\r
1508         String fullName = calendarClass.getName();\r
1509         int lastDot = fullName.lastIndexOf('.');\r
1510         String className = fullName.substring(lastDot+1);\r
1511         String calType = Utility.replaceAll(className, "Calendar", "").toLowerCase();\r
1512         \r
1513         initializeData(locale, calType);\r
1514     }\r
1515 \r
1516     /**\r
1517      * Fetch a custom calendar's DateFormatSymbols out of the given resource\r
1518      * bundle.  Symbols that are not overridden are inherited from the\r
1519      * default DateFormatSymbols for the locale.\r
1520      * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale)\r
1521      * @stable ICU 2.0\r
1522      */\r
1523     public DateFormatSymbols(ResourceBundle bundle, Locale locale) {\r
1524         this(bundle, ULocale.forLocale(locale));\r
1525     }\r
1526 \r
1527     /**\r
1528      * Fetch a custom calendar's DateFormatSymbols out of the given resource\r
1529      * bundle.  Symbols that are not overridden are inherited from the\r
1530      * default DateFormatSymbols for the locale.\r
1531      * @see DateFormatSymbols#DateFormatSymbols(java.util.Locale)\r
1532      * @stable ICU 3.2\r
1533      */\r
1534     public DateFormatSymbols(ResourceBundle bundle, ULocale locale) {\r
1535         initializeData(locale, \r
1536             new CalendarData((ICUResourceBundle)bundle, getCalendarType(locale)));\r
1537     }\r
1538 \r
1539     /**\r
1540      * Find the ResourceBundle containing the date format information for\r
1541      * a specified calendar subclass in a given locale.\r
1542      * <p>\r
1543      * The resource bundle name is based on the calendar's fully-specified\r
1544      * class name, with ".resources" inserted at the end of the package name\r
1545      * (just before the class name) and "Symbols" appended to the end.\r
1546      * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar"\r
1547      * is "com.ibm.icu.impl.data.HebrewCalendarSymbols".\r
1548      * <p>\r
1549      * <b>Note:</b>Because of the structural changes in the ICU locale bundle,\r
1550      * this API no longer works as described.  This method always returns null.\r
1551      * @deprecated ICU 4.0\r
1552      */\r
1553     // This API was formerly @stable ICU 2.0\r
1554     static public ResourceBundle getDateFormatBundle(Class calendarClass, Locale locale)\r
1555         throws MissingResourceException {\r
1556         return null;\r
1557     }\r
1558         \r
1559     /**\r
1560      * Find the ResourceBundle containing the date format information for\r
1561      * a specified calendar subclass in a given locale.\r
1562      * <p>\r
1563      * The resource bundle name is based on the calendar's fully-specified\r
1564      * class name, with ".resources" inserted at the end of the package name\r
1565      * (just before the class name) and "Symbols" appended to the end.\r
1566      * For example, the bundle corresponding to "com.ibm.icu.util.HebrewCalendar"\r
1567      * is "com.ibm.icu.impl.data.HebrewCalendarSymbols".\r
1568      * <p>\r
1569      * <b>Note:</b>Because of the structural changes in the ICU locale bundle,\r
1570      * this API no longer works as described.  This method always returns null.\r
1571      * @deprecated ICU 4.0\r
1572      */\r
1573     // This API was formerly @stable ICU 3.2\r
1574     static public ResourceBundle getDateFormatBundle(Class calendarClass, ULocale locale)\r
1575         throws MissingResourceException {\r
1576         return null;\r
1577     }\r
1578 \r
1579     /**\r
1580      * Variant of getDateFormatBundle(java.lang.Class, java.util.Locale) that takes\r
1581      * a Calendar instance instead of a Calendar class.\r
1582      * <p>\r
1583      * <b>Note:</b>Because of the structural changes in the ICU locale bundle,\r
1584      * this API no longer works as described.  This method always returns null.\r
1585      * @see #getDateFormatBundle(java.lang.Class, java.util.Locale)\r
1586      * @deprecated ICU 4.0\r
1587      */\r
1588     // This API was formerly @stable ICU 2.2\r
1589     public static ResourceBundle getDateFormatBundle(Calendar cal, Locale locale)\r
1590         throws MissingResourceException {\r
1591         return null;\r
1592     }\r
1593     \r
1594     /**\r
1595      * Variant of getDateFormatBundle(java.lang.Class, java.util.Locale) that takes\r
1596      * a Calendar instance instead of a Calendar class.\r
1597      * <p>\r
1598      * <b>Note:</b>Because of the structural changes in the ICU locale bundle,\r
1599      * this API no longer works as described.  This method always returns null.\r
1600      * @see #getDateFormatBundle(java.lang.Class, java.util.Locale)\r
1601      * @deprecated ICU 4.0\r
1602      */\r
1603     // This API was formerly @stable ICU 3.2\r
1604     public static ResourceBundle getDateFormatBundle(Calendar cal, ULocale locale)\r
1605         throws MissingResourceException {\r
1606         return null;\r
1607     }\r
1608 \r
1609     // Return the calendar type string for the given locale\r
1610     private static String getCalendarType(ULocale locale) {\r
1611         String calType = locale.getKeywordValue("calendar");\r
1612         if (calType == null) {\r
1613             locale = ICUResourceBundle.getFunctionalEquivalent(\r
1614                 ICUResourceBundle.ICU_BASE_NAME, "calendar", "calendar", locale, null, false);\r
1615             calType = locale.getKeywordValue("calendar");\r
1616         }\r
1617         return calType;\r
1618     }\r
1619 \r
1620     // -------- BEGIN ULocale boilerplate --------\r
1621 \r
1622     /**\r
1623      * Return the locale that was used to create this object, or null.\r
1624      * This may may differ from the locale requested at the time of\r
1625      * this object's creation.  For example, if an object is created\r
1626      * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be\r
1627      * drawn from <tt>en</tt> (the <i>actual</i> locale), and\r
1628      * <tt>en_US</tt> may be the most specific locale that exists (the\r
1629      * <i>valid</i> locale).\r
1630      *\r
1631      * <p>Note: This method will be implemented in ICU 3.0; ICU 2.8\r
1632      * contains a partial preview implementation.  The * <i>actual</i>\r
1633      * locale is returned correctly, but the <i>valid</i> locale is\r
1634      * not, in most cases.\r
1635      * @param type type of information requested, either {@link\r
1636      * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link\r
1637      * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.\r
1638      * @return the information specified by <i>type</i>, or null if\r
1639      * this object was not constructed from locale data.\r
1640      * @see com.ibm.icu.util.ULocale\r
1641      * @see com.ibm.icu.util.ULocale#VALID_LOCALE\r
1642      * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE\r
1643      * @draft ICU 2.8 (retain)\r
1644      * @provisional This API might change or be removed in a future release.\r
1645      */\r
1646     public final ULocale getLocale(ULocale.Type type) {\r
1647         return type == ULocale.ACTUAL_LOCALE ?\r
1648             this.actualLocale : this.validLocale;\r
1649     }\r
1650 \r
1651     /*\r
1652      * Set information about the locales that were used to create this\r
1653      * object.  If the object was not constructed from locale data,\r
1654      * both arguments should be set to null.  Otherwise, neither\r
1655      * should be null.  The actual locale must be at the same level or\r
1656      * less specific than the valid locale.  This method is intended\r
1657      * for use by factories or other entities that create objects of\r
1658      * this class.\r
1659      * @param valid the most specific locale containing any resource\r
1660      * data, or null\r
1661      * @param actual the locale containing data used to construct this\r
1662      * object, or null\r
1663      * @see com.ibm.icu.util.ULocale\r
1664      * @see com.ibm.icu.util.ULocale#VALID_LOCALE\r
1665      * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE\r
1666      */\r
1667     final void setLocale(ULocale valid, ULocale actual) {\r
1668         // Change the following to an assertion later\r
1669         if ((valid == null) != (actual == null)) {\r
1670             ///CLOVER:OFF\r
1671             throw new IllegalArgumentException();\r
1672             ///CLOVER:ON\r
1673         }\r
1674         // Another check we could do is that the actual locale is at\r
1675         // the same level or less specific than the valid locale.\r
1676         this.validLocale = valid;\r
1677         this.actualLocale = actual;\r
1678     }\r
1679 \r
1680     /*\r
1681      * The most specific locale containing any resource data, or null.\r
1682      * @see com.ibm.icu.util.ULocale\r
1683      */\r
1684     private ULocale validLocale;\r
1685 \r
1686     /*\r
1687      * The locale containing data used to construct this object, or\r
1688      * null.\r
1689      * @see com.ibm.icu.util.ULocale\r
1690      */\r
1691     private ULocale actualLocale;\r
1692 \r
1693     // -------- END ULocale boilerplate --------\r
1694 \r
1695     /*\r
1696      * 3.8 or older version did not have localized GMT format\r
1697      * patterns.\r
1698      */\r
1699     private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {\r
1700         stream.defaultReadObject();\r
1701         if (gmtFormat == null) {\r
1702             initializeGMTFormat(requestedLocale);\r
1703         }\r
1704     }\r
1705 }\r