Source for java.text.DateFormatSymbols

   1: /* DateFormatSymbols.java -- Format over a range of numbers
   2:    Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005  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., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 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: 
  81:   private static String[] getStringArray(ResourceBundle res, String name)
  82:   { 
  83:     return res.getString(name).split("\u00ae");
  84:   }
  85: 
  86:   private String[][] getZoneStrings(ResourceBundle res)
  87:   {
  88:     try
  89:       {
  90:         int index = 0;
  91:         String data = res.getString("zoneStrings");
  92:     String[] zones = data.split("\u00a9");
  93:     String[][] array = new String[zones.length][];
  94:     for (int a = 0; a < zones.length; ++a)
  95:       array[a] = zones[a].split("\u00ae");
  96:     return array;
  97:       }
  98:     catch (MissingResourceException e)
  99:       {
 100:     return new String[0][];
 101:       }
 102:   }
 103:   
 104:   private String[] formatsForKey(ResourceBundle res, String key) 
 105:   {
 106:     String[] values = new String[formatPrefixes.length];
 107:     
 108:     for (int i = 0; i < formatPrefixes.length; i++)
 109:       values[i] = res.getString(formatPrefixes[i] + key);
 110:   
 111:     return values;
 112:   }
 113: 
 114:   /**
 115:    * This method initializes a new instance of <code>DateFormatSymbols</code>
 116:    * by loading the date format information for the specified locale.
 117:    *
 118:    * @param locale The locale for which date formatting symbols should
 119:    *               be loaded. 
 120:    */
 121:   public DateFormatSymbols (Locale locale) throws MissingResourceException
 122:   {
 123:     ResourceBundle res
 124:       = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", locale,
 125:                        ClassLoader.getSystemClassLoader());
 126: 
 127:     ampms = getStringArray(res, "ampms");
 128:     eras = getStringArray(res, "eras");
 129:     localPatternChars = res.getString("localPatternChars");
 130:     months = getStringArray(res, "months");
 131:     shortMonths = getStringArray(res, "shortMonths");
 132:     shortWeekdays = getStringArray(res, "shortWeekdays");
 133:     weekdays = getStringArray(res, "weekdays");
 134:     zoneStrings = getZoneStrings(res);
 135:     dateFormats = formatsForKey(res, "DateFormat");
 136:     timeFormats = formatsForKey(res, "TimeFormat");
 137:   }
 138: 
 139:   /**
 140:    * This method loads the format symbol information for the default
 141:    * locale.
 142:    */
 143:   public DateFormatSymbols () throws MissingResourceException
 144:   {
 145:     this (Locale.getDefault());
 146:   }
 147: 
 148:   /**
 149:    * This method returns the list of strings used for displaying AM or PM.
 150:    * This is a two element <code>String</code> array indexed by
 151:    * <code>Calendar.AM</code> and <code>Calendar.PM</code>
 152:    *
 153:    * @return The list of AM/PM display strings.
 154:    */
 155:   public String[] getAmPmStrings()
 156:   {
 157:     return ampms;
 158:   }
 159: 
 160:   /**
 161:     * This method returns the list of strings used for displaying eras
 162:     * (e.g., "BC" and "AD").  This is a two element <code>String</code>
 163:     * array indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.
 164:     *
 165:     * @return The list of era disply strings.
 166:     */
 167:   public String[] getEras()
 168:   {
 169:     return eras;
 170:   }
 171: 
 172:   /**
 173:     * This method returns the pattern character information for this
 174:     * object.  This is an 18 character string that contains the characters
 175:     * that are used in creating the date formatting strings in 
 176:     * <code>SimpleDateFormat</code>.   The following are the character
 177:     * positions in the string and which format character they correspond
 178:     * to (the character in parentheses is the default value in the US English
 179:     * locale):
 180:     * <p>
 181:     * <ul>
 182:     * <li>0 - era (G)</li>
 183:     * <li>1 - year (y)</li>
 184:     * <li>2 - month (M)</li>
 185:     * <li>3 - day of month (d)</li>
 186:     * <li>4 - hour out of 12, from 1-12 (h)</li>
 187:     * <li>5 - hour out of 24, from 0-23 (H)</li>
 188:     * <li>6 - minute (m)</li>
 189:     * <li>7 - second (s)</li>
 190:     * <li>8 - millisecond (S)</li>
 191:     * <li>9 - date of week (E)</li>
 192:     * <li>10 - date of year (D)</li>
 193:     * <li>11 - day of week in month, eg. "4th Thur in Nov" (F)</li>
 194:     * <li>12 - week in year (w)</li>
 195:     * <li>13 - week in month (W)</li>
 196:     * <li>14 - am/pm (a)</li>
 197:     * <li>15 - hour out of 24, from 1-24 (k)</li>
 198:     * <li>16 - hour out of 12, from 0-11 (K)</li>
 199:     * <li>17 - time zone (z)</li>
 200:     * </ul>
 201:     *
 202:     * @return The format patter characters
 203:     */
 204:   public String getLocalPatternChars()
 205:   {
 206:     return localPatternChars;
 207:   }
 208: 
 209:   /**
 210:    * This method returns the list of strings used for displaying month
 211:    * names (e.g., "January" and "February").  This is a thirteen element
 212:    * string array indexed by <code>Calendar.JANUARY</code> through
 213:    * <code>Calendar.UNDECEMBER</code>.  Note that there are thirteen
 214:    * elements because some calendars have thriteen months.
 215:    *
 216:    * @return The list of month display strings.
 217:    */
 218:   public String[] getMonths ()
 219:   {
 220:     return months;
 221:   }
 222: 
 223:   /**
 224:    * This method returns the list of strings used for displaying abbreviated
 225:    * month names (e.g., "Jan" and "Feb").  This is a thirteen element
 226:    * <code>String</code> array indexed by <code>Calendar.JANUARY</code>
 227:    * through <code>Calendar.UNDECEMBER</code>.  Note that there are thirteen
 228:    * elements because some calendars have thirteen months.
 229:    *
 230:    * @return The list of abbreviated month display strings.
 231:    */
 232:   public String[] getShortMonths ()
 233:   {
 234:     return shortMonths;
 235:   }
 236: 
 237:   /**
 238:    * This method returns the list of strings used for displaying abbreviated 
 239:    * weekday names (e.g., "Sun" and "Mon").  This is an eight element
 240:    * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
 241:    * through <code>Calendar.SATURDAY</code>.  Note that the first element
 242:    * of this array is ignored.
 243:    *
 244:    * @return This list of abbreviated weekday display strings.
 245:    */
 246:   public String[] getShortWeekdays ()
 247:   {
 248:     return shortWeekdays;
 249:   }
 250: 
 251:   /**
 252:    * This method returns the list of strings used for displaying weekday
 253:    * names (e.g., "Sunday" and "Monday").  This is an eight element
 254:    * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
 255:    * through <code>Calendar.SATURDAY</code>.  Note that the first element
 256:    * of this array is ignored.
 257:    *
 258:    * @return This list of weekday display strings.
 259:    */
 260:   public String[] getWeekdays ()
 261:   {
 262:     return weekdays;
 263:   }
 264: 
 265:   /**
 266:    * This method returns this list of localized timezone display strings.
 267:    * This is a two dimensional <code>String</code> array where each row in
 268:    * the array contains five values:
 269:    * <P>
 270:    * <ul>
 271:    * <li>0 - The non-localized time zone id string.</li>
 272:    * <li>1 - The long name of the time zone (standard time).</li>
 273:    * <li>2 - The short name of the time zone (standard time).</li>
 274:    * <li>3 - The long name of the time zone (daylight savings time).</li>
 275:    * <li>4 - the short name of the time zone (daylight savings time).</li>
 276:    * </ul>
 277:    *
 278:    * @return The list of time zone display strings.
 279:    */
 280:   public String[] [] getZoneStrings ()
 281:   {
 282:     return zoneStrings;
 283:   }
 284: 
 285:   /**
 286:    * This method sets the list of strings used to display AM/PM values to
 287:    * the specified list.
 288:    * This is a two element <code>String</code> array indexed by
 289:    * <code>Calendar.AM</code> and <code>Calendar.PM</code>
 290:    *
 291:    * @param value The new list of AM/PM display strings.
 292:    */
 293:   public void setAmPmStrings (String[] value)
 294:   {
 295:     ampms = value;
 296:   }
 297: 
 298:   /**
 299:    * This method sets the list of strings used to display time eras to
 300:    * to the specified list.
 301:    * This is a two element <code>String</code>
 302:    * array indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.
 303:    *
 304:    * @param labels The new list of era display strings.
 305:    */
 306:   public void setEras (String[] labels)
 307:   {
 308:     eras = labels;
 309:   }
 310: 
 311:   /**
 312:     * This method sets the list of characters used to specific date/time
 313:     * formatting strings.
 314:     * This is an 18 character string that contains the characters
 315:     * that are used in creating the date formatting strings in 
 316:     * <code>SimpleDateFormat</code>.   The following are the character
 317:     * positions in the string and which format character they correspond
 318:     * to (the character in parentheses is the default value in the US English
 319:     * locale):
 320:     * <p>
 321:     * <ul>
 322:     * <li>0 - era (G)</li>
 323:     * <li>1 - year (y)</li>
 324:     * <li>2 - month (M)</li>
 325:     * <li>3 - day of month (d)</li>
 326:     * <li>4 - hour out of 12, from 1-12 (h)</li>
 327:     * <li>5 - hour out of 24, from 0-23 (H)</li>
 328:     * <li>6 - minute (m)</li>
 329:     * <li>7 - second (s)</li>
 330:     * <li>8 - millisecond (S)</li>
 331:     * <li>9 - date of week (E)</li>
 332:     * <li>10 - date of year (D)</li>
 333:     * <li>11 - day of week in month, eg. "4th Thur in Nov" (F)</li>
 334:     * <li>12 - week in year (w)</li>
 335:     * <li>13 - week in month (W)</li>
 336:     * <li>14 - am/pm (a)</li>
 337:     * <li>15 - hour out of 24, from 1-24 (k)</li>
 338:     * <li>16 - hour out of 12, from 0-11 (K)</li>
 339:     * <li>17 - time zone (z)</li>
 340:     * </ul>
 341:     *
 342:     * @param chars The new format pattern characters
 343:     */
 344:   public void setLocalPatternChars (String chars)
 345:   {
 346:     localPatternChars = chars;
 347:   }
 348: 
 349:   /**
 350:     * This method sets the list of strings used to display month names.
 351:     * This is a thirteen element
 352:     * string array indexed by <code>Calendar.JANUARY</code> through
 353:     * <code>Calendar.UNDECEMBER</code>.  Note that there are thirteen
 354:     * elements because some calendars have thriteen months.
 355:     *
 356:     * @param labels The list of month display strings.
 357:     */
 358:   public void setMonths (String[] labels)
 359:   {
 360:     months = labels;
 361:   }
 362: 
 363:   /**
 364:    * This method sets the list of strings used to display abbreviated month
 365:    * names.
 366:    * This is a thirteen element
 367:    * <code>String</code> array indexed by <code>Calendar.JANUARY</code>
 368:    * through <code>Calendar.UNDECEMBER</code>.  Note that there are thirteen
 369:    * elements because some calendars have thirteen months.
 370:    *
 371:    * @param labels The new list of abbreviated month display strings.
 372:    */
 373:   public void setShortMonths (String[] labels)
 374:   {
 375:     shortMonths = labels;
 376:   }
 377: 
 378:   /**
 379:    * This method sets the list of strings used to display abbreviated
 380:    * weekday names.
 381:    * This is an eight element
 382:    * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
 383:    * through <code>Calendar.SATURDAY</code>.  Note that the first element
 384:    * of this array is ignored.
 385:    *
 386:    * @param labels This list of abbreviated weekday display strings.
 387:    */
 388:   public void setShortWeekdays (String[] labels)
 389:   {
 390:     shortWeekdays = labels;
 391:   }
 392: 
 393:   /**
 394:    * This method sets the list of strings used to display weekday names.
 395:    * This is an eight element
 396:    * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
 397:    * through <code>Calendar.SATURDAY</code>.  Note that the first element
 398:    * of this array is ignored.
 399:    *
 400:    * @param labels This list of weekday display strings.
 401:    */
 402:   public void setWeekdays (String[] labels)
 403:   {
 404:     weekdays = labels;
 405:   }
 406: 
 407:   /**
 408:    * This method sets the list of display strings for time zones.
 409:    * This is a two dimensional <code>String</code> array where each row in
 410:    * the array contains five values:
 411:    * <P>
 412:    * <ul>
 413:    * <li>0 - The non-localized time zone id string.</li>
 414:    * <li>1 - The long name of the time zone (standard time).</li>
 415:    * <li>2 - The short name of the time zone (standard time).</li>
 416:    * <li>3 - The long name of the time zone (daylight savings time).</li>
 417:    * <li>4 - the short name of the time zone (daylight savings time).</li>
 418:    * </ul>
 419:    *
 420:    * @params zones The list of time zone display strings.
 421:    */
 422:   public void setZoneStrings (String[][] zones)
 423:   {
 424:     zoneStrings = zones;
 425:   }
 426: 
 427:   /* Does a "deep" equality test - recurses into arrays. */
 428:   private static boolean equals (Object x, Object y)
 429:   {
 430:     if (x == y)
 431:       return true;
 432:     if (x == null || y == null)
 433:       return false;
 434:     if (! (x instanceof Object[]) || ! (y instanceof Object[]))
 435:       return x.equals(y);
 436:     Object[] xa = (Object[]) x;
 437:     Object[] ya = (Object[]) y;
 438:     if (xa.length != ya.length)
 439:       return false;
 440:     for (int i = xa.length;  --i >= 0; )
 441:       {
 442:     if (! equals(xa[i], ya[i]))
 443:       return false;
 444:       }
 445:     return true;
 446:   }
 447: 
 448:   private static int hashCode (Object x)
 449:   {
 450:     if (x == null)
 451:       return 0;
 452:     if (! (x instanceof Object[]))
 453:       return x.hashCode();
 454:     Object[] xa = (Object[]) x;
 455:     int hash = 0;
 456:     for (int i = 0;  i < xa.length;  i++)
 457:       hash = 37 * hashCode(xa[i]);
 458:     return hash;
 459:   }
 460: 
 461:   /**
 462:    * This method tests a specified object for equality against this object.
 463:    * This will be true if and only if the specified object:
 464:    * <p>
 465:    * <ul>
 466:    * <li> Is not <code>null</code>.</li>
 467:    * <li> Is an instance of <code>DateFormatSymbols</code>.</li>
 468:    * <li> Contains identical formatting symbols to this object.</li>
 469:    * </ul>
 470:    * 
 471:    * @param obj The <code>Object</code> to test for equality against.
 472:    *
 473:    * @return <code>true</code> if the specified object is equal to this one,
 474:    * <code>false</code> otherwise.
 475:    */
 476:   public boolean equals (Object obj)
 477:   {
 478:     if (! (obj instanceof DateFormatSymbols))
 479:       return false;
 480:     DateFormatSymbols other = (DateFormatSymbols) obj;
 481:     return (equals(ampms, other.ampms)
 482:         && equals(eras, other.eras)
 483:         && equals(localPatternChars, other.localPatternChars)
 484:         && equals(months, other.months)
 485:         && equals(shortMonths, other.shortMonths)
 486:         && equals(shortWeekdays, other.shortWeekdays)
 487:         && equals(weekdays, other.weekdays)
 488:         && equals(zoneStrings, other.zoneStrings));
 489:   }
 490: 
 491:   /**
 492:    * Returns a new copy of this object.
 493:    *
 494:    * @return A copy of this object
 495:    */
 496:   public Object clone ()
 497:   {
 498:     try
 499:       {
 500:         return super.clone ();
 501:       } 
 502:     catch (CloneNotSupportedException e) 
 503:       {
 504:         return null;
 505:       }
 506:   }
 507: 
 508:   /**
 509:    * This method returns a hash value for this object.
 510:    *
 511:    * @return A hash value for this object.
 512:    */
 513:   public int hashCode ()
 514:   {
 515:     return (hashCode(ampms)
 516:         ^ hashCode(eras)
 517:         ^ hashCode(localPatternChars)
 518:         ^ hashCode(months)
 519:         ^ hashCode(shortMonths)
 520:         ^ hashCode(shortWeekdays)
 521:         ^ hashCode(weekdays)
 522:         ^ hashCode(zoneStrings));
 523:   }
 524: }