Save This Page
Home » openjdk-7 » java » text » [javadoc | source]
    1   /*
    2    * Copyright 1996-2005 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   /*
   27    * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
   28    * (C) Copyright IBM Corp. 1996 - All Rights Reserved
   29    *
   30    *   The original version of this source code and documentation is copyrighted
   31    * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
   32    * materials are provided under terms of a License Agreement between Taligent
   33    * and Sun. This technology is protected by multiple US and International
   34    * patents. This notice and attribution to Taligent may not be removed.
   35    *   Taligent is a registered trademark of Taligent, Inc.
   36    *
   37    */
   38   
   39   package java.text;
   40   
   41   import java.io.InvalidObjectException;
   42   import java.text.spi.DateFormatProvider;
   43   import java.util.Calendar;
   44   import java.util.Date;
   45   import java.util.GregorianCalendar;
   46   import java.util.HashMap;
   47   import java.util.Locale;
   48   import java.util.Map;
   49   import java.util.MissingResourceException;
   50   import java.util.ResourceBundle;
   51   import java.util.TimeZone;
   52   import java.util.spi.LocaleServiceProvider;
   53   import sun.util.LocaleServiceProviderPool;
   54   
   55   /**
   56    * DateFormat is an abstract class for date/time formatting subclasses which
   57    * formats and parses dates or time in a language-independent manner.
   58    * The date/time formatting subclass, such as SimpleDateFormat, allows for
   59    * formatting (i.e., date -> text), parsing (text -> date), and
   60    * normalization.  The date is represented as a <code>Date</code> object or
   61    * as the milliseconds since January 1, 1970, 00:00:00 GMT.
   62    *
   63    * <p>DateFormat provides many class methods for obtaining default date/time
   64    * formatters based on the default or a given locale and a number of formatting
   65    * styles. The formatting styles include FULL, LONG, MEDIUM, and SHORT. More
   66    * detail and examples of using these styles are provided in the method
   67    * descriptions.
   68    *
   69    * <p>DateFormat helps you to format and parse dates for any locale.
   70    * Your code can be completely independent of the locale conventions for
   71    * months, days of the week, or even the calendar format: lunar vs. solar.
   72    *
   73    * <p>To format a date for the current Locale, use one of the
   74    * static factory methods:
   75    * <pre>
   76    *  myString = DateFormat.getDateInstance().format(myDate);
   77    * </pre>
   78    * <p>If you are formatting multiple dates, it is
   79    * more efficient to get the format and use it multiple times so that
   80    * the system doesn't have to fetch the information about the local
   81    * language and country conventions multiple times.
   82    * <pre>
   83    *  DateFormat df = DateFormat.getDateInstance();
   84    *  for (int i = 0; i < myDate.length; ++i) {
   85    *    output.println(df.format(myDate[i]) + "; ");
   86    *  }
   87    * </pre>
   88    * <p>To format a date for a different Locale, specify it in the
   89    * call to getDateInstance().
   90    * <pre>
   91    *  DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
   92    * </pre>
   93    * <p>You can use a DateFormat to parse also.
   94    * <pre>
   95    *  myDate = df.parse(myString);
   96    * </pre>
   97    * <p>Use getDateInstance to get the normal date format for that country.
   98    * There are other static factory methods available.
   99    * Use getTimeInstance to get the time format for that country.
  100    * Use getDateTimeInstance to get a date and time format. You can pass in
  101    * different options to these factory methods to control the length of the
  102    * result; from SHORT to MEDIUM to LONG to FULL. The exact result depends
  103    * on the locale, but generally:
  104    * <ul><li>SHORT is completely numeric, such as 12.13.52 or 3:30pm
  105    * <li>MEDIUM is longer, such as Jan 12, 1952
  106    * <li>LONG is longer, such as January 12, 1952 or 3:30:32pm
  107    * <li>FULL is pretty completely specified, such as
  108    * Tuesday, April 12, 1952 AD or 3:30:42pm PST.
  109    * </ul>
  110    *
  111    * <p>You can also set the time zone on the format if you wish.
  112    * If you want even more control over the format or parsing,
  113    * (or want to give your users more control),
  114    * you can try casting the DateFormat you get from the factory methods
  115    * to a SimpleDateFormat. This will work for the majority
  116    * of countries; just remember to put it in a try block in case you
  117    * encounter an unusual one.
  118    *
  119    * <p>You can also use forms of the parse and format methods with
  120    * ParsePosition and FieldPosition to
  121    * allow you to
  122    * <ul><li>progressively parse through pieces of a string.
  123    * <li>align any particular field, or find out where it is for selection
  124    * on the screen.
  125    * </ul>
  126    *
  127    * <h4><a name="synchronization">Synchronization</a></h4>
  128    *
  129    * <p>
  130    * Date formats are not synchronized.
  131    * It is recommended to create separate format instances for each thread.
  132    * If multiple threads access a format concurrently, it must be synchronized
  133    * externally.
  134    *
  135    * @see          Format
  136    * @see          NumberFormat
  137    * @see          SimpleDateFormat
  138    * @see          java.util.Calendar
  139    * @see          java.util.GregorianCalendar
  140    * @see          java.util.TimeZone
  141    * @author       Mark Davis, Chen-Lieh Huang, Alan Liu
  142    */
  143   public abstract class DateFormat extends Format {
  144   
  145       /**
  146        * The calendar that <code>DateFormat</code> uses to produce the time field
  147        * values needed to implement date and time formatting.  Subclasses should
  148        * initialize this to a calendar appropriate for the locale associated with
  149        * this <code>DateFormat</code>.
  150        * @serial
  151        */
  152       protected Calendar calendar;
  153   
  154       /**
  155        * The number formatter that <code>DateFormat</code> uses to format numbers
  156        * in dates and times.  Subclasses should initialize this to a number format
  157        * appropriate for the locale associated with this <code>DateFormat</code>.
  158        * @serial
  159        */
  160       protected NumberFormat numberFormat;
  161   
  162       /**
  163        * Useful constant for ERA field alignment.
  164        * Used in FieldPosition of date/time formatting.
  165        */
  166       public final static int ERA_FIELD = 0;
  167       /**
  168        * Useful constant for YEAR field alignment.
  169        * Used in FieldPosition of date/time formatting.
  170        */
  171       public final static int YEAR_FIELD = 1;
  172       /**
  173        * Useful constant for MONTH field alignment.
  174        * Used in FieldPosition of date/time formatting.
  175        */
  176       public final static int MONTH_FIELD = 2;
  177       /**
  178        * Useful constant for DATE field alignment.
  179        * Used in FieldPosition of date/time formatting.
  180        */
  181       public final static int DATE_FIELD = 3;
  182       /**
  183        * Useful constant for one-based HOUR_OF_DAY field alignment.
  184        * Used in FieldPosition of date/time formatting.
  185        * HOUR_OF_DAY1_FIELD is used for the one-based 24-hour clock.
  186        * For example, 23:59 + 01:00 results in 24:59.
  187        */
  188       public final static int HOUR_OF_DAY1_FIELD = 4;
  189       /**
  190        * Useful constant for zero-based HOUR_OF_DAY field alignment.
  191        * Used in FieldPosition of date/time formatting.
  192        * HOUR_OF_DAY0_FIELD is used for the zero-based 24-hour clock.
  193        * For example, 23:59 + 01:00 results in 00:59.
  194        */
  195       public final static int HOUR_OF_DAY0_FIELD = 5;
  196       /**
  197        * Useful constant for MINUTE field alignment.
  198        * Used in FieldPosition of date/time formatting.
  199        */
  200       public final static int MINUTE_FIELD = 6;
  201       /**
  202        * Useful constant for SECOND field alignment.
  203        * Used in FieldPosition of date/time formatting.
  204        */
  205       public final static int SECOND_FIELD = 7;
  206       /**
  207        * Useful constant for MILLISECOND field alignment.
  208        * Used in FieldPosition of date/time formatting.
  209        */
  210       public final static int MILLISECOND_FIELD = 8;
  211       /**
  212        * Useful constant for DAY_OF_WEEK field alignment.
  213        * Used in FieldPosition of date/time formatting.
  214        */
  215       public final static int DAY_OF_WEEK_FIELD = 9;
  216       /**
  217        * Useful constant for DAY_OF_YEAR field alignment.
  218        * Used in FieldPosition of date/time formatting.
  219        */
  220       public final static int DAY_OF_YEAR_FIELD = 10;
  221       /**
  222        * Useful constant for DAY_OF_WEEK_IN_MONTH field alignment.
  223        * Used in FieldPosition of date/time formatting.
  224        */
  225       public final static int DAY_OF_WEEK_IN_MONTH_FIELD = 11;
  226       /**
  227        * Useful constant for WEEK_OF_YEAR field alignment.
  228        * Used in FieldPosition of date/time formatting.
  229        */
  230       public final static int WEEK_OF_YEAR_FIELD = 12;
  231       /**
  232        * Useful constant for WEEK_OF_MONTH field alignment.
  233        * Used in FieldPosition of date/time formatting.
  234        */
  235       public final static int WEEK_OF_MONTH_FIELD = 13;
  236       /**
  237        * Useful constant for AM_PM field alignment.
  238        * Used in FieldPosition of date/time formatting.
  239        */
  240       public final static int AM_PM_FIELD = 14;
  241       /**
  242        * Useful constant for one-based HOUR field alignment.
  243        * Used in FieldPosition of date/time formatting.
  244        * HOUR1_FIELD is used for the one-based 12-hour clock.
  245        * For example, 11:30 PM + 1 hour results in 12:30 AM.
  246        */
  247       public final static int HOUR1_FIELD = 15;
  248       /**
  249        * Useful constant for zero-based HOUR field alignment.
  250        * Used in FieldPosition of date/time formatting.
  251        * HOUR0_FIELD is used for the zero-based 12-hour clock.
  252        * For example, 11:30 PM + 1 hour results in 00:30 AM.
  253        */
  254       public final static int HOUR0_FIELD = 16;
  255       /**
  256        * Useful constant for TIMEZONE field alignment.
  257        * Used in FieldPosition of date/time formatting.
  258        */
  259       public final static int TIMEZONE_FIELD = 17;
  260   
  261       // Proclaim serial compatibility with 1.1 FCS
  262       private static final long serialVersionUID = 7218322306649953788L;
  263   
  264       /**
  265        * Overrides Format.
  266        * Formats a time object into a time string. Examples of time objects
  267        * are a time value expressed in milliseconds and a Date object.
  268        * @param obj must be a Number or a Date.
  269        * @param toAppendTo the string buffer for the returning time string.
  270        * @return the string buffer passed in as toAppendTo, with formatted text appended.
  271        * @param fieldPosition keeps track of the position of the field
  272        * within the returned string.
  273        * On input: an alignment field,
  274        * if desired. On output: the offsets of the alignment field. For
  275        * example, given a time text "1996.07.10 AD at 15:08:56 PDT",
  276        * if the given fieldPosition is DateFormat.YEAR_FIELD, the
  277        * begin index and end index of fieldPosition will be set to
  278        * 0 and 4, respectively.
  279        * Notice that if the same time field appears
  280        * more than once in a pattern, the fieldPosition will be set for the first
  281        * occurrence of that time field. For instance, formatting a Date to
  282        * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern
  283        * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD,
  284        * the begin index and end index of fieldPosition will be set to
  285        * 5 and 8, respectively, for the first occurrence of the timezone
  286        * pattern character 'z'.
  287        * @see java.text.Format
  288        */
  289       public final StringBuffer format(Object obj, StringBuffer toAppendTo,
  290                                        FieldPosition fieldPosition)
  291       {
  292           if (obj instanceof Date)
  293               return format( (Date)obj, toAppendTo, fieldPosition );
  294           else if (obj instanceof Number)
  295               return format( new Date(((Number)obj).longValue()),
  296                             toAppendTo, fieldPosition );
  297           else
  298               throw new IllegalArgumentException("Cannot format given Object as a Date");
  299       }
  300   
  301       /**
  302        * Formats a Date into a date/time string.
  303        * @param date a Date to be formatted into a date/time string.
  304        * @param toAppendTo the string buffer for the returning date/time string.
  305        * @param fieldPosition keeps track of the position of the field
  306        * within the returned string.
  307        * On input: an alignment field,
  308        * if desired. On output: the offsets of the alignment field. For
  309        * example, given a time text "1996.07.10 AD at 15:08:56 PDT",
  310        * if the given fieldPosition is DateFormat.YEAR_FIELD, the
  311        * begin index and end index of fieldPosition will be set to
  312        * 0 and 4, respectively.
  313        * Notice that if the same time field appears
  314        * more than once in a pattern, the fieldPosition will be set for the first
  315        * occurrence of that time field. For instance, formatting a Date to
  316        * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern
  317        * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD,
  318        * the begin index and end index of fieldPosition will be set to
  319        * 5 and 8, respectively, for the first occurrence of the timezone
  320        * pattern character 'z'.
  321        * @return the string buffer passed in as toAppendTo, with formatted text appended.
  322        */
  323       public abstract StringBuffer format(Date date, StringBuffer toAppendTo,
  324                                           FieldPosition fieldPosition);
  325   
  326       /**
  327        * Formats a Date into a date/time string.
  328        * @param date the time value to be formatted into a time string.
  329        * @return the formatted time string.
  330        */
  331       public final String format(Date date)
  332       {
  333           return format(date, new StringBuffer(),
  334                         DontCareFieldPosition.INSTANCE).toString();
  335       }
  336   
  337       /**
  338        * Parses text from the beginning of the given string to produce a date.
  339        * The method may not use the entire text of the given string.
  340        * <p>
  341        * See the {@link #parse(String, ParsePosition)} method for more information
  342        * on date parsing.
  343        *
  344        * @param source A <code>String</code> whose beginning should be parsed.
  345        * @return A <code>Date</code> parsed from the string.
  346        * @exception ParseException if the beginning of the specified string
  347        *            cannot be parsed.
  348        */
  349       public Date parse(String source) throws ParseException
  350       {
  351           ParsePosition pos = new ParsePosition(0);
  352           Date result = parse(source, pos);
  353           if (pos.index == 0)
  354               throw new ParseException("Unparseable date: \"" + source + "\"" ,
  355                   pos.errorIndex);
  356           return result;
  357       }
  358   
  359       /**
  360        * Parse a date/time string according to the given parse position.  For
  361        * example, a time text "07/10/96 4:5 PM, PDT" will be parsed into a Date
  362        * that is equivalent to Date(837039928046).
  363        *
  364        * <p> By default, parsing is lenient: If the input is not in the form used
  365        * by this object's format method but can still be parsed as a date, then
  366        * the parse succeeds.  Clients may insist on strict adherence to the
  367        * format by calling setLenient(false).
  368        *
  369        * @see java.text.DateFormat#setLenient(boolean)
  370        *
  371        * @param source  The date/time string to be parsed
  372        *
  373        * @param pos   On input, the position at which to start parsing; on
  374        *              output, the position at which parsing terminated, or the
  375        *              start position if the parse failed.
  376        *
  377        * @return      A Date, or null if the input could not be parsed
  378        */
  379       public abstract Date parse(String source, ParsePosition pos);
  380   
  381       /**
  382        * Parses text from a string to produce a <code>Date</code>.
  383        * <p>
  384        * The method attempts to parse text starting at the index given by
  385        * <code>pos</code>.
  386        * If parsing succeeds, then the index of <code>pos</code> is updated
  387        * to the index after the last character used (parsing does not necessarily
  388        * use all characters up to the end of the string), and the parsed
  389        * date is returned. The updated <code>pos</code> can be used to
  390        * indicate the starting point for the next call to this method.
  391        * If an error occurs, then the index of <code>pos</code> is not
  392        * changed, the error index of <code>pos</code> is set to the index of
  393        * the character where the error occurred, and null is returned.
  394        * <p>
  395        * See the {@link #parse(String, ParsePosition)} method for more information
  396        * on date parsing.
  397        *
  398        * @param source A <code>String</code>, part of which should be parsed.
  399        * @param pos A <code>ParsePosition</code> object with index and error
  400        *            index information as described above.
  401        * @return A <code>Date</code> parsed from the string. In case of
  402        *         error, returns null.
  403        * @exception NullPointerException if <code>pos</code> is null.
  404        */
  405       public Object parseObject(String source, ParsePosition pos) {
  406           return parse(source, pos);
  407       }
  408   
  409       /**
  410        * Constant for full style pattern.
  411        */
  412       public static final int FULL = 0;
  413       /**
  414        * Constant for long style pattern.
  415        */
  416       public static final int LONG = 1;
  417       /**
  418        * Constant for medium style pattern.
  419        */
  420       public static final int MEDIUM = 2;
  421       /**
  422        * Constant for short style pattern.
  423        */
  424       public static final int SHORT = 3;
  425       /**
  426        * Constant for default style pattern.  Its value is MEDIUM.
  427        */
  428       public static final int DEFAULT = MEDIUM;
  429   
  430       /**
  431        * Gets the time formatter with the default formatting style
  432        * for the default locale.
  433        * @return a time formatter.
  434        */
  435       public final static DateFormat getTimeInstance()
  436       {
  437           return get(DEFAULT, 0, 1, Locale.getDefault());
  438       }
  439   
  440       /**
  441        * Gets the time formatter with the given formatting style
  442        * for the default locale.
  443        * @param style the given formatting style. For example,
  444        * SHORT for "h:mm a" in the US locale.
  445        * @return a time formatter.
  446        */
  447       public final static DateFormat getTimeInstance(int style)
  448       {
  449           return get(style, 0, 1, Locale.getDefault());
  450       }
  451   
  452       /**
  453        * Gets the time formatter with the given formatting style
  454        * for the given locale.
  455        * @param style the given formatting style. For example,
  456        * SHORT for "h:mm a" in the US locale.
  457        * @param aLocale the given locale.
  458        * @return a time formatter.
  459        */
  460       public final static DateFormat getTimeInstance(int style,
  461                                                    Locale aLocale)
  462       {
  463           return get(style, 0, 1, aLocale);
  464       }
  465   
  466       /**
  467        * Gets the date formatter with the default formatting style
  468        * for the default locale.
  469        * @return a date formatter.
  470        */
  471       public final static DateFormat getDateInstance()
  472       {
  473           return get(0, DEFAULT, 2, Locale.getDefault());
  474       }
  475   
  476       /**
  477        * Gets the date formatter with the given formatting style
  478        * for the default locale.
  479        * @param style the given formatting style. For example,
  480        * SHORT for "M/d/yy" in the US locale.
  481        * @return a date formatter.
  482        */
  483       public final static DateFormat getDateInstance(int style)
  484       {
  485           return get(0, style, 2, Locale.getDefault());
  486       }
  487   
  488       /**
  489        * Gets the date formatter with the given formatting style
  490        * for the given locale.
  491        * @param style the given formatting style. For example,
  492        * SHORT for "M/d/yy" in the US locale.
  493        * @param aLocale the given locale.
  494        * @return a date formatter.
  495        */
  496       public final static DateFormat getDateInstance(int style,
  497                                                    Locale aLocale)
  498       {
  499           return get(0, style, 2, aLocale);
  500       }
  501   
  502       /**
  503        * Gets the date/time formatter with the default formatting style
  504        * for the default locale.
  505        * @return a date/time formatter.
  506        */
  507       public final static DateFormat getDateTimeInstance()
  508       {
  509           return get(DEFAULT, DEFAULT, 3, Locale.getDefault());
  510       }
  511   
  512       /**
  513        * Gets the date/time formatter with the given date and time
  514        * formatting styles for the default locale.
  515        * @param dateStyle the given date formatting style. For example,
  516        * SHORT for "M/d/yy" in the US locale.
  517        * @param timeStyle the given time formatting style. For example,
  518        * SHORT for "h:mm a" in the US locale.
  519        * @return a date/time formatter.
  520        */
  521       public final static DateFormat getDateTimeInstance(int dateStyle,
  522                                                          int timeStyle)
  523       {
  524           return get(timeStyle, dateStyle, 3, Locale.getDefault());
  525       }
  526   
  527       /**
  528        * Gets the date/time formatter with the given formatting styles
  529        * for the given locale.
  530        * @param dateStyle the given date formatting style.
  531        * @param timeStyle the given time formatting style.
  532        * @param aLocale the given locale.
  533        * @return a date/time formatter.
  534        */
  535       public final static DateFormat
  536           getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale)
  537       {
  538           return get(timeStyle, dateStyle, 3, aLocale);
  539       }
  540   
  541       /**
  542        * Get a default date/time formatter that uses the SHORT style for both the
  543        * date and the time.
  544        */
  545       public final static DateFormat getInstance() {
  546           return getDateTimeInstance(SHORT, SHORT);
  547       }
  548   
  549       /**
  550        * Returns an array of all locales for which the
  551        * <code>get*Instance</code> methods of this class can return
  552        * localized instances.
  553        * The returned array represents the union of locales supported by the Java
  554        * runtime and by installed
  555        * {@link java.text.spi.DateFormatProvider DateFormatProvider} implementations.
  556        * It must contain at least a <code>Locale</code> instance equal to
  557        * {@link java.util.Locale#US Locale.US}.
  558        *
  559        * @return An array of locales for which localized
  560        *         <code>DateFormat</code> instances are available.
  561        */
  562       public static Locale[] getAvailableLocales()
  563       {
  564           LocaleServiceProviderPool pool =
  565               LocaleServiceProviderPool.getPool(DateFormatProvider.class);
  566           return pool.getAvailableLocales();
  567       }
  568   
  569       /**
  570        * Set the calendar to be used by this date format.  Initially, the default
  571        * calendar for the specified or default locale is used.
  572        * @param newCalendar the new Calendar to be used by the date format
  573        */
  574       public void setCalendar(Calendar newCalendar)
  575       {
  576           this.calendar = newCalendar;
  577       }
  578   
  579       /**
  580        * Gets the calendar associated with this date/time formatter.
  581        * @return the calendar associated with this date/time formatter.
  582        */
  583       public Calendar getCalendar()
  584       {
  585           return calendar;
  586       }
  587   
  588       /**
  589        * Allows you to set the number formatter.
  590        * @param newNumberFormat the given new NumberFormat.
  591        */
  592       public void setNumberFormat(NumberFormat newNumberFormat)
  593       {
  594           this.numberFormat = newNumberFormat;
  595       }
  596   
  597       /**
  598        * Gets the number formatter which this date/time formatter uses to
  599        * format and parse a time.
  600        * @return the number formatter which this date/time formatter uses.
  601        */
  602       public NumberFormat getNumberFormat()
  603       {
  604           return numberFormat;
  605       }
  606   
  607       /**
  608        * Sets the time zone for the calendar of this DateFormat object.
  609        * @param zone the given new time zone.
  610        */
  611       public void setTimeZone(TimeZone zone)
  612       {
  613           calendar.setTimeZone(zone);
  614       }
  615   
  616       /**
  617        * Gets the time zone.
  618        * @return the time zone associated with the calendar of DateFormat.
  619        */
  620       public TimeZone getTimeZone()
  621       {
  622           return calendar.getTimeZone();
  623       }
  624   
  625       /**
  626        * Specify whether or not date/time parsing is to be lenient.  With
  627        * lenient parsing, the parser may use heuristics to interpret inputs that
  628        * do not precisely match this object's format.  With strict parsing,
  629        * inputs must match this object's format.
  630        * @param lenient when true, parsing is lenient
  631        * @see java.util.Calendar#setLenient
  632        */
  633       public void setLenient(boolean lenient)
  634       {
  635           calendar.setLenient(lenient);
  636       }
  637   
  638       /**
  639        * Tell whether date/time parsing is to be lenient.
  640        */
  641       public boolean isLenient()
  642       {
  643           return calendar.isLenient();
  644       }
  645   
  646       /**
  647        * Overrides hashCode
  648        */
  649       public int hashCode() {
  650           return numberFormat.hashCode();
  651           // just enough fields for a reasonable distribution
  652       }
  653   
  654       /**
  655        * Overrides equals
  656        */
  657       public boolean equals(Object obj) {
  658           if (this == obj) return true;
  659           if (obj == null || getClass() != obj.getClass()) return false;
  660           DateFormat other = (DateFormat) obj;
  661           return (// calendar.equivalentTo(other.calendar) // THIS API DOESN'T EXIST YET!
  662                   calendar.getFirstDayOfWeek() == other.calendar.getFirstDayOfWeek() &&
  663                   calendar.getMinimalDaysInFirstWeek() == other.calendar.getMinimalDaysInFirstWeek() &&
  664                   calendar.isLenient() == other.calendar.isLenient() &&
  665                   calendar.getTimeZone().equals(other.calendar.getTimeZone()) &&
  666                   numberFormat.equals(other.numberFormat));
  667       }
  668   
  669       /**
  670        * Overrides Cloneable
  671        */
  672       public Object clone()
  673       {
  674           DateFormat other = (DateFormat) super.clone();
  675           other.calendar = (Calendar) calendar.clone();
  676           other.numberFormat = (NumberFormat) numberFormat.clone();
  677           return other;
  678       }
  679   
  680       /**
  681        * Creates a DateFormat with the given time and/or date style in the given
  682        * locale.
  683        * @param timeStyle a value from 0 to 3 indicating the time format,
  684        * ignored if flags is 2
  685        * @param dateStyle a value from 0 to 3 indicating the time format,
  686        * ignored if flags is 1
  687        * @param flags either 1 for a time format, 2 for a date format,
  688        * or 3 for a date/time format
  689        * @param loc the locale for the format
  690        */
  691       private static DateFormat get(int timeStyle, int dateStyle,
  692                                     int flags, Locale loc) {
  693           if ((flags & 1) != 0) {
  694               if (timeStyle < 0 || timeStyle > 3) {
  695                   throw new IllegalArgumentException("Illegal time style " + timeStyle);
  696               }
  697           } else {
  698               timeStyle = -1;
  699           }
  700           if ((flags & 2) != 0) {
  701               if (dateStyle < 0 || dateStyle > 3) {
  702                   throw new IllegalArgumentException("Illegal date style " + dateStyle);
  703               }
  704           } else {
  705               dateStyle = -1;
  706           }
  707           try {
  708               // Check whether a provider can provide an implementation that's closer
  709               // to the requested locale than what the Java runtime itself can provide.
  710               LocaleServiceProviderPool pool =
  711                   LocaleServiceProviderPool.getPool(DateFormatProvider.class);
  712               if (pool.hasProviders()) {
  713                   DateFormat providersInstance = pool.getLocalizedObject(
  714                                                       DateFormatGetter.INSTANCE,
  715                                                       loc,
  716                                                       timeStyle,
  717                                                       dateStyle,
  718                                                       flags);
  719                   if (providersInstance != null) {
  720                       return providersInstance;
  721                   }
  722               }
  723   
  724               return new SimpleDateFormat(timeStyle, dateStyle, loc);
  725           } catch (MissingResourceException e) {
  726               return new SimpleDateFormat("M/d/yy h:mm a");
  727           }
  728       }
  729   
  730       /**
  731        * Create a new date format.
  732        */
  733       protected DateFormat() {}
  734   
  735       /**
  736        * Defines constants that are used as attribute keys in the
  737        * <code>AttributedCharacterIterator</code> returned
  738        * from <code>DateFormat.formatToCharacterIterator</code> and as
  739        * field identifiers in <code>FieldPosition</code>.
  740        * <p>
  741        * The class also provides two methods to map
  742        * between its constants and the corresponding Calendar constants.
  743        *
  744        * @since 1.4
  745        * @see java.util.Calendar
  746        */
  747       public static class Field extends Format.Field {
  748   
  749           // Proclaim serial compatibility with 1.4 FCS
  750           private static final long serialVersionUID = 7441350119349544720L;
  751   
  752           // table of all instances in this class, used by readResolve
  753           private static final Map instanceMap = new HashMap(18);
  754           // Maps from Calendar constant (such as Calendar.ERA) to Field
  755           // constant (such as Field.ERA).
  756           private static final Field[] calendarToFieldMapping =
  757                                                new Field[Calendar.FIELD_COUNT];
  758   
  759           /** Calendar field. */
  760           private int calendarField;
  761   
  762           /**
  763            * Returns the <code>Field</code> constant that corresponds to
  764            * the <code>Calendar</code> constant <code>calendarField</code>.
  765            * If there is no direct mapping between the <code>Calendar</code>
  766            * constant and a <code>Field</code>, null is returned.
  767            *
  768            * @throws IllegalArgumentException if <code>calendarField</code> is
  769            *         not the value of a <code>Calendar</code> field constant.
  770            * @param calendarField Calendar field constant
  771            * @return Field instance representing calendarField.
  772            * @see java.util.Calendar
  773            */
  774           public static Field ofCalendarField(int calendarField) {
  775               if (calendarField < 0 || calendarField >=
  776                           calendarToFieldMapping.length) {
  777                   throw new IllegalArgumentException("Unknown Calendar constant "
  778                                                      + calendarField);
  779               }
  780               return calendarToFieldMapping[calendarField];
  781           }
  782   
  783           /**
  784            * Creates a <code>Field</code>.
  785            *
  786            * @param name the name of the <code>Field</code>
  787            * @param calendarField the <code>Calendar</code> constant this
  788            *        <code>Field</code> corresponds to; any value, even one
  789            *        outside the range of legal <code>Calendar</code> values may
  790            *        be used, but <code>-1</code> should be used for values
  791            *        that don't correspond to legal <code>Calendar</code> values
  792            */
  793           protected Field(String name, int calendarField) {
  794               super(name);
  795               this.calendarField = calendarField;
  796               if (this.getClass() == DateFormat.Field.class) {
  797                   instanceMap.put(name, this);
  798                   if (calendarField >= 0) {
  799                       // assert(calendarField < Calendar.FIELD_COUNT);
  800                       calendarToFieldMapping[calendarField] = this;
  801                   }
  802               }
  803           }
  804   
  805           /**
  806            * Returns the <code>Calendar</code> field associated with this
  807            * attribute. For example, if this represents the hours field of
  808            * a <code>Calendar</code>, this would return
  809            * <code>Calendar.HOUR</code>. If there is no corresponding
  810            * <code>Calendar</code> constant, this will return -1.
  811            *
  812            * @return Calendar constant for this field
  813            * @see java.util.Calendar
  814            */
  815           public int getCalendarField() {
  816               return calendarField;
  817           }
  818   
  819           /**
  820            * Resolves instances being deserialized to the predefined constants.
  821            *
  822            * @throws InvalidObjectException if the constant could not be
  823            *         resolved.
  824            * @return resolved DateFormat.Field constant
  825            */
  826           protected Object readResolve() throws InvalidObjectException {
  827               if (this.getClass() != DateFormat.Field.class) {
  828                   throw new InvalidObjectException("subclass didn't correctly implement readResolve");
  829               }
  830   
  831               Object instance = instanceMap.get(getName());
  832               if (instance != null) {
  833                   return instance;
  834               } else {
  835                   throw new InvalidObjectException("unknown attribute name");
  836               }
  837           }
  838   
  839           //
  840           // The constants
  841           //
  842   
  843           /**
  844            * Constant identifying the era field.
  845            */
  846           public final static Field ERA = new Field("era", Calendar.ERA);
  847   
  848           /**
  849            * Constant identifying the year field.
  850            */
  851           public final static Field YEAR = new Field("year", Calendar.YEAR);
  852   
  853           /**
  854            * Constant identifying the month field.
  855            */
  856           public final static Field MONTH = new Field("month", Calendar.MONTH);
  857   
  858           /**
  859            * Constant identifying the day of month field.
  860            */
  861           public final static Field DAY_OF_MONTH = new
  862                               Field("day of month", Calendar.DAY_OF_MONTH);
  863   
  864           /**
  865            * Constant identifying the hour of day field, where the legal values
  866            * are 1 to 24.
  867            */
  868           public final static Field HOUR_OF_DAY1 = new Field("hour of day 1",-1);
  869   
  870           /**
  871            * Constant identifying the hour of day field, where the legal values
  872            * are 0 to 23.
  873            */
  874           public final static Field HOUR_OF_DAY0 = new
  875                  Field("hour of day", Calendar.HOUR_OF_DAY);
  876   
  877           /**
  878            * Constant identifying the minute field.
  879            */
  880           public final static Field MINUTE =new Field("minute", Calendar.MINUTE);
  881   
  882           /**
  883            * Constant identifying the second field.
  884            */
  885           public final static Field SECOND =new Field("second", Calendar.SECOND);
  886   
  887           /**
  888            * Constant identifying the millisecond field.
  889            */
  890           public final static Field MILLISECOND = new
  891                   Field("millisecond", Calendar.MILLISECOND);
  892   
  893           /**
  894            * Constant identifying the day of week field.
  895            */
  896           public final static Field DAY_OF_WEEK = new
  897                   Field("day of week", Calendar.DAY_OF_WEEK);
  898   
  899           /**
  900            * Constant identifying the day of year field.
  901            */
  902           public final static Field DAY_OF_YEAR = new
  903                   Field("day of year", Calendar.DAY_OF_YEAR);
  904   
  905           /**
  906            * Constant identifying the day of week field.
  907            */
  908           public final static Field DAY_OF_WEEK_IN_MONTH =
  909                        new Field("day of week in month",
  910                                               Calendar.DAY_OF_WEEK_IN_MONTH);
  911   
  912           /**
  913            * Constant identifying the week of year field.
  914            */
  915           public final static Field WEEK_OF_YEAR = new
  916                 Field("week of year", Calendar.WEEK_OF_YEAR);
  917   
  918           /**
  919            * Constant identifying the week of month field.
  920            */
  921           public final static Field WEEK_OF_MONTH = new
  922               Field("week of month", Calendar.WEEK_OF_MONTH);
  923   
  924           /**
  925            * Constant identifying the time of day indicator
  926            * (e.g. "a.m." or "p.m.") field.
  927            */
  928           public final static Field AM_PM = new
  929                               Field("am pm", Calendar.AM_PM);
  930   
  931           /**
  932            * Constant identifying the hour field, where the legal values are
  933            * 1 to 12.
  934            */
  935           public final static Field HOUR1 = new Field("hour 1", -1);
  936   
  937           /**
  938            * Constant identifying the hour field, where the legal values are
  939            * 0 to 11.
  940            */
  941           public final static Field HOUR0 = new
  942                               Field("hour", Calendar.HOUR);
  943   
  944           /**
  945            * Constant identifying the time zone field.
  946            */
  947           public final static Field TIME_ZONE = new Field("time zone", -1);
  948       }
  949   
  950       /**
  951        * Obtains a DateFormat instance from a DateFormatProvider
  952        * implementation.
  953        */
  954       private static class DateFormatGetter
  955           implements LocaleServiceProviderPool.LocalizedObjectGetter<DateFormatProvider, DateFormat> {
  956           private static final DateFormatGetter INSTANCE = new DateFormatGetter();
  957   
  958           public DateFormat getObject(DateFormatProvider dateFormatProvider,
  959                                   Locale locale,
  960                                   String key,
  961                                   Object... params) {
  962               assert params.length == 3;
  963   
  964               int timeStyle = (Integer)params[0];
  965               int dateStyle = (Integer)params[1];
  966               int flags = (Integer)params[2];
  967   
  968               switch (flags) {
  969               case 1:
  970                   return dateFormatProvider.getTimeInstance(timeStyle, locale);
  971               case 2:
  972                   return dateFormatProvider.getDateInstance(dateStyle, locale);
  973               case 3:
  974                   return dateFormatProvider.getDateTimeInstance(dateStyle, timeStyle, locale);
  975               default:
  976                   assert false : "should not happen";
  977               }
  978   
  979               return null;
  980           }
  981       }
  982   }

Save This Page
Home » openjdk-7 » java » text » [javadoc | source]