1 /* ChoiceFormat.java -- Format over a range of numbers
2    Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 
39 package java.text;
40 
41 import java.util.Locale;
42 import java.util.MissingResourceException;
43 import java.util.ResourceBundle;
44 
45 /**
46  * This class acts as container for locale specific date/time formatting
47  * information such as the days of the week and the months of the year.
48  * @author Per Bothner <bothner@cygnus.com>
49  * @date October 24, 1998.
50  */
51 /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3.
52  * Status:  Believed complete and correct.
53  */
54 public class DateFormatSymbols implements java.io.Serializable, Cloneable
55 {
56   String[] ampms;
57   String[] eras;
58   private String localPatternChars;
59   String[] months;
60   String[] shortMonths;
61   String[] shortWeekdays;
62   String[] weekdays;
63   private String[][] zoneStrings;
64 
65   private static final long serialVersionUID = -5987973545549424702L;
66 
67   // The order of these prefixes must be the same as in DateFormat
68   private static final String[] formatPrefixes =
69   {
70     "full", "long", "medium", "short"
71   };
72 
73   // These are each arrays with a value for SHORT, MEDIUM, LONG, FULL,
74   // and DEFAULT (constants defined in java.text.DateFormat).  While
75   // not part of the official spec, we need a way to get at locale-specific
76   // default formatting patterns.  They are declared package scope so
77   // as to be easily accessible where needed (DateFormat, SimpleDateFormat).
78   transient String[] dateFormats;
79   transient String[] timeFormats;
80 
formatsForKey(ResourceBundle res, String key)81   private String[] formatsForKey(ResourceBundle res, String key)
82   {
83     String[] values = new String [formatPrefixes.length];
84     for (int i = 0; i < formatPrefixes.length; i++)
85       {
86         values[i] = res.getString(formatPrefixes[i]+key);
87       }
88     return values;
89   }
90 
91   /**
92    * This method initializes a new instance of <code>DateFormatSymbols</code>
93    * by loading the date format information for the specified locale.
94    *
95    * @param locale The locale for which date formatting symbols should
96    *               be loaded.
97    */
DateFormatSymbols(Locale locale)98   public DateFormatSymbols (Locale locale) throws MissingResourceException
99   {
100     ResourceBundle res
101       = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", locale);
102 
103     ampms = res.getStringArray ("ampms");
104     eras = res.getStringArray ("eras");
105     localPatternChars = res.getString ("localPatternChars");
106     months = res.getStringArray ("months");
107     shortMonths = res.getStringArray ("shortMonths");
108     shortWeekdays = res.getStringArray ("shortWeekdays");
109     weekdays = res.getStringArray ("weekdays");
110     zoneStrings = (String[][]) res.getObject ("zoneStrings");
111 
112     dateFormats = formatsForKey(res, "DateFormat");
113     timeFormats = formatsForKey(res, "TimeFormat");
114   }
115 
116   /**
117    * This method loads the format symbol information for the default
118    * locale.
119    */
DateFormatSymbols()120   public DateFormatSymbols () throws MissingResourceException
121   {
122     this (Locale.getDefault());
123   }
124 
125   /**
126    * This method returns the list of strings used for displaying AM or PM.
127    * This is a two element <code>String</code> array indexed by
128    * <code>Calendar.AM</code> and <code>Calendar.PM</code>
129    *
130    * @return The list of AM/PM display strings.
131    */
getAmPmStrings()132   public String[] getAmPmStrings()
133   {
134     return ampms;
135   }
136 
137   /**
138     * This method returns the list of strings used for displaying eras
139     * (e.g., "BC" and "AD").  This is a two element <code>String</code>
140     * array indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.
141     *
142     * @return The list of era disply strings.
143     */
getEras()144   public String[] getEras()
145   {
146     return eras;
147   }
148 
149   /**
150     * This method returns the pattern character information for this
151     * object.  This is an 18 character string that contains the characters
152     * that are used in creating the date formatting strings in
153     * <code>SimpleDateFormat</code>.   The following are the character
154     * positions in the string and which format character they correspond
155     * to (the character in parentheses is the default value in the US English
156     * locale):
157     * <p>
158     * <ul>
159     * <li>0 - era (G)</li>
160     * <li>1 - year (y)</li>
161     * <li>2 - month (M)</li>
162     * <li>3 - day of month (d)</li>
163     * <li>4 - hour out of 12, from 1-12 (h)</li>
164     * <li>5 - hour out of 24, from 0-23 (H)</li>
165     * <li>6 - minute (m)</li>
166     * <li>7 - second (s)</li>
167     * <li>8 - millisecond (S)</li>
168     * <li>9 - date of week (E)</li>
169     * <li>10 - date of year (D)</li>
170     * <li>11 - day of week in month, eg. "4th Thur in Nov" (F)</li>
171     * <li>12 - week in year (w)</li>
172     * <li>13 - week in month (W)</li>
173     * <li>14 - am/pm (a)</li>
174     * <li>15 - hour out of 24, from 1-24 (k)</li>
175     * <li>16 - hour out of 12, from 0-11 (K)</li>
176     * <li>17 - time zone (z)</li>
177     * </ul>
178     *
179     * @return The format patter characters
180     */
getLocalPatternChars()181   public String getLocalPatternChars()
182   {
183     return localPatternChars;
184   }
185 
186   /**
187    * This method returns the list of strings used for displaying month
188    * names (e.g., "January" and "February").  This is a thirteen element
189    * string array indexed by <code>Calendar.JANUARY</code> through
190    * <code>Calendar.UNDECEMBER</code>.  Note that there are thirteen
191    * elements because some calendars have thriteen months.
192    *
193    * @return The list of month display strings.
194    */
getMonths()195   public String[] getMonths ()
196   {
197     return months;
198   }
199 
200   /**
201    * This method returns the list of strings used for displaying abbreviated
202    * month names (e.g., "Jan" and "Feb").  This is a thirteen element
203    * <code>String</code> array indexed by <code>Calendar.JANUARY</code>
204    * through <code>Calendar.UNDECEMBER</code>.  Note that there are thirteen
205    * elements because some calendars have thirteen months.
206    *
207    * @return The list of abbreviated month display strings.
208    */
getShortMonths()209   public String[] getShortMonths ()
210   {
211     return shortMonths;
212   }
213 
214   /**
215    * This method returns the list of strings used for displaying abbreviated
216    * weekday names (e.g., "Sun" and "Mon").  This is an eight element
217    * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
218    * through <code>Calendar.SATURDAY</code>.  Note that the first element
219    * of this array is ignored.
220    *
221    * @return This list of abbreviated weekday display strings.
222    */
getShortWeekdays()223   public String[] getShortWeekdays ()
224   {
225     return shortWeekdays;
226   }
227 
228   /**
229    * This method returns the list of strings used for displaying weekday
230    * names (e.g., "Sunday" and "Monday").  This is an eight element
231    * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
232    * through <code>Calendar.SATURDAY</code>.  Note that the first element
233    * of this array is ignored.
234    *
235    * @return This list of weekday display strings.
236    */
getWeekdays()237   public String[] getWeekdays ()
238   {
239     return weekdays;
240   }
241 
242   /**
243    * This method returns this list of localized timezone display strings.
244    * This is a two dimensional <code>String</code> array where each row in
245    * the array contains five values:
246    * <P>
247    * <ul>
248    * <li>0 - The non-localized time zone id string.
249    * <li>1 - The long name of the time zone (standard time).
250    * <li>2 - The short name of the time zone (standard time).
251    * <li>3 - The long name of the time zone (daylight savings time).
252    * <li>4 - the short name of the time zone (daylight savings time).
253    *
254    * @return The list of time zone display strings.
255    */
getZoneStrings()256   public String[] [] getZoneStrings ()
257   {
258     return zoneStrings;
259   }
260 
261   /**
262    * This method sets the list of strings used to display AM/PM values to
263    * the specified list.
264    * This is a two element <code>String</code> array indexed by
265    * <code>Calendar.AM</code> and <code>Calendar.PM</code>
266    *
267    * @param ampms The new list of AM/PM display strings.
268    */
setAmPmStrings(String[] value)269   public void setAmPmStrings (String[] value)
270   {
271     ampms = value;
272   }
273 
274   /**
275    * This method sets the list of strings used to display time eras to
276    * to the specified list.
277    * This is a two element <code>String</code>
278    * array indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.
279    *
280    * @param eras The new list of era disply strings.
281    */
setEras(String[] value)282   public void setEras (String[] value)
283   {
284     eras = value;
285   }
286 
287   /**
288     * This method sets the list of characters used to specific date/time
289     * formatting strings.
290     * This is an 18 character string that contains the characters
291     * that are used in creating the date formatting strings in
292     * <code>SimpleDateFormat</code>.   The following are the character
293     * positions in the string and which format character they correspond
294     * to (the character in parentheses is the default value in the US English
295     * locale):
296     * <p>
297     * <ul>
298     * <li>0 - era (G)</li>
299     * <li>1 - year (y)</li>
300     * <li>2 - month (M)</li>
301     * <li>3 - day of month (d)</li>
302     * <li>4 - hour out of 12, from 1-12 (h)</li>
303     * <li>5 - hour out of 24, from 0-23 (H)</li>
304     * <li>6 - minute (m)</li>
305     * <li>7 - second (s)</li>
306     * <li>8 - millisecond (S)</li>
307     * <li>9 - date of week (E)</li>
308     * <li>10 - date of year (D)</li>
309     * <li>11 - day of week in month, eg. "4th Thur in Nov" (F)</li>
310     * <li>12 - week in year (w)</li>
311     * <li>13 - week in month (W)</li>
312     * <li>14 - am/pm (a)</li>
313     * <li>15 - hour out of 24, from 1-24 (k)</li>
314     * <li>16 - hour out of 12, from 0-11 (K)</li>
315     * <li>17 - time zone (z)</li>
316     * </ul>
317     *
318     * @param localPatternChars The new format patter characters
319     */
setLocalPatternChars(String value)320   public void setLocalPatternChars (String value)
321   {
322     localPatternChars = value;
323   }
324 
325   /**
326     * This method sets the list of strings used to display month names.
327     * This is a thirteen element
328     * string array indexed by <code>Calendar.JANUARY</code> through
329     * <code>Calendar.UNDECEMBER</code>.  Note that there are thirteen
330     * elements because some calendars have thriteen months.
331     *
332     * @param months The list of month display strings.
333     */
setMonths(String[] value)334   public void setMonths (String[] value)
335   {
336     months = value;
337   }
338 
339   /**
340    * This method sets the list of strings used to display abbreviated month
341    * names.
342    * This is a thirteen element
343    * <code>String</code> array indexed by <code>Calendar.JANUARY</code>
344    * through <code>Calendar.UNDECEMBER</code>.  Note that there are thirteen
345    * elements because some calendars have thirteen months.
346    *
347    * @param shortMonths The new list of abbreviated month display strings.
348    */
setShortMonths(String[] value)349   public void setShortMonths (String[] value)
350   {
351     shortMonths = value;
352   }
353 
354   /**
355    * This method sets the list of strings used to display abbreviated
356    * weekday names.
357    * This is an eight element
358    * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
359    * through <code>Calendar.SATURDAY</code>.  Note that the first element
360    * of this array is ignored.
361    *
362    * @param shortWeekdays This list of abbreviated weekday display strings.
363    */
setShortWeekdays(String[] value)364   public void setShortWeekdays (String[] value)
365   {
366     shortWeekdays = value;
367   }
368 
369   /**
370    * This method sets the list of strings used to display weekday names.
371    * This is an eight element
372    * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
373    * through <code>Calendar.SATURDAY</code>.  Note that the first element
374    * of this array is ignored.
375    *
376    * @param weekdays This list of weekday display strings.
377    */
setWeekdays(String[] value)378   public void setWeekdays (String[] value)
379   {
380     weekdays = value;
381   }
382 
383   /**
384    * This method sets the list of display strings for time zones.
385    * This is a two dimensional <code>String</code> array where each row in
386    * the array contains five values:
387    * <P>
388    * <ul>
389    * <li>0 - The non-localized time zone id string.
390    * <li>1 - The long name of the time zone (standard time).
391    * <li>2 - The short name of the time zone (standard time).
392    * <li>3 - The long name of the time zone (daylight savings time).
393    * <li>4 - the short name of the time zone (daylight savings time).
394    *
395    * @return The list of time zone display strings.
396    */
setZoneStrings(String[][] value)397   public void setZoneStrings (String[][] value)
398   {
399     zoneStrings = value;
400   }
401 
402   /* Does a "deep" equality test - recurses into arrays. */
equals(Object x, Object y)403   private static boolean equals (Object x, Object y)
404   {
405     if (x == y)
406       return true;
407     if (x == null || y == null)
408       return false;
409     if (! (x instanceof Object[]) || ! (y instanceof Object[]))
410       return x.equals(y);
411     Object[] xa = (Object[]) x;
412     Object[] ya = (Object[]) y;
413     if (xa.length != ya.length)
414       return false;
415     for (int i = xa.length;  --i >= 0; )
416       {
417 	if (! equals(xa[i], ya[i]))
418 	  return false;
419       }
420     return true;
421   }
422 
hashCode(Object x)423   private static int hashCode (Object x)
424   {
425     if (x == null)
426       return 0;
427     if (! (x instanceof Object[]))
428       return x.hashCode();
429     Object[] xa = (Object[]) x;
430     int hash = 0;
431     for (int i = 0;  i < xa.length;  i++)
432       hash = 37 * hashCode(xa[i]);
433     return hash;
434   }
435 
436   /**
437    * This method tests a specified object for equality against this object.
438    * This will be true if and only if the specified object:
439    * <p>
440    * <ul>
441    * <li> Is not <code>null</code>.
442    * <li> Is an instance of <code>DateFormatSymbols</code>.
443    * <li> Contains identical formatting symbols to this object.
444    * </ul>
445    *
446    * @param obj The <code>Object</code> to test for equality against.
447    *
448    * @return <code>true</code> if the specified object is equal to this one,
449    * </code>false</code> otherwise.
450    */
equals(Object obj)451   public boolean equals (Object obj)
452   {
453     if (! (obj instanceof DateFormatSymbols))
454       return false;
455     DateFormatSymbols other = (DateFormatSymbols) obj;
456     return (equals(ampms, other.ampms)
457 	    && equals(eras, other.eras)
458 	    && equals(localPatternChars, other.localPatternChars)
459 	    && equals(months, other.months)
460 	    && equals(shortMonths, other.shortMonths)
461 	    && equals(shortWeekdays, other.shortWeekdays)
462 	    && equals(weekdays, other.weekdays)
463 	    && equals(zoneStrings, other.zoneStrings));
464   }
465 
466   /**
467    * Returns a new copy of this object.
468    *
469    * @param A copy of this object
470    */
clone()471   public Object clone ()
472   {
473     try
474       {
475         return super.clone ();
476       }
477     catch (CloneNotSupportedException e)
478       {
479         return null;
480       }
481   }
482 
483   /**
484    * This method returns a hash value for this object.
485    *
486    * @return A hash value for this object.
487    */
hashCode()488   public int hashCode ()
489   {
490     return (hashCode(ampms)
491 	    ^ hashCode(eras)
492 	    ^ hashCode(localPatternChars)
493 	    ^ hashCode(months)
494 	    ^ hashCode(shortMonths)
495 	    ^ hashCode(shortWeekdays)
496 	    ^ hashCode(weekdays)
497 	    ^ hashCode(zoneStrings));
498   }
499 }
500