home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / text / DateFormatSymbols.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  15.6 KB  |  474 lines

  1. /*
  2.  * @(#)DateFormatSymbols.java    1.24 98/03/18
  3.  *
  4.  * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
  5.  * (C) Copyright IBM Corp. 1996 - All Rights Reserved
  6.  *
  7.  * Portions copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.
  8.  *
  9.  *   The original version of this source code and documentation is copyrighted
  10.  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
  11.  * materials are provided under terms of a License Agreement between Taligent
  12.  * and Sun. This technology is protected by multiple US and International
  13.  * patents. This notice and attribution to Taligent may not be removed.
  14.  *   Taligent is a registered trademark of Taligent, Inc.
  15.  *
  16.  * Permission to use, copy, modify, and distribute this software
  17.  * and its documentation for NON-COMMERCIAL purposes and without
  18.  * fee is hereby granted provided that this copyright notice
  19.  * appears in all copies. Please refer to the file "copyright.html"
  20.  * for further important copyright and licensing information.
  21.  *
  22.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  23.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  24.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  25.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  26.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  27.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  28.  *
  29.  */
  30.  
  31. package java.text;
  32. import java.util.Locale;
  33. import java.util.ResourceBundle;
  34. import java.io.Serializable;
  35. import java.lang.ref.SoftReference;
  36. import java.util.Hashtable;
  37.  
  38. /**
  39.  * <code>DateFormatSymbols</code> is a public class for encapsulating
  40.  * localizable date-time formatting data, such as the names of the
  41.  * months, the names of the days of the week, and the time zone data.
  42.  * <code>DateFormat</code> and <code>SimpleDateFormat</code> both use
  43.  * <code>DateFormatSymbols</code> to encapsulate this information.
  44.  *
  45.  * <p>
  46.  * Typically you shouldn't use <code>DateFormatSymbols</code> directly.
  47.  * Rather, you are encouraged to create a date-time formatter with the
  48.  * <code>DateFormat</code> class's factory methods: <code>getTimeInstance</code>,
  49.  * <code>getDateInstance</code>, or <code>getDateTimeInstance</code>. 
  50.  * These methods automatically create a <code>DateFormatSymbols</code> for
  51.  * the formatter so that you don't have to. After the
  52.  * formatter is created, you may modify its format pattern using the
  53.  * <code>setPattern</code> method. For more information about
  54.  * creating formatters using <code>DateFormat</code>'s factory methods,
  55.  * see <a href="java.text.DateFormat.html"><code>DateFormat</code></a>.
  56.  *
  57.  * <p>
  58.  * If you decide to create a date-time formatter with a specific
  59.  * format pattern for a specific locale, you can do so with:
  60.  * <blockquote>
  61.  * <pre>
  62.  * new SimpleDateFormat(aPattern, new DateFormatSymbols(aLocale)).
  63.  * </pre>
  64.  * </blockquote>
  65.  *
  66.  * <p>
  67.  * <code>DateFormatSymbols</code> objects are clonable. When you obtain
  68.  * a <code>DateFormatSymbols</code> object, feel free to modify the
  69.  * date-time formatting data. For instance, you can replace the localized
  70.  * date-time format pattern characters with the ones that you feel easy
  71.  * to remember. Or you can change the representative cities
  72.  * to your favorite ones.
  73.  *
  74.  * <p>
  75.  * New <code>DateFormatSymbols</code> subclasses may be added to support
  76.  * <code>SimpleDateFormat</code> for date-time formatting for additional locales.
  77.  
  78.  * @see          DateFormat
  79.  * @see          SimpleDateFormat
  80.  * @see          java.util.SimpleTimeZone
  81.  * @version      1.24 03/18/98
  82.  * @author       Chen-Lieh Huang
  83.  */
  84. public class DateFormatSymbols implements Serializable, Cloneable {
  85.  
  86.     /**
  87.      * Construct a DateFormatSymbols object by loading format data from
  88.      * resources for the default locale.
  89.      *
  90.      * @exception  java.util.MissingResourceException
  91.      *             if the resources for the default locale cannot be
  92.      *             found or cannot be loaded.
  93.      */
  94.     public DateFormatSymbols()
  95.     {
  96.         initializeData(Locale.getDefault());
  97.     }
  98.  
  99.     /**
  100.      * Construct a DateFormatSymbols object by loading format data from
  101.      * resources for the given locale.
  102.      *
  103.      * @exception  java.util.MissingResourceException
  104.      *             if the resources for the specified locale cannot be
  105.      *             found or cannot be loaded.
  106.      */
  107.     public DateFormatSymbols(Locale locale)
  108.     {
  109.         initializeData(locale);
  110.     }
  111.  
  112.     /**
  113.      * Era strings. For example: "AD" and "BC".
  114.      */
  115.     String eras[] = null;
  116.     /**
  117.      * Month strings. For example: "January", "February", etc.
  118.      */
  119.     String months[] = null;
  120.     /**
  121.      * Short month strings. For example: "Jan", "Feb", etc.
  122.      */
  123.     String shortMonths[] = null;
  124.     /**
  125.      * Weekday strings. For example: "Sunday", "Monday", etc.
  126.      */
  127.     String weekdays[] = null;
  128.     /**
  129.      * Short weekday strings. For example: "Sun", "Mon", etc.
  130.      */
  131.     String shortWeekdays[] = null;
  132.     /**
  133.      * Ampm strings. For example: "AM" and "PM".
  134.      */
  135.     String ampms[] = null;
  136.     /**
  137.      * The format data of all the timezones in this locale.
  138.      */
  139.     String zoneStrings[][] = null;
  140.     /**
  141.      * Unlocalized date-time pattern characters. For example: 'y', 'd', etc.
  142.      * All locales use the same these unlocalized pattern characters.
  143.      */
  144.     static final String  patternChars = "GyMdkHmsSEDFwWahKz";
  145.     /**
  146.      * Localized date-time pattern characters. For example: use 'u' as 'y'.
  147.      */
  148.     String  localPatternChars = null;
  149.    
  150.     /* use serialVersionUID from JDK 1.1.4 for interoperability */
  151.     static final long serialVersionUID = -5987973545549424702L;
  152.  
  153.     /**
  154.      * Gets era strings. For example: "AD" and "BC".
  155.      * @return the era strings.
  156.      */
  157.     public String[] getEras() {
  158.         return duplicate(eras);
  159.     }
  160.  
  161.     /**
  162.      * Sets era strings. For example: "AD" and "BC".
  163.      * @param newEras the new era strings.
  164.      */
  165.     public void setEras(String[] newEras) {
  166.         eras = duplicate(newEras);
  167.     }
  168.  
  169.     /**
  170.      * Gets month strings. For example: "January", "February", etc.
  171.      * @return the month strings.
  172.      */
  173.     public String[] getMonths() {
  174.         return duplicate(months);
  175.     }
  176.  
  177.     /**
  178.      * Sets month strings. For example: "January", "February", etc.
  179.      * @param newMonths the new month strings.
  180.      */
  181.     public void setMonths(String[] newMonths) {
  182.         months = duplicate(newMonths);
  183.     }
  184.  
  185.     /**
  186.      * Gets short month strings. For example: "Jan", "Feb", etc.
  187.      * @return the short month strings.
  188.      */
  189.     public String[] getShortMonths() {
  190.         return duplicate(shortMonths);
  191.     }
  192.  
  193.     /**
  194.      * Sets short month strings. For example: "Jan", "Feb", etc.
  195.      * @param newShortMonths the new short month strings.
  196.      */
  197.     public void setShortMonths(String[] newShortMonths) {
  198.         shortMonths = duplicate(newShortMonths);
  199.     }
  200.  
  201.     /**
  202.      * Gets weekday strings. For example: "Sunday", "Monday", etc.
  203.      * @return the weekday strings.
  204.      */
  205.     public String[] getWeekdays() {
  206.         return duplicate(weekdays);
  207.     }
  208.  
  209.     /**
  210.      * Sets weekday strings. For example: "Sunday", "Monday", etc.
  211.      * @param newWeekdays the new weekday strings.
  212.      */
  213.     public void setWeekdays(String[] newWeekdays) {
  214.         weekdays = duplicate(newWeekdays);
  215.     }
  216.  
  217.     /**
  218.      * Gets short weekday strings. For example: "Sun", "Mon", etc.
  219.      * @return the short weekday strings.
  220.      */
  221.     public String[] getShortWeekdays() {
  222.         return duplicate(shortWeekdays);
  223.     }
  224.  
  225.     /**
  226.      * Sets short weekday strings. For example: "Sun", "Mon", etc.
  227.      * @param newShortWeekdays the new short weekday strings.
  228.      */
  229.     public void setShortWeekdays(String[] newShortWeekdays) {
  230.         shortWeekdays = duplicate(newShortWeekdays);
  231.     }
  232.  
  233.     /**
  234.      * Gets ampm strings. For example: "AM" and "PM".
  235.      * @return the weekday strings.
  236.      */
  237.     public String[] getAmPmStrings() {
  238.         return duplicate(ampms);
  239.     }
  240.  
  241.     /**
  242.      * Sets ampm strings. For example: "AM" and "PM".
  243.      * @param newAmpms the new ampm strings.
  244.      */
  245.     public void setAmPmStrings(String[] newAmpms) {
  246.         ampms = duplicate(newAmpms);
  247.     }
  248.  
  249.     /**
  250.      * Gets timezone strings.
  251.      * @return the timezone strings.
  252.      */
  253.     public String[][] getZoneStrings() {
  254.         String[][] aCopy = new String[zoneStrings.length][];
  255.         for (int i = 0; i < zoneStrings.length; ++i)
  256.             aCopy[i] = duplicate(zoneStrings[i]);
  257.         return aCopy;
  258.     }
  259.  
  260.     /**
  261.      * Sets timezone strings.
  262.      * @param newZoneStrings the new timezone strings.
  263.      */
  264.     public void setZoneStrings(String[][] newZoneStrings) {
  265.         String[][] aCopy = new String[newZoneStrings.length][];
  266.         for (int i = 0; i < newZoneStrings.length; ++i)
  267.             aCopy[i] = duplicate(newZoneStrings[i]);
  268.         zoneStrings = aCopy;
  269.     }
  270.  
  271.     /**
  272.      * Gets localized date-time pattern characters. For example: 'u', 't', etc.
  273.      * @return the localized date-time pattern characters.
  274.      */
  275.     public String getLocalPatternChars() {
  276.         return new String(localPatternChars);
  277.     }
  278.  
  279.     /**
  280.      * Sets localized date-time pattern characters. For example: 'u', 't', etc.
  281.      * @param newLocalPatternChars the new localized date-time
  282.      * pattern characters.
  283.      */
  284.     public void setLocalPatternChars(String newLocalPatternChars) {
  285.         localPatternChars = new String(newLocalPatternChars);
  286.     }
  287.  
  288.     /**
  289.      * Overrides Cloneable
  290.      */
  291.     public Object clone()
  292.     {
  293.         try
  294.         {
  295.             DateFormatSymbols other = (DateFormatSymbols)super.clone();
  296.             copyMembers(this, other);
  297.             return other;
  298.         } catch (CloneNotSupportedException e) {
  299.             throw new InternalError();
  300.         }
  301.     }
  302.  
  303.     /**
  304.      * Override hashCode.
  305.      * Generates a hash code for the DateFormatSymbols object.
  306.      */
  307.     public int hashCode() {
  308.         int hashcode = 0;
  309.         for (int index = 0; index < this.zoneStrings[0].length; ++index)
  310.             hashcode ^= this.zoneStrings[0][index].hashCode();
  311.         return hashcode;
  312.     }
  313.  
  314.     /**
  315.      * Override equals
  316.      */
  317.     public boolean equals(Object obj)
  318.     {
  319.         if (this == obj) return true;
  320.         if (obj == null || getClass() != obj.getClass()) return false;
  321.         DateFormatSymbols that = (DateFormatSymbols) obj;
  322.         return (Utility.arrayEquals(eras, that.eras)
  323.                 && Utility.arrayEquals(months, that.months)
  324.                 && Utility.arrayEquals(shortMonths, that.shortMonths)
  325.                 && Utility.arrayEquals(weekdays, that.weekdays)
  326.                 && Utility.arrayEquals(shortWeekdays, that.shortWeekdays)
  327.                 && Utility.arrayEquals(ampms, that.ampms)
  328.                 && Utility.arrayEquals(zoneStrings, that.zoneStrings)
  329.                 && Utility.arrayEquals(localPatternChars,
  330.                                        that.localPatternChars));
  331.     }
  332.  
  333.     // =======================privates===============================
  334.  
  335.     /**
  336.      * Useful constant for defining timezone offsets.
  337.      */
  338.     static final int millisPerHour = 60*60*1000;
  339.     
  340.     /**
  341.      * Cache to hold the LocaleElements and DateFormatZoneData ResourceBundles
  342.      * of a Locale.
  343.      */
  344.     private static Hashtable cachedLocaleData = new Hashtable(3);
  345.  
  346.     /* Utility methods for fetching resource bundles */
  347.     private ResourceBundle getLocaleElements(Locale desiredLocale) {
  348.     return ResourceBundle.getBundle("java.text.resources.LocaleElements",
  349.                     desiredLocale);
  350.     }
  351.  
  352.     private ResourceBundle getZoneData(Locale desiredLocale) {
  353.     return ResourceBundle.getBundle("java.text.resources.DateFormatZoneData",
  354.                     desiredLocale);
  355.     }
  356.  
  357.     /**
  358.      * Look up resource data for the desiredLocale in the cache; update the
  359.      * cache if necessary.
  360.      */
  361.     private SoftReference[] cacheLookup(Locale desiredLocale) {
  362.     SoftReference[] data
  363.         = (SoftReference[])cachedLocaleData.get(desiredLocale);
  364.     if (data == null) {
  365.         data = new SoftReference[] {
  366.                new SoftReference(getLocaleElements(desiredLocale)),
  367.                new SoftReference(getZoneData(desiredLocale)) };
  368.         cachedLocaleData.put(desiredLocale, data);
  369.     } else {
  370.         if (data[0].get() == null) {
  371.         data[0] = new SoftReference(getLocaleElements(desiredLocale));
  372.         }
  373.         if (data[1].get() == null) {
  374.         data[1] = new SoftReference(getZoneData(desiredLocale));
  375.         }
  376.     }
  377.     return data;
  378.     }
  379.  
  380.     private void initializeData(Locale desiredLocale)
  381.     {
  382.     int i;
  383.     SoftReference[] rbs = cacheLookup(desiredLocale);
  384.     ResourceBundle resource = (ResourceBundle)rbs[0].get();
  385.     ResourceBundle zoneResource = (ResourceBundle)rbs[1].get();
  386.  
  387.     eras = (String[])resource.getObject("Eras");
  388.         months = resource.getStringArray("MonthNames");
  389.         shortMonths = resource.getStringArray("MonthAbbreviations");
  390.         String[] lWeekdays = resource.getStringArray("DayNames");
  391.         weekdays = new String[8];
  392.         weekdays[0] = "";  // 1-based
  393.         for (i=0; i<lWeekdays.length; i++)
  394.             weekdays[i+1] = lWeekdays[i];
  395.         String[] sWeekdays = resource.getStringArray("DayAbbreviations");
  396.         shortWeekdays = new String[8];
  397.         shortWeekdays[0] = "";  // 1-based
  398.         for (i=0; i<sWeekdays.length; i++)
  399.             shortWeekdays[i+1] = sWeekdays[i];
  400.         ampms = resource.getStringArray("AmPmMarkers");
  401.         zoneStrings = (String[][])zoneResource.getObject("zoneStrings");
  402.         localPatternChars
  403.             = (String) zoneResource.getObject("localPatternChars");
  404.     }
  405.  
  406.     /**
  407.      * Package private: used by SimpleDateFormat
  408.      * Gets the index for the given time zone ID to obtain the timezone
  409.      * strings for formatting. The time zone ID is just for programmatic
  410.      * lookup. NOT LOCALIZED!!!
  411.      * @param ID the given time zone ID.
  412.      * @return the index of the given time zone ID.  Returns -1 if
  413.      * the given time zone ID can't be located in the DateFormatSymbols object.
  414.      * @see java.util.SimpleTimeZone
  415.      */
  416.     final int getZoneIndex (String ID)
  417.     {
  418.         for (int index=0; index<zoneStrings.length; index++)
  419.         {
  420.             if (ID.equalsIgnoreCase(zoneStrings[index][0])) return index;
  421.         }
  422.  
  423.         return -1;
  424.     }
  425.  
  426.     /**
  427.      * Clones an array of Strings.
  428.      * @param srcArray the source array to be cloned.
  429.      * @param count the number of elements in the given source array.
  430.      * @return a cloned array.
  431.      */
  432.     private final String[] duplicate(String[] srcArray)
  433.     {
  434.         String[] dstArray = new String[srcArray.length];
  435.         System.arraycopy(srcArray, 0, dstArray, 0, srcArray.length);
  436.         return dstArray;
  437.     }
  438.  
  439.     /**
  440.      * Clones all the data members from the source DateFormatSymbols to
  441.      * the target DateFormatSymbols. This is only for subclasses.
  442.      * @param src the source DateFormatSymbols.
  443.      * @param dst the target DateFormatSymbols.
  444.      */
  445.     private final void copyMembers(DateFormatSymbols src, DateFormatSymbols dst)
  446.     {
  447.         dst.eras = duplicate(src.eras);
  448.         dst.months = duplicate(src.months);
  449.         dst.shortMonths = duplicate(src.shortMonths);
  450.         dst.weekdays = duplicate(src.weekdays);
  451.         dst.shortWeekdays = duplicate(src.shortWeekdays);
  452.         dst.ampms = duplicate(src.ampms);
  453.         for (int i = 0; i < dst.zoneStrings.length; ++i)
  454.             dst.zoneStrings[i] = duplicate(src.zoneStrings[i]);
  455.         dst.localPatternChars = new String (src.localPatternChars);
  456.     }
  457.  
  458.     /**
  459.      * Compares the equality of the two arrays of String.
  460.      * @param current this String array.
  461.      * @param other that String array.
  462.      */
  463.     private final boolean equals(String[] current, String[] other)
  464.     {
  465.         int count = current.length;
  466.  
  467.         for (int i = 0; i < count; ++i)
  468.             if (!current[i].equals(other[i]))
  469.                 return false;
  470.         return true;
  471.     }
  472.  
  473. }
  474.