Save This Page
Home » apache-harmony-6.0-src-r917296-snapshot » java » util » [javadoc | source]
    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    */
   17   
   18   package java.util;
   19   
   20   import java.io.IOException;
   21   import java.io.ObjectInputStream;
   22   import java.io.ObjectOutputStream;
   23   import java.io.ObjectStreamField;
   24   import java.io.Serializable;
   25   import java.text.DateFormatSymbols;
   26   
   27   /**
   28    * {@code Calendar} is an abstract base class for converting between a
   29    * {@code Date} object and a set of integer fields such as
   30    * {@code YEAR}, {@code MONTH}, {@code DAY},
   31    * {@code HOUR}, and so on. (A {@code Date} object represents a
   32    * specific instant in time with millisecond precision. See {@link Date} for
   33    * information about the {@code Date} class.)
   34    * 
   35    * <p>
   36    * Subclasses of {@code Calendar} interpret a {@code Date}
   37    * according to the rules of a specific calendar system.
   38    *
   39    * <p>
   40    * Like other locale-sensitive classes, {@code Calendar} provides a class
   41    * method, {@code getInstance}, for getting a default instance of
   42    * this class for general use. {@code Calendar}'s {@code getInstance} method
   43    * returns a calendar whose locale is based on system settings and whose time fields
   44    * have been initialized with the current date and time: <blockquote>
   45    *
   46    * <pre>Calendar rightNow = Calendar.getInstance()</pre>
   47    *
   48    * </blockquote>
   49    *
   50    * <p>
   51    * A {@code Calendar} object can produce all the time field values needed
   52    * to implement the date-time formatting for a particular language and calendar
   53    * style (for example, Japanese-Gregorian, Japanese-Traditional).
   54    * {@code Calendar} defines the range of values returned by certain
   55    * fields, as well as their meaning. For example, the first month of the year
   56    * has value {@code MONTH} == {@code JANUARY} for all calendars.
   57    * Other values are defined by the concrete subclass, such as {@code ERA}
   58    * and {@code YEAR}. See individual field documentation and subclass
   59    * documentation for details.
   60    *
   61    * <p>
   62    * When a {@code Calendar} is <em>lenient</em>, it accepts a wider
   63    * range of field values than it produces. For example, a lenient
   64    * {@code GregorianCalendar} interprets {@code MONTH} ==
   65    * {@code JANUARY}, {@code DAY_OF_MONTH} == 32 as February 1. A
   66    * non-lenient {@code GregorianCalendar} throws an exception when given
   67    * out-of-range field settings. When calendars recompute field values for return
   68    * by {@code get()}, they normalize them. For example, a
   69    * {@code GregorianCalendar} always produces {@code DAY_OF_MONTH}
   70    * values between 1 and the length of the month.
   71    *
   72    * <p>
   73    * {@code Calendar} defines a locale-specific seven day week using two
   74    * parameters: the first day of the week and the minimal days in first week
   75    * (from 1 to 7). These numbers are taken from the locale resource data when a
   76    * {@code Calendar} is constructed. They may also be specified explicitly
   77    * through the API.
   78    *
   79    * <p>
   80    * When setting or getting the {@code WEEK_OF_MONTH} or
   81    * {@code WEEK_OF_YEAR} fields, {@code Calendar} must determine
   82    * the first week of the month or year as a reference point. The first week of a
   83    * month or year is defined as the earliest seven day period beginning on
   84    * {@code getFirstDayOfWeek()} and containing at least
   85    * {@code getMinimalDaysInFirstWeek()} days of that month or year. Weeks
   86    * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow
   87    * it. Note that the normalized numbering returned by {@code get()} may
   88    * be different. For example, a specific {@code Calendar} subclass may
   89    * designate the week before week 1 of a year as week <em>n</em> of the
   90    * previous year.
   91    *
   92    * <p>
   93    * When computing a {@code Date} from time fields, two special
   94    * circumstances may arise: there may be insufficient information to compute the
   95    * {@code Date} (such as only year and month but no day in the month), or
   96    * there may be inconsistent information (such as "Tuesday, July 15, 1996" --
   97    * July 15, 1996 is actually a Monday).
   98    *
   99    * <p>
  100    * <strong>Insufficient information.</strong> The calendar will use default
  101    * information to specify the missing fields. This may vary by calendar; for the
  102    * Gregorian calendar, the default for a field is the same as that of the start
  103    * of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc.
  104    *
  105    * <p>
  106    * <strong>Inconsistent information.</strong> If fields conflict, the calendar
  107    * will give preference to fields set more recently. For example, when
  108    * determining the day, the calendar will look for one of the following
  109    * combinations of fields. The most recent combination, as determined by the
  110    * most recently set single field, will be used.
  111    *
  112    * <blockquote>
  113    *
  114    * <pre>
  115    * MONTH + DAY_OF_MONTH
  116    * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
  117    * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
  118    * DAY_OF_YEAR
  119    * DAY_OF_WEEK + WEEK_OF_YEAR</pre>
  120    *
  121    * </blockquote>
  122    *
  123    * For the time of day:
  124    *
  125    * <blockquote>
  126    *
  127    * <pre>
  128    * HOUR_OF_DAY
  129    * AM_PM + HOUR</pre>
  130    *
  131    * </blockquote>
  132    *
  133    * <p>
  134    * <strong>Note:</strong> There are certain possible ambiguities in
  135    * interpretation of certain singular times, which are resolved in the following
  136    * ways:
  137    * <ol>
  138    * <li> 24:00:00 "belongs" to the following day. That is, 23:59 on Dec 31, 1969
  139    * &lt; 24:00 on Jan 1, 1970 &lt; 24:01:00 on Jan 1, 1970 form a sequence of
  140    * three consecutive minutes in time.
  141    *
  142    * <li> Although historically not precise, midnight also belongs to "am", and
  143    * noon belongs to "pm", so on the same day, we have 12:00 am (midnight) &lt; 12:01 am,
  144    * and 12:00 pm (noon) &lt; 12:01 pm
  145    * </ol>
  146    *
  147    * <p>
  148    * The date or time format strings are not part of the definition of a calendar,
  149    * as those must be modifiable or overridable by the user at runtime. Use
  150    * {@link java.text.DateFormat} to format dates.
  151    *
  152    * <p>
  153    * <strong>Field manipulation methods</strong>
  154    *
  155    * <p>
  156    * {@code Calendar} fields can be changed using three methods:
  157    * {@code set()}, {@code add()}, and {@code roll()}.
  158    *
  159    * <p>
  160    * <strong>{@code set(f, value)}</strong> changes field {@code f}
  161    * to {@code value}. In addition, it sets an internal member variable to
  162    * indicate that field {@code f} has been changed. Although field
  163    * {@code f} is changed immediately, the calendar's milliseconds is not
  164    * recomputed until the next call to {@code get()},
  165    * {@code getTime()}, or {@code getTimeInMillis()} is made. Thus,
  166    * multiple calls to {@code set()} do not trigger multiple, unnecessary
  167    * computations. As a result of changing a field using {@code set()},
  168    * other fields may also change, depending on the field, the field value, and
  169    * the calendar system. In addition, {@code get(f)} will not necessarily
  170    * return {@code value} after the fields have been recomputed. The
  171    * specifics are determined by the concrete calendar class.
  172    *
  173    * <p>
  174    * <em>Example</em>: Consider a {@code GregorianCalendar} originally
  175    * set to August 31, 1999. Calling <code>set(Calendar.MONTH,
  176    * Calendar.SEPTEMBER)</code>
  177    * sets the calendar to September 31, 1999. This is a temporary internal
  178    * representation that resolves to October 1, 1999 if {@code getTime()}is
  179    * then called. However, a call to {@code set(Calendar.DAY_OF_MONTH, 30)}
  180    * before the call to {@code getTime()} sets the calendar to September
  181    * 30, 1999, since no recomputation occurs after {@code set()} itself.
  182    *
  183    * <p>
  184    * <strong>{@code add(f, delta)}</strong> adds {@code delta} to
  185    * field {@code f}. This is equivalent to calling <code>set(f,
  186    * get(f) + delta)</code>
  187    * with two adjustments:
  188    *
  189    * <blockquote>
  190    * <p>
  191    * <strong>Add rule 1</strong>. The value of field {@code f} after the
  192    * call minus the value of field {@code f} before the call is
  193    * {@code delta}, modulo any overflow that has occurred in field
  194    * {@code f}. Overflow occurs when a field value exceeds its range and,
  195    * as a result, the next larger field is incremented or decremented and the
  196    * field value is adjusted back into its range.
  197    *
  198    * <p>
  199    * <strong>Add rule 2</strong>. If a smaller field is expected to be invariant,
  200    * but &nbsp; it is impossible for it to be equal to its prior value because of
  201    * changes in its minimum or maximum after field {@code f} is changed,
  202    * then its value is adjusted to be as close as possible to its expected value.
  203    * A smaller field represents a smaller unit of time. {@code HOUR} is a
  204    * smaller field than {@code DAY_OF_MONTH}. No adjustment is made to
  205    * smaller fields that are not expected to be invariant. The calendar system
  206    * determines what fields are expected to be invariant.
  207    * </blockquote>
  208    *
  209    * <p>
  210    * In addition, unlike {@code set()}, {@code add()} forces an
  211    * immediate recomputation of the calendar's milliseconds and all fields.
  212    *
  213    * <p>
  214    * <em>Example</em>: Consider a {@code GregorianCalendar} originally
  215    * set to August 31, 1999. Calling {@code add(Calendar.MONTH, 13)} sets
  216    * the calendar to September 30, 2000. <strong>Add rule 1</strong> sets the
  217    * {@code MONTH} field to September, since adding 13 months to August
  218    * gives September of the next year. Since {@code DAY_OF_MONTH} cannot be
  219    * 31 in September in a {@code GregorianCalendar}, <strong>add rule 2</strong>
  220    * sets the {@code DAY_OF_MONTH} to 30, the closest possible value.
  221    * Although it is a smaller field, {@code DAY_OF_WEEK} is not adjusted by
  222    * rule 2, since it is expected to change when the month changes in a
  223    * {@code GregorianCalendar}.
  224    *
  225    * <p>
  226    * <strong>{@code roll(f, delta)}</strong> adds {@code delta} to
  227    * field {@code f} without changing larger fields. This is equivalent to
  228    * calling {@code add(f, delta)} with the following adjustment:
  229    *
  230    * <blockquote>
  231    * <p>
  232    * <strong>Roll rule</strong>. Larger fields are unchanged after the call. A
  233    * larger field represents a larger unit of time. {@code DAY_OF_MONTH} is
  234    * a larger field than {@code HOUR}.
  235    * </blockquote>
  236    *
  237    * <p>
  238    * <em>Example</em>: Consider a {@code GregorianCalendar} originally
  239    * set to August 31, 1999. Calling <code>roll(Calendar.MONTH,
  240    * 8)</code> sets
  241    * the calendar to April 30, <strong>1999</strong>. Add rule 1 sets the
  242    * {@code MONTH} field to April. Using a {@code GregorianCalendar},
  243    * the {@code DAY_OF_MONTH} cannot be 31 in the month April. Add rule 2
  244    * sets it to the closest possible value, 30. Finally, the <strong>roll rule</strong>
  245    * maintains the {@code YEAR} field value of 1999.
  246    *
  247    * <p>
  248    * <em>Example</em>: Consider a {@code GregorianCalendar} originally
  249    * set to Sunday June 6, 1999. Calling
  250    * {@code roll(Calendar.WEEK_OF_MONTH, -1)} sets the calendar to Tuesday
  251    * June 1, 1999, whereas calling {@code add(Calendar.WEEK_OF_MONTH, -1)}
  252    * sets the calendar to Sunday May 30, 1999. This is because the roll rule
  253    * imposes an additional constraint: The {@code MONTH} must not change
  254    * when the {@code WEEK_OF_MONTH} is rolled. Taken together with add rule
  255    * 1, the resultant date must be between Tuesday June 1 and Saturday June 5.
  256    * According to add rule 2, the {@code DAY_OF_WEEK}, an invariant when
  257    * changing the {@code WEEK_OF_MONTH}, is set to Tuesday, the closest
  258    * possible value to Sunday (where Sunday is the first day of the week).
  259    *
  260    * <p>
  261    * <strong>Usage model</strong>. To motivate the behavior of {@code add()}
  262    * and {@code roll()}, consider a user interface component with
  263    * increment and decrement buttons for the month, day, and year, and an
  264    * underlying {@code GregorianCalendar}. If the interface reads January
  265    * 31, 1999 and the user presses the month increment button, what should it
  266    * read? If the underlying implementation uses {@code set()}, it might
  267    * read March 3, 1999. A better result would be February 28, 1999. Furthermore,
  268    * if the user presses the month increment button again, it should read March
  269    * 31, 1999, not March 28, 1999. By saving the original date and using either
  270    * {@code add()} or {@code roll()}, depending on whether larger
  271    * fields should be affected, the user interface can behave as most users will
  272    * intuitively expect.
  273    *
  274    * <p>
  275    * <b>Note:</b> You should always use {@code roll} and {@code add} rather than
  276    * attempting to perform arithmetic operations directly on the fields of a
  277    * <tt>Calendar</tt>. It is quite possible for <tt>Calendar</tt> subclasses
  278    * to have fields with non-linear behavior, for example missing months or days
  279    * during non-leap years. The subclasses' <tt>add</tt> and <tt>roll</tt>
  280    * methods will take this into account, while simple arithmetic manipulations
  281    * may give invalid results.
  282    *
  283    * @see Date
  284    * @see GregorianCalendar
  285    * @see TimeZone
  286    */
  287   public abstract class Calendar implements Serializable, Cloneable,
  288           Comparable<Calendar> {
  289   
  290       private static final long serialVersionUID = -1807547505821590642L;
  291   
  292       /**
  293        * Set to {@code true} when the calendar fields have been set from the time, set to
  294        * {@code false} when a field is changed and the fields must be recomputed.
  295        */
  296       protected boolean areFieldsSet;
  297   
  298       /**
  299        * An integer array of calendar fields. The length is {@code FIELD_COUNT}.
  300        */
  301       protected int[] fields;
  302   
  303       /**
  304        * A boolean array. Each element indicates if the corresponding field has
  305        * been set. The length is {@code FIELD_COUNT}.
  306        */
  307       protected boolean[] isSet;
  308   
  309       /**
  310        * Set to {@code true} when the time has been set, set to {@code false} when a field is
  311        * changed and the time must be recomputed.
  312        */
  313       protected boolean isTimeSet;
  314   
  315   	/**
  316   	 * A specifier for all styles.
  317   	 * 
  318   	 * @since 1.6
  319   	 */
  320   	public static final int ALL_STYLES = 0;
  321   
  322   	/**
  323   	 * A specifier for a short name
  324   	 * 
  325   	 * @since 1.6
  326   	 */
  327   	public static final int SHORT = 1;
  328   
  329   	/**
  330   	 * A specifier for a long name
  331   	 * 
  332   	 * @since 1.6
  333   	 */
  334   	public static final int LONG = 2;
  335   
  336   	/**
  337   	 * The time in milliseconds since January 1, 1970.
  338   	 */
  339   	protected long time;
  340   
  341   	/**
  342   	 * The version of the serialized data of the class
  343   	 */
  344   	int serialVersionOnStream = 1;
  345   
  346       transient int lastTimeFieldSet;
  347   
  348       transient int lastDateFieldSet;
  349   
  350       private boolean lenient;
  351   
  352       private int firstDayOfWeek;
  353   
  354       private int minimalDaysInFirstWeek;
  355   
  356       private TimeZone zone;
  357   
  358       /**
  359        * Value of the {@code MONTH} field indicating the first month of the
  360        * year.
  361        */
  362       public static final int JANUARY = 0;
  363   
  364       /**
  365        * Value of the {@code MONTH} field indicating the second month of
  366        * the year.
  367        */
  368       public static final int FEBRUARY = 1;
  369   
  370       /**
  371        * Value of the {@code MONTH} field indicating the third month of the
  372        * year.
  373        */
  374       public static final int MARCH = 2;
  375   
  376       /**
  377        * Value of the {@code MONTH} field indicating the fourth month of
  378        * the year.
  379        */
  380       public static final int APRIL = 3;
  381   
  382       /**
  383        * Value of the {@code MONTH} field indicating the fifth month of the
  384        * year.
  385        */
  386       public static final int MAY = 4;
  387   
  388       /**
  389        * Value of the {@code MONTH} field indicating the sixth month of the
  390        * year.
  391        */
  392       public static final int JUNE = 5;
  393   
  394       /**
  395        * Value of the {@code MONTH} field indicating the seventh month of
  396        * the year.
  397        */
  398       public static final int JULY = 6;
  399   
  400       /**
  401        * Value of the {@code MONTH} field indicating the eighth month of
  402        * the year.
  403        */
  404       public static final int AUGUST = 7;
  405   
  406       /**
  407        * Value of the {@code MONTH} field indicating the ninth month of the
  408        * year.
  409        */
  410       public static final int SEPTEMBER = 8;
  411   
  412       /**
  413        * Value of the {@code MONTH} field indicating the tenth month of the
  414        * year.
  415        */
  416       public static final int OCTOBER = 9;
  417   
  418       /**
  419        * Value of the {@code MONTH} field indicating the eleventh month of
  420        * the year.
  421        */
  422       public static final int NOVEMBER = 10;
  423   
  424       /**
  425        * Value of the {@code MONTH} field indicating the twelfth month of
  426        * the year.
  427        */
  428       public static final int DECEMBER = 11;
  429   
  430       /**
  431        * Value of the {@code MONTH} field indicating the thirteenth month
  432        * of the year. Although {@code GregorianCalendar} does not use this
  433        * value, lunar calendars do.
  434        */
  435       public static final int UNDECIMBER = 12;
  436   
  437       /**
  438        * Value of the {@code DAY_OF_WEEK} field indicating Sunday.
  439        */
  440       public static final int SUNDAY = 1;
  441   
  442       /**
  443        * Value of the {@code DAY_OF_WEEK} field indicating Monday.
  444        */
  445       public static final int MONDAY = 2;
  446   
  447       /**
  448        * Value of the {@code DAY_OF_WEEK} field indicating Tuesday.
  449        */
  450       public static final int TUESDAY = 3;
  451   
  452       /**
  453        * Value of the {@code DAY_OF_WEEK} field indicating Wednesday.
  454        */
  455       public static final int WEDNESDAY = 4;
  456   
  457       /**
  458        * Value of the {@code DAY_OF_WEEK} field indicating Thursday.
  459        */
  460       public static final int THURSDAY = 5;
  461   
  462       /**
  463        * Value of the {@code DAY_OF_WEEK} field indicating Friday.
  464        */
  465       public static final int FRIDAY = 6;
  466   
  467       /**
  468        * Value of the {@code DAY_OF_WEEK} field indicating Saturday.
  469        */
  470       public static final int SATURDAY = 7;
  471   
  472       /**
  473        * Field number for {@code get} and {@code set} indicating the
  474        * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
  475        * value; see subclass documentation.
  476        *
  477        * @see GregorianCalendar#AD
  478        * @see GregorianCalendar#BC
  479        */
  480       public static final int ERA = 0;
  481   
  482       /**
  483        * Field number for {@code get} and {@code set} indicating the
  484        * year. This is a calendar-specific value; see subclass documentation.
  485        */
  486       public static final int YEAR = 1;
  487   
  488       /**
  489        * Field number for {@code get} and {@code set} indicating the
  490        * month. This is a calendar-specific value. The first month of the year is
  491        * {@code JANUARY}; the last depends on the number of months in a
  492        * year.
  493        *
  494        * @see #JANUARY
  495        * @see #FEBRUARY
  496        * @see #MARCH
  497        * @see #APRIL
  498        * @see #MAY
  499        * @see #JUNE
  500        * @see #JULY
  501        * @see #AUGUST
  502        * @see #SEPTEMBER
  503        * @see #OCTOBER
  504        * @see #NOVEMBER
  505        * @see #DECEMBER
  506        * @see #UNDECIMBER
  507        */
  508       public static final int MONTH = 2;
  509   
  510       /**
  511        * Field number for {@code get} and {@code set} indicating the
  512        * week number within the current year. The first week of the year, as
  513        * defined by {@code getFirstDayOfWeek()} and
  514        * {@code getMinimalDaysInFirstWeek()}, has value 1. Subclasses
  515        * define the value of {@code WEEK_OF_YEAR} for days before the first
  516        * week of the year.
  517        *
  518        * @see #getFirstDayOfWeek
  519        * @see #getMinimalDaysInFirstWeek
  520        */
  521       public static final int WEEK_OF_YEAR = 3;
  522   
  523       /**
  524        * Field number for {@code get} and {@code set} indicating the
  525        * week number within the current month. The first week of the month, as
  526        * defined by {@code getFirstDayOfWeek()} and
  527        * {@code getMinimalDaysInFirstWeek()}, has value 1. Subclasses
  528        * define the value of {@code WEEK_OF_MONTH} for days before the
  529        * first week of the month.
  530        *
  531        * @see #getFirstDayOfWeek
  532        * @see #getMinimalDaysInFirstWeek
  533        */
  534       public static final int WEEK_OF_MONTH = 4;
  535   
  536       /**
  537        * Field number for {@code get} and {@code set} indicating the
  538        * day of the month. This is a synonym for {@code DAY_OF_MONTH}. The
  539        * first day of the month has value 1.
  540        *
  541        * @see #DAY_OF_MONTH
  542        */
  543       public static final int DATE = 5;
  544   
  545       /**
  546        * Field number for {@code get} and {@code set} indicating the
  547        * day of the month. This is a synonym for {@code DATE}. The first
  548        * day of the month has value 1.
  549        *
  550        * @see #DATE
  551        */
  552       public static final int DAY_OF_MONTH = 5;
  553   
  554       /**
  555        * Field number for {@code get} and {@code set} indicating the
  556        * day number within the current year. The first day of the year has value
  557        * 1.
  558        */
  559       public static final int DAY_OF_YEAR = 6;
  560   
  561       /**
  562        * Field number for {@code get} and {@code set} indicating the
  563        * day of the week. This field takes values {@code SUNDAY},
  564        * {@code MONDAY}, {@code TUESDAY}, {@code WEDNESDAY},
  565        * {@code THURSDAY}, {@code FRIDAY}, and
  566        * {@code SATURDAY}.
  567        *
  568        * @see #SUNDAY
  569        * @see #MONDAY
  570        * @see #TUESDAY
  571        * @see #WEDNESDAY
  572        * @see #THURSDAY
  573        * @see #FRIDAY
  574        * @see #SATURDAY
  575        */
  576       public static final int DAY_OF_WEEK = 7;
  577   
  578       /**
  579        * Field number for {@code get} and {@code set} indicating the
  580        * ordinal number of the day of the week within the current month. Together
  581        * with the {@code DAY_OF_WEEK} field, this uniquely specifies a day
  582        * within a month. Unlike {@code WEEK_OF_MONTH} and
  583        * {@code WEEK_OF_YEAR}, this field's value does <em>not</em>
  584        * depend on {@code getFirstDayOfWeek()} or
  585        * {@code getMinimalDaysInFirstWeek()}. {@code DAY_OF_MONTH 1}
  586        * through {@code 7} always correspond to <code>DAY_OF_WEEK_IN_MONTH
  587        * 1</code>;
  588        * {@code 8} through {@code 15} correspond to
  589        * {@code DAY_OF_WEEK_IN_MONTH 2}, and so on.
  590        * {@code DAY_OF_WEEK_IN_MONTH 0} indicates the week before
  591        * {@code DAY_OF_WEEK_IN_MONTH 1}. Negative values count back from
  592        * the end of the month, so the last Sunday of a month is specified as
  593        * {@code DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1}. Because
  594        * negative values count backward they will usually be aligned differently
  595        * within the month than positive values. For example, if a month has 31
  596        * days, {@code DAY_OF_WEEK_IN_MONTH -1} will overlap
  597        * {@code DAY_OF_WEEK_IN_MONTH 5} and the end of {@code 4}.
  598        *
  599        * @see #DAY_OF_WEEK
  600        * @see #WEEK_OF_MONTH
  601        */
  602       public static final int DAY_OF_WEEK_IN_MONTH = 8;
  603   
  604       /**
  605        * Field number for {@code get} and {@code set} indicating
  606        * whether the {@code HOUR} is before or after noon. E.g., at
  607        * 10:04:15.250 PM the {@code AM_PM} is {@code PM}.
  608        *
  609        * @see #AM
  610        * @see #PM
  611        * @see #HOUR
  612        */
  613       public static final int AM_PM = 9;
  614   
  615       /**
  616        * Field number for {@code get} and {@code set} indicating the
  617        * hour of the morning or afternoon. {@code HOUR} is used for the
  618        * 12-hour clock. E.g., at 10:04:15.250 PM the {@code HOUR} is 10.
  619        *
  620        * @see #AM_PM
  621        * @see #HOUR_OF_DAY
  622        */
  623       public static final int HOUR = 10;
  624   
  625       /**
  626        * Field number for {@code get} and {@code set} indicating the
  627        * hour of the day. {@code HOUR_OF_DAY} is used for the 24-hour
  628        * clock. E.g., at 10:04:15.250 PM the {@code HOUR_OF_DAY} is 22.
  629        *
  630        * @see #HOUR
  631        */
  632       public static final int HOUR_OF_DAY = 11;
  633   
  634       /**
  635        * Field number for {@code get} and {@code set} indicating the
  636        * minute within the hour. E.g., at 10:04:15.250 PM the {@code MINUTE}
  637        * is 4.
  638        */
  639       public static final int MINUTE = 12;
  640   
  641       /**
  642        * Field number for {@code get} and {@code set} indicating the
  643        * second within the minute. E.g., at 10:04:15.250 PM the
  644        * {@code SECOND} is 15.
  645        */
  646       public static final int SECOND = 13;
  647   
  648       /**
  649        * Field number for {@code get} and {@code set} indicating the
  650        * millisecond within the second. E.g., at 10:04:15.250 PM the
  651        * {@code MILLISECOND} is 250.
  652        */
  653       public static final int MILLISECOND = 14;
  654   
  655       /**
  656        * Field number for {@code get} and {@code set} indicating the
  657        * raw offset from GMT in milliseconds.
  658        */
  659       public static final int ZONE_OFFSET = 15;
  660   
  661       /**
  662        * Field number for {@code get} and {@code set} indicating the
  663        * daylight savings offset in milliseconds.
  664        */
  665       public static final int DST_OFFSET = 16;
  666   
  667       /**
  668        * This is the total number of fields in this calendar.
  669        */
  670       public static final int FIELD_COUNT = 17;
  671   
  672       /**
  673        * Value of the {@code AM_PM} field indicating the period of the day
  674        * from midnight to just before noon.
  675        */
  676       public static final int AM = 0;
  677   
  678       /**
  679        * Value of the {@code AM_PM} field indicating the period of the day
  680        * from noon to just before midnight.
  681        */
  682       public static final int PM = 1;
  683   
  684       private static String[] fieldNames = { "ERA=", "YEAR=", "MONTH=", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  685               "WEEK_OF_YEAR=", "WEEK_OF_MONTH=", "DAY_OF_MONTH=", "DAY_OF_YEAR=", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
  686               "DAY_OF_WEEK=", "DAY_OF_WEEK_IN_MONTH=", "AM_PM=", "HOUR=", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
  687               "HOUR_OF_DAY", "MINUTE=", "SECOND=", "MILLISECOND=", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
  688               "ZONE_OFFSET=", "DST_OFFSET=" }; //$NON-NLS-1$ //$NON-NLS-2$
  689   
  690       /**
  691        * Constructs a {@code Calendar} instance using the default {@code TimeZone} and {@code Locale}.
  692        */
  693       protected Calendar() {
  694           this(TimeZone.getDefault(), Locale.getDefault());
  695       }
  696   
  697       Calendar(TimeZone timezone) {
  698           fields = new int[FIELD_COUNT];
  699           isSet = new boolean[FIELD_COUNT];
  700           areFieldsSet = isTimeSet = false;
  701           setLenient(true);
  702           setTimeZone(timezone);
  703       }
  704   
  705       /**
  706        * Constructs a {@code Calendar} instance using the specified {@code TimeZone} and {@code Locale}.
  707        *
  708        * @param timezone
  709        *            the timezone.
  710        * @param locale
  711        *            the locale.
  712        */
  713       protected Calendar(TimeZone timezone, Locale locale) {
  714           this(timezone);
  715           com.ibm.icu.util.Calendar icuCalendar = com.ibm.icu.util.Calendar
  716                   .getInstance(com.ibm.icu.util.SimpleTimeZone
  717                           .getTimeZone(timezone.getID()), locale);
  718           setFirstDayOfWeek(icuCalendar.getFirstDayOfWeek());
  719           setMinimalDaysInFirstWeek(icuCalendar.getMinimalDaysInFirstWeek());
  720       }
  721   
  722   
  723       /**
  724        * Adds the specified amount to a {@code Calendar} field.
  725        * 
  726        * @param field
  727        *            the {@code Calendar} field to modify.
  728        * @param value
  729        *            the amount to add to the field.
  730        * @throws IllegalArgumentException
  731        *                if {@code field} is {@code DST_OFFSET} or {@code
  732        *                ZONE_OFFSET}.
  733        */
  734       abstract public void add(int field, int value);
  735   
  736       /**
  737        * Returns whether the {@code Date} specified by this {@code Calendar} instance is after the {@code Date}
  738        * specified by the parameter. The comparison is not dependent on the time
  739        * zones of the {@code Calendar}.
  740        * 
  741        * @param calendar
  742        *            the {@code Calendar} instance to compare.
  743        * @return {@code true} when this Calendar is after calendar, {@code false} otherwise.
  744        * @throws IllegalArgumentException
  745        *                if the time is not set and the time cannot be computed
  746        *                from the current field values.
  747        */
  748       public boolean after(Object calendar) {
  749           if (!(calendar instanceof Calendar)) {
  750               return false;
  751           }
  752           return getTimeInMillis() > ((Calendar) calendar).getTimeInMillis();
  753       }
  754   
  755       /**
  756        * Returns whether the {@code Date} specified by this {@code Calendar} instance is before the
  757        * {@code Date} specified by the parameter. The comparison is not dependent on the
  758        * time zones of the {@code Calendar}.
  759        * 
  760        * @param calendar
  761        *            the {@code Calendar} instance to compare.
  762        * @return {@code true} when this Calendar is before calendar, {@code false} otherwise.
  763        * @throws IllegalArgumentException
  764        *                if the time is not set and the time cannot be computed
  765        *                from the current field values.
  766        */
  767       public boolean before(Object calendar) {
  768           if (!(calendar instanceof Calendar)) {
  769               return false;
  770           }
  771           return getTimeInMillis() < ((Calendar) calendar).getTimeInMillis();
  772       }
  773   
  774       /**
  775        * Clears all of the fields of this {@code Calendar}. All fields are initialized to
  776        * zero.
  777        */
  778       public final void clear() {
  779           for (int i = 0; i < FIELD_COUNT; i++) {
  780               fields[i] = 0;
  781               isSet[i] = false;
  782           }
  783           areFieldsSet = isTimeSet = false;
  784       }
  785   
  786       /**
  787        * Clears the specified field to zero and sets the isSet flag to {@code false}.
  788        * 
  789        * @param field
  790        *            the field to clear.
  791        */
  792       public final void clear(int field) {
  793           fields[field] = 0;
  794           isSet[field] = false;
  795           areFieldsSet = isTimeSet = false;
  796       }
  797   
  798       /**
  799        * Returns a new {@code Calendar} with the same properties.
  800        * 
  801        * @return a shallow copy of this {@code Calendar}.
  802        * 
  803        * @see java.lang.Cloneable
  804        */
  805       @Override
  806       public Object clone() {
  807           try {
  808               Calendar clone = (Calendar) super.clone();
  809               clone.fields = fields.clone();
  810               clone.isSet = isSet.clone();
  811               clone.zone = (TimeZone) zone.clone();
  812               return clone;
  813           } catch (CloneNotSupportedException e) {
  814               return null;
  815           }
  816       }
  817   
  818       /**
  819        * Computes the time from the fields if the time has not already been set.
  820        * Computes the fields from the time if the fields are not already set.
  821        * 
  822        * @throws IllegalArgumentException
  823        *                if the time is not set and the time cannot be computed
  824        *                from the current field values.
  825        */
  826       protected void complete() {
  827           if (!isTimeSet) {
  828               computeTime();
  829               isTimeSet = true;
  830           }
  831           if (!areFieldsSet) {
  832               computeFields();
  833               areFieldsSet = true;
  834           }
  835       }
  836   
  837       /**
  838        * Computes the {@code Calendar} fields from {@code time}.
  839        */
  840       protected abstract void computeFields();
  841   
  842       /**
  843        * Computes {@code time} from the Calendar fields.
  844        * 
  845        * @throws IllegalArgumentException
  846        *                if the time cannot be computed from the current field
  847        *                values.
  848        */
  849       protected abstract void computeTime();
  850   
  851       /**
  852        * Compares the specified object to this {@code Calendar} and returns whether they are
  853        * equal. The object must be an instance of {@code Calendar} and have the same
  854        * properties.
  855        * 
  856        * @param object
  857        *            the object to compare with this object.
  858        * @return {@code true} if the specified object is equal to this {@code Calendar}, {@code false}
  859        *         otherwise.
  860        */
  861       @Override
  862       public boolean equals(Object object) {
  863           if (this == object) {
  864               return true;
  865           }
  866           if (!(object instanceof Calendar)) {
  867               return false;
  868           }
  869           Calendar cal = (Calendar) object;
  870           return getTimeInMillis() == cal.getTimeInMillis()
  871                   && isLenient() == cal.isLenient()
  872                   && getFirstDayOfWeek() == cal.getFirstDayOfWeek()
  873                   && getMinimalDaysInFirstWeek() == cal
  874                           .getMinimalDaysInFirstWeek()
  875                   && getTimeZone().equals(cal.getTimeZone());
  876       }
  877   
  878       /**
  879        * Gets the value of the specified field after computing the field values by
  880        * calling {@code complete()} first.
  881        * 
  882        * @param field
  883        *            the field to get.
  884        * @return the value of the specified field.
  885        * 
  886        * @throws IllegalArgumentException
  887        *                if the fields are not set, the time is not set, and the
  888        *                time cannot be computed from the current field values.
  889        * @throws ArrayIndexOutOfBoundsException
  890        *                if the field is not inside the range of possible fields.
  891        *                The range is starting at 0 up to {@code FIELD_COUNT}.
  892        */
  893       public int get(int field) {
  894           complete();
  895           return fields[field];
  896       }
  897   
  898       /**
  899        * Gets the maximum value of the specified field for the current date.
  900        * 
  901        * @param field
  902        *            the field.
  903        * @return the maximum value of the specified field.
  904        */
  905       public int getActualMaximum(int field) {
  906           int value, next;
  907           if (getMaximum(field) == (next = getLeastMaximum(field))) {
  908               return next;
  909           }
  910           complete();
  911           long orgTime = time;
  912           set(field, next);
  913           do {
  914               value = next;
  915               roll(field, true);
  916               next = get(field);
  917           } while (next > value);
  918           time = orgTime;
  919           areFieldsSet = false;
  920           return value;
  921       }
  922   
  923       /**
  924        * Gets the minimum value of the specified field for the current date.
  925        * 
  926        * @param field
  927        *            the field.
  928        * @return the minimum value of the specified field.
  929        */
  930       public int getActualMinimum(int field) {
  931           int value, next;
  932           if (getMinimum(field) == (next = getGreatestMinimum(field))) {
  933               return next;
  934           }
  935           complete();
  936           long orgTime = time;
  937           set(field, next);
  938           do {
  939               value = next;
  940               roll(field, false);
  941               next = get(field);
  942           } while (next < value);
  943           time = orgTime;
  944           areFieldsSet = false;
  945           return value;
  946       }
  947   
  948       /**
  949        * Gets the list of installed {@code Locale}s which support {@code Calendar}.
  950        * 
  951        * @return an array of {@code Locale}.
  952        */
  953       public static synchronized Locale[] getAvailableLocales() {
  954           return Locale.getAvailableLocales();
  955       }
  956   
  957       /**
  958        * Gets the first day of the week for this {@code Calendar}.
  959        * 
  960        * @return the first day of the week.
  961        */
  962       public int getFirstDayOfWeek() {
  963           return firstDayOfWeek;
  964       }
  965   
  966       /**
  967        * Gets the greatest minimum value of the specified field. This is the
  968        * biggest value that {@code getActualMinimum} can return for any possible
  969        * time.
  970        * 
  971        * @param field
  972        *            the field.
  973        * @return the greatest minimum value of the specified field.
  974        */
  975       abstract public int getGreatestMinimum(int field);
  976   
  977       /**
  978        * Constructs a new instance of the {@code Calendar} subclass appropriate for the
  979        * default {@code Locale}.
  980        * 
  981        * @return a {@code Calendar} subclass instance set to the current date and time in
  982        *         the default {@code Timezone}.
  983        */
  984       public static synchronized Calendar getInstance() {
  985           return new GregorianCalendar();
  986       }
  987   
  988       /**
  989        * Constructs a new instance of the {@code Calendar} subclass appropriate for the
  990        * specified {@code Locale}.
  991        * 
  992        * @param locale
  993        *            the locale to use.
  994        * @return a {@code Calendar} subclass instance set to the current date and time.
  995        */
  996       public static synchronized Calendar getInstance(Locale locale) {
  997           return new GregorianCalendar(locale);
  998       }
  999   
 1000       /**
 1001        * Constructs a new instance of the {@code Calendar} subclass appropriate for the
 1002        * default {@code Locale}, using the specified {@code TimeZone}.
 1003        * 
 1004        * @param timezone
 1005        *            the {@code TimeZone} to use.
 1006        * @return a {@code Calendar} subclass instance set to the current date and time in
 1007        *         the specified timezone.
 1008        */
 1009       public static synchronized Calendar getInstance(TimeZone timezone) {
 1010           return new GregorianCalendar(timezone);
 1011       }
 1012   
 1013       /**
 1014        * Constructs a new instance of the {@code Calendar} subclass appropriate for the
 1015        * specified {@code Locale}.
 1016        *
 1017        * @param timezone
 1018        *            the {@code TimeZone} to use.
 1019        * @param locale
 1020        *            the {@code Locale} to use.
 1021        * @return a {@code Calendar} subclass instance set to the current date and time in
 1022        *         the specified timezone.
 1023        */
 1024       public static synchronized Calendar getInstance(TimeZone timezone,
 1025               Locale locale) {
 1026           return new GregorianCalendar(timezone, locale);
 1027       }
 1028   
 1029       /**
 1030        * Gets the smallest maximum value of the specified field. This is the
 1031        * smallest value that {@code getActualMaximum()} can return for any
 1032        * possible time.
 1033        * 
 1034        * @param field
 1035        *            the field number.
 1036        * @return the smallest maximum value of the specified field.
 1037        */
 1038       abstract public int getLeastMaximum(int field);
 1039   
 1040       /**
 1041        * Gets the greatest maximum value of the specified field. This returns the
 1042        * biggest value that {@code get} can return for the specified field.
 1043        * 
 1044        * @param field
 1045        *            the field.
 1046        * @return the greatest maximum value of the specified field.
 1047        */
 1048       abstract public int getMaximum(int field);
 1049   
 1050       /**
 1051        * Gets the minimal days in the first week of the year.
 1052        * 
 1053        * @return the minimal days in the first week of the year.
 1054        */
 1055       public int getMinimalDaysInFirstWeek() {
 1056           return minimalDaysInFirstWeek;
 1057       }
 1058   
 1059       /**
 1060        * Gets the smallest minimum value of the specified field. this returns the
 1061        * smallest value thet {@code get} can return for the specified field.
 1062        * 
 1063        * @param field
 1064        *            the field number.
 1065        * @return the smallest minimum value of the specified field.
 1066        */
 1067       abstract public int getMinimum(int field);
 1068   
 1069       /**
 1070        * Gets the time of this {@code Calendar} as a {@code Date} object.
 1071        * 
 1072        * @return a new {@code Date} initialized to the time of this {@code Calendar}.
 1073        * 
 1074        * @throws IllegalArgumentException
 1075        *                if the time is not set and the time cannot be computed
 1076        *                from the current field values.
 1077        */
 1078       public final Date getTime() {
 1079           return new Date(getTimeInMillis());
 1080       }
 1081   
 1082       /**
 1083        * Computes the time from the fields if required and returns the time.
 1084        * 
 1085        * @return the time of this {@code Calendar}.
 1086        * 
 1087        * @throws IllegalArgumentException
 1088        *                if the time is not set and the time cannot be computed
 1089        *                from the current field values.
 1090        */
 1091       public long getTimeInMillis() {
 1092           if (!isTimeSet) {
 1093               computeTime();
 1094               isTimeSet = true;
 1095           }
 1096           return time;
 1097       }
 1098   
 1099       /**
 1100        * Gets the timezone of this {@code Calendar}.
 1101        * 
 1102        * @return the {@code TimeZone} used by this {@code Calendar}.
 1103        */
 1104       public TimeZone getTimeZone() {
 1105           return zone;
 1106       }
 1107   
 1108       /**
 1109        * Returns an integer hash code for the receiver. Objects which are equal
 1110        * return the same value for this method.
 1111        * 
 1112        * @return the receiver's hash.
 1113        * 
 1114        * @see #equals
 1115        */
 1116       @Override
 1117       public int hashCode() {
 1118           return (isLenient() ? 1237 : 1231) + getFirstDayOfWeek()
 1119                   + getMinimalDaysInFirstWeek() + getTimeZone().hashCode();
 1120       }
 1121   
 1122       /**
 1123        * Gets the value of the specified field without recomputing.
 1124        * 
 1125        * @param field
 1126        *            the field.
 1127        * @return the value of the specified field.
 1128        */
 1129       protected final int internalGet(int field) {
 1130           return fields[field];
 1131       }
 1132   
 1133       /**
 1134        * Returns if this {@code Calendar} accepts field values which are outside the valid
 1135        * range for the field.
 1136        * 
 1137        * @return {@code true} if this {@code Calendar} is lenient, {@code false} otherwise.
 1138        */
 1139       public boolean isLenient() {
 1140           return lenient;
 1141       }
 1142   
 1143       /**
 1144        * Returns whether the specified field is set.
 1145        * 
 1146        * @param field
 1147        *            a {@code Calendar} field number.
 1148        * @return {@code true} if the specified field is set, {@code false} otherwise.
 1149        */
 1150       public final boolean isSet(int field) {
 1151           return isSet[field];
 1152       }
 1153   
 1154       /**
 1155        * Adds the specified amount to the specified field and wraps the value of
 1156        * the field when it goes beyond the maximum or minimum value for the
 1157        * current date. Other fields will be adjusted as required to maintain a
 1158        * consistent date.
 1159        * 
 1160        * @param field
 1161        *            the field to roll.
 1162        * @param value
 1163        *            the amount to add.
 1164        */
 1165       public void roll(int field, int value) {
 1166           boolean increment = value >= 0;
 1167           int count = increment ? value : -value;
 1168           for (int i = 0; i < count; i++) {
 1169               roll(field, increment);
 1170           }
 1171       }
 1172   
 1173       /**
 1174        * Increment or decrement the specified field and wrap the value of the
 1175        * field when it goes beyond the maximum or minimum value for the current
 1176        * date. Other fields will be adjusted as required to maintain a consistent
 1177        * date.
 1178        * 
 1179        * @param field
 1180        *            the number indicating the field to roll.
 1181        * @param increment
 1182        *            {@code true} to increment the field, {@code false} to decrement.
 1183        */
 1184       abstract public void roll(int field, boolean increment);
 1185   
 1186       /**
 1187        * Sets a field to the specified value.
 1188        * 
 1189        * @param field
 1190        *            the code indicating the {@code Calendar} field to modify.
 1191        * @param value
 1192        *            the value.
 1193        */
 1194       public void set(int field, int value) {
 1195           fields[field] = value;
 1196           isSet[field] = true;
 1197           areFieldsSet = isTimeSet = false;
 1198           if (field > MONTH && field < AM_PM) {
 1199               lastDateFieldSet = field;
 1200           }
 1201           if (field == HOUR || field == HOUR_OF_DAY) {
 1202               lastTimeFieldSet = field;
 1203           }
 1204           if (field == AM_PM) {
 1205               lastTimeFieldSet = HOUR;
 1206           }
 1207       }
 1208   
 1209       /**
 1210        * Sets the year, month and day of the month fields. Other fields are not
 1211        * changed.
 1212        * 
 1213        * @param year
 1214        *            the year.
 1215        * @param month
 1216        *            the month.
 1217        * @param day
 1218        *            the day of the month.
 1219        */
 1220       public final void set(int year, int month, int day) {
 1221           set(YEAR, year);
 1222           set(MONTH, month);
 1223           set(DATE, day);
 1224       }
 1225   
 1226       /**
 1227        * Sets the year, month, day of the month, hour of day and minute fields.
 1228        * Other fields are not changed.
 1229        *
 1230        * @param year
 1231        *            the year.
 1232        * @param month
 1233        *            the month.
 1234        * @param day
 1235        *            the day of the month.
 1236        * @param hourOfDay
 1237        *            the hour of day.
 1238        * @param minute
 1239        *            the minute.
 1240        */
 1241       public final void set(int year, int month, int day, int hourOfDay,
 1242               int minute) {
 1243           set(year, month, day);
 1244           set(HOUR_OF_DAY, hourOfDay);
 1245           set(MINUTE, minute);
 1246       }
 1247   
 1248       /**
 1249        * Sets the year, month, day of the month, hour of day, minute and second
 1250        * fields. Other fields are not changed.
 1251        * 
 1252        * @param year
 1253        *            the year.
 1254        * @param month
 1255        *            the month.
 1256        * @param day
 1257        *            the day of the month.
 1258        * @param hourOfDay
 1259        *            the hour of day.
 1260        * @param minute
 1261        *            the minute.
 1262        * @param second
 1263        *            the second.
 1264        */
 1265       public final void set(int year, int month, int day, int hourOfDay,
 1266               int minute, int second) {
 1267           set(year, month, day, hourOfDay, minute);
 1268           set(SECOND, second);
 1269       }
 1270   
 1271       /**
 1272        * Sets the first day of the week for this {@code Calendar}.
 1273        * 
 1274        * @param value
 1275        *            a {@code Calendar} day of the week.
 1276        */
 1277       public void setFirstDayOfWeek(int value) {
 1278           firstDayOfWeek = value;
 1279       }
 1280   
 1281       /**
 1282        * Sets this {@code Calendar} to accept field values which are outside the valid
 1283        * range for the field.
 1284        * 
 1285        * @param value
 1286        *            a boolean value.
 1287        */
 1288       public void setLenient(boolean value) {
 1289           lenient = value;
 1290       }
 1291   
 1292       /**
 1293        * Sets the minimal days in the first week of the year.
 1294        * 
 1295        * @param value
 1296        *            the minimal days in the first week of the year.
 1297        */
 1298       public void setMinimalDaysInFirstWeek(int value) {
 1299           minimalDaysInFirstWeek = value;
 1300       }
 1301   
 1302       /**
 1303        * Sets the time of this {@code Calendar}.
 1304        * 
 1305        * @param date
 1306        *            a {@code Date} object.
 1307        */
 1308       public final void setTime(Date date) {
 1309           setTimeInMillis(date.getTime());
 1310       }
 1311   
 1312       /**
 1313        * Sets the time of this {@code Calendar}.
 1314        * 
 1315        * @param milliseconds
 1316        *            the time as the number of milliseconds since Jan. 1, 1970.
 1317        */
 1318       public void setTimeInMillis(long milliseconds) {
 1319           if (!isTimeSet || !areFieldsSet || time != milliseconds) {
 1320               time = milliseconds;
 1321               isTimeSet = true;
 1322               areFieldsSet = false;
 1323               complete();
 1324           }
 1325       }
 1326   
 1327       /**
 1328        * Sets the {@code TimeZone} used by this Calendar.
 1329        * 
 1330        * @param timezone
 1331        *            a {@code TimeZone}.
 1332        */
 1333       public void setTimeZone(TimeZone timezone) {
 1334           zone = timezone;
 1335           areFieldsSet = false;
 1336       }
 1337   
 1338       /**
 1339        * Returns the string representation of this {@code Calendar}.
 1340        * 
 1341        * @return the string representation of this {@code Calendar}.
 1342        */
 1343       @Override
 1344       @SuppressWarnings("nls")
 1345       public String toString() {
 1346           StringBuilder result = new StringBuilder(getClass().getName() + "[time="
 1347                   + (isTimeSet ? String.valueOf(time) : "?")
 1348                   + ",areFieldsSet="
 1349                   + areFieldsSet
 1350                   + // ",areAllFieldsSet=" + areAllFieldsSet +
 1351                   ",lenient=" + lenient + ",zone=" + zone + ",firstDayOfWeek="
 1352                   + firstDayOfWeek + ",minimalDaysInFirstWeek="
 1353                   + minimalDaysInFirstWeek);
 1354           for (int i = 0; i < FIELD_COUNT; i++) {
 1355               result.append(',');
 1356               result.append(fieldNames[i]);
 1357               result.append('=');
 1358               if (isSet[i]) {
 1359                   result.append(fields[i]);
 1360               } else {
 1361                   result.append('?');
 1362               }
 1363           }
 1364           result.append(']');
 1365           return result.toString();
 1366       }
 1367   
 1368       /**
 1369        * Compares the times of the two {@code Calendar}, which represent the milliseconds
 1370        * from the January 1, 1970 00:00:00.000 GMT (Gregorian).
 1371        * 
 1372        * @param anotherCalendar
 1373        *            another calendar that this one is compared with.
 1374        * @return 0 if the times of the two {@code Calendar}s are equal, -1 if the time of
 1375        *         this {@code Calendar} is before the other one, 1 if the time of this
 1376        *         {@code Calendar} is after the other one.
 1377        * @throws NullPointerException
 1378        *             if the argument is null.
 1379        * @throws IllegalArgumentException
 1380        *             if the argument does not include a valid time
 1381        *             value.
 1382        */
 1383       public int compareTo(Calendar anotherCalendar) {
 1384           if (null == anotherCalendar) {
 1385               throw new NullPointerException();
 1386           }
 1387           long timeInMillis = getTimeInMillis();
 1388           long anotherTimeInMillis = anotherCalendar.getTimeInMillis();
 1389           if (timeInMillis > anotherTimeInMillis) {
 1390               return 1;
 1391           }
 1392           if (timeInMillis == anotherTimeInMillis) {
 1393               return 0;
 1394           }
 1395           return -1;
 1396       }
 1397   
 1398   	/**
 1399   	 * answers the display name for given field, style and locale
 1400   	 * 
 1401   	 * @param field
 1402   	 *            the field of the calendar
 1403   	 * @param style
 1404   	 *            the style of the name
 1405   	 * @param locale
 1406   	 *            the locale to use
 1407   	 * @return the display name
 1408   	 * @since 1.6
 1409   	 */
 1410   	public String getDisplayName(int field, int style, Locale locale) {
 1411   		if (field < 0 || field >= FIELD_COUNT) {
 1412   			throw new IllegalArgumentException();
 1413   		}
 1414   		if (ALL_STYLES == style) {
 1415   			if (!lenient) {
 1416   				throw new IllegalArgumentException();
 1417   			}
 1418   			style = SHORT;
 1419   		}
 1420   		if (SHORT != style && LONG != style) {
 1421   			throw new IllegalArgumentException();
 1422   		}
 1423   		DateFormatSymbols symbol = new DateFormatSymbols(locale);
 1424   		int fid = get(field);
 1425   		switch (field) {
 1426   		case MONTH:
 1427   			return (LONG == style ? symbol.getMonths()[fid] : symbol
 1428   					.getShortMonths()[fid]);
 1429   		case DAY_OF_WEEK:
 1430   			return (LONG == style ? symbol.getWeekdays()[fid] : symbol
 1431   					.getShortWeekdays()[fid]);
 1432   		case AM_PM:
 1433   			return symbol.getAmPmStrings()[fid];
 1434   		case ERA:
 1435   			return symbol.getEras()[fid];
 1436   		default:
 1437   			return null;
 1438   		}
 1439   	}
 1440   
 1441   	/**
 1442   	 * answers a map of display names for given field, style and locale
 1443   	 * 
 1444   	 * @param field
 1445   	 *            the field of the calendar
 1446   	 * @param style
 1447   	 *            the style of the name
 1448   	 * @param locale
 1449   	 *            the locale to use
 1450   	 * @return a map of display names
 1451   	 * @since 1.6
 1452   	 */
 1453   	public Map<String, Integer> getDisplayNames(int field, int style,
 1454   			Locale locale) {
 1455   		if (field < 0 || field >= FIELD_COUNT) {
 1456   			throw new IllegalArgumentException();
 1457   		}
 1458   		if (ALL_STYLES != style && SHORT != style && LONG != style) {
 1459   			throw new IllegalArgumentException();
 1460   		}
 1461   		complete();
 1462   		DateFormatSymbols symbol = new DateFormatSymbols(locale);
 1463   		Map<String, Integer> ret = new HashMap<String, Integer>();
 1464   		switch (field) {
 1465   		case MONTH:
 1466   			String[] months;
 1467   			switch (style) {
 1468   			case LONG:
 1469   				months = symbol.getMonths();
 1470   				break;
 1471   			case SHORT:
 1472   				months = symbol.getShortMonths();
 1473   				break;
 1474   			case ALL_STYLES:
 1475   				months = symbol.getMonths();
 1476   				for (int i = 0; i < months.length; i++) {
 1477   					if (!months[i].equals("") && months[i] != null) {
 1478   						ret.put(months[i], i);
 1479   					}
 1480   				}
 1481   				months = symbol.getShortMonths();
 1482   				break;
 1483   			default:
 1484   				throw new IllegalArgumentException();
 1485   			}
 1486   			for (int i = 0; i < months.length; i++) {
 1487   				if (!months[i].equals("") && months[i] != null) {
 1488   					ret.put(months[i], i);
 1489   				}
 1490   			}
 1491   			break;
 1492   		case DAY_OF_WEEK:
 1493   			String[] weekDays;
 1494   			switch (style) {
 1495   			case LONG:
 1496   				weekDays = symbol.getWeekdays();
 1497   				break;
 1498   			case SHORT:
 1499   				weekDays = symbol.getShortWeekdays();
 1500   				break;
 1501   			case ALL_STYLES:
 1502   				weekDays = symbol.getWeekdays();
 1503   				for (int i = 0; i < weekDays.length; i++) {
 1504   					if (!weekDays[i].equals("") && weekDays[i] != null) {
 1505   						ret.put(weekDays[i], i);
 1506   					}
 1507   				}
 1508   				weekDays = symbol.getWeekdays();
 1509   				break;
 1510   			default:
 1511   				throw new IllegalArgumentException();
 1512   			}
 1513   			for (int i = 0; i < weekDays.length; i++) {
 1514   				if (!weekDays[i].equals("") && weekDays[i] != null) {
 1515   					ret.put(weekDays[i], i);
 1516   				}
 1517   			}
 1518   			break;
 1519   		case AM_PM:
 1520   			String[] amPms = symbol.getAmPmStrings();
 1521   			for (int i = 0; i < amPms.length; i++) {
 1522   				if (!amPms[i].equals("") && amPms[i] != null) {
 1523   					ret.put(amPms[i], i);
 1524   				}
 1525   			}
 1526   			break;
 1527   		case ERA:
 1528   			String[] eras = symbol.getEras();
 1529   			for (int i = 0; i < eras.length; i++) {
 1530   				if (!eras[i].equals("") && eras[i] != null) {
 1531   					ret.put(eras[i], i);
 1532   				}
 1533   			}
 1534   			break;
 1535   		default:
 1536   			ret = null;
 1537   		}
 1538   		return ret;
 1539   	}
 1540   
 1541       private static final ObjectStreamField[] serialPersistentFields = {
 1542               new ObjectStreamField("areFieldsSet", Boolean.TYPE),
 1543               new ObjectStreamField("fields", int[].class),
 1544               new ObjectStreamField("firstDayOfWeek", Integer.TYPE),
 1545               new ObjectStreamField("isSet", boolean[].class),
 1546               new ObjectStreamField("isTimeSet", Boolean.TYPE),
 1547               new ObjectStreamField("lenient", Boolean.TYPE),
 1548               new ObjectStreamField("minimalDaysInFirstWeek", Integer.TYPE),
 1549               new ObjectStreamField("nextStamp", Integer.TYPE),
 1550               new ObjectStreamField("serialVersionOnStream", Integer.TYPE),
 1551               new ObjectStreamField("time", Long.TYPE),
 1552               new ObjectStreamField("zone", TimeZone.class), };
 1553   
 1554       @SuppressWarnings("nls")
 1555       private void writeObject(ObjectOutputStream stream) throws IOException {
 1556           complete();
 1557           ObjectOutputStream.PutField putFields = stream.putFields();
 1558           putFields.put("areFieldsSet", areFieldsSet);
 1559           putFields.put("fields", this.fields);
 1560           putFields.put("firstDayOfWeek", firstDayOfWeek);
 1561           putFields.put("isSet", isSet);
 1562           putFields.put("isTimeSet", isTimeSet);
 1563           putFields.put("lenient", lenient);
 1564           putFields.put("minimalDaysInFirstWeek", minimalDaysInFirstWeek);
 1565           putFields.put("nextStamp", 2 /* MINIMUM_USER_STAMP */);
 1566           putFields.put("serialVersionOnStream", 1);
 1567           putFields.put("time", time);
 1568           putFields.put("zone", zone);
 1569           stream.writeFields();
 1570       }
 1571   
 1572       @SuppressWarnings("nls")
 1573       private void readObject(ObjectInputStream stream) throws IOException,
 1574               ClassNotFoundException {
 1575           ObjectInputStream.GetField readFields = stream.readFields();
 1576           areFieldsSet = readFields.get("areFieldsSet", false);
 1577           this.fields = (int[]) readFields.get("fields", null);
 1578           firstDayOfWeek = readFields.get("firstDayOfWeek", Calendar.SUNDAY);
 1579           isSet = (boolean[]) readFields.get("isSet", null);
 1580           isTimeSet = readFields.get("isTimeSet", false);
 1581           lenient = readFields.get("lenient", true);
 1582           minimalDaysInFirstWeek = readFields.get("minimalDaysInFirstWeek", 1);
 1583           time = readFields.get("time", 0L);
 1584           zone = (TimeZone) readFields.get("zone", null);
 1585       }
 1586   }

Save This Page
Home » apache-harmony-6.0-src-r917296-snapshot » java » util » [javadoc | source]