home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 July & August / Pcwk78a98.iso / Internet / Javadraw / DATA.Z / Calendar.java < prev    next >
Text File  |  1997-08-30  |  35KB  |  1,001 lines

  1. /*
  2.  * @(#)Calendar.java    1.24 97/07/15
  3.  *
  4.  * (C) Copyright Taligent, Inc. 1996-1997 - All Rights Reserved
  5.  * (C) Copyright IBM Corp. 1996-1997 - All Rights Reserved
  6.  *
  7.  * Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
  8.  *
  9.  *   The original version of this source code and documentation is copyrighted
  10.  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
  11.  * materials are provided under terms of a License Agreement between Taligent
  12.  * and Sun. This technology is protected by multiple US and International
  13.  * patents. This notice and attribution to Taligent may not be removed.
  14.  *   Taligent is a registered trademark of Taligent, Inc.
  15.  *
  16.  * Permission to use, copy, modify, and distribute this software
  17.  * and its documentation for NON-COMMERCIAL purposes and without
  18.  * fee is hereby granted provided that this copyright notice
  19.  * appears in all copies. Please refer to the file "copyright.html"
  20.  * for further important copyright and licensing information.
  21.  *
  22.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  23.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  24.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  25.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  26.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  27.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  28.  *
  29.  */
  30.  
  31. package java.util;
  32. import java.io.Serializable;
  33. import java.text.DateFormat;
  34.  
  35. /**
  36.  * <code>Calendar</code> is an abstract base class for converting between
  37.  * a <code>Date</code> object and a set of integer fields such as
  38.  * <code>YEAR</code>, <code>MONTH</code>, <code>DAY</code>, <code>HOUR</code>,
  39.  * and so on. (A <code>Date</code> object represents a specific instant in
  40.  * time with millisecond precision. See
  41.  * <a href="java.util.Date.html"><code>java.util.Date</code></a>
  42.  * for information about the <code>Date</code> class.)
  43.  *
  44.  * <p>
  45.  * Subclasses of <code>Calendar</code> interpret a <code>Date</code>
  46.  * according to the rules of a specific calendar system. The JDK
  47.  * provides one concrete subclass of <code>Calendar</code>:
  48.  * <code>GregorianCalendar</code>. Future subclasses could represent
  49.  * the various types of lunar calendars in use in many parts of the world.
  50.  *
  51.  * <p>
  52.  * Like other locale-sensitive classes, <code>Calendar</code> provides a
  53.  * class method, <code>getInstance</code>, for getting a generally useful
  54.  * object of this type. <code>Calendar</code>'s <code>getInstance</code> method
  55.  * returns a <code>GregorianCalendar</code> object whose
  56.  * time fields have been initialized with the current date and time:
  57.  * <blockquote>
  58.  * <pre>
  59.  * Calendar rightNow = Calendar.getInstance();
  60.  * </pre>
  61.  * </blockquote>
  62.  *
  63.  * <p>
  64.  * A <code>Calendar</code> object can produce all the time field values
  65.  * needed to implement the date-time formatting for a particular language
  66.  * and calendar style (for example, Japanese-Gregorian, Japanese-Traditional).
  67.  *
  68.  * <p>
  69.  * When computing a <code>Date</code> from time fields, two special circumstances
  70.  * may arise: there may be insufficient information to compute the
  71.  * <code>Date</code> (such as only year and month but no day in the month),
  72.  * or there may be inconsistent information (such as "Tuesday, July 15, 1996"
  73.  * -- July 15, 1996 is actually a Monday).
  74.  *
  75.  * <p>
  76.  * <strong>Insufficient information.</strong> The calendar will use default
  77.  * information to specify the missing fields. This may vary by calendar; for
  78.  * the Gregorian calendar, the default for a field is the same as that of the
  79.  * start of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc.
  80.  *
  81.  * <p>
  82.  * <strong>Inconsistent information.</strong> The calendar will give preference
  83.  * to the combinations of fields in the following order (and disregard other
  84.  * inconsistent information).  For the day of the year:
  85.  *
  86.  * <blockquote>
  87.  * <pre>
  88.  * MONTH + DAY_OF_MONTH
  89.  * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
  90.  * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
  91.  * DAY_OF_YEAR
  92.  * DAY_OF_WEEK + WEEK_OF_YEAR
  93.  * </pre>
  94.  * </blockquote>
  95.  * 
  96.  * For the time of day:
  97.  *
  98.  * <blockquote>
  99.  * <pre>
  100.  * HOUR_OF_DAY
  101.  * AM_PM + HOUR
  102.  * </pre>
  103.  * </blockquote>
  104.  *
  105.  * <p>
  106.  * <strong>Note:</strong> for some non-Gregorian calendars, different
  107.  * fields may be necessary for complete disambiguation. For example, a full
  108.  * specification of the historial Arabic astronomical calendar requires year,
  109.  * month, day-of-month <em>and</em> day-of-week in some cases.
  110.  *
  111.  * <p>
  112.  * <strong>Note:</strong> There are certain possible ambiguities in
  113.  * interpretation of certain singular times, which are resolved in the
  114.  * following ways:
  115.  * <ol>
  116.  *     <li> 24:00:00 "belongs" to the following day. That is,
  117.  *          23:59 on Dec 31, 1969 < 24:00 on Jan 1, 1970 < 24:01:00 on Jan 1, 1970
  118.  *
  119.  *     <li> Although historically not precise, midnight also belongs to "am",
  120.  *          and noon belongs to "pm", so on the same day,
  121.  *          12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm
  122.  * </ol>
  123.  *
  124.  * <p>
  125.  * The date or time format strings are not part of the definition of a
  126.  * calendar, as those must be modifiable or overridable by the user at
  127.  * runtime. Use <a href="java.text.DateFormat.html">java.text.DateFormat</a>
  128.  * to format dates.
  129.  *
  130.  * <p>
  131.  * <code>Calendar</code> provides an API for field "rolling", where fields
  132.  * can be incremented or decremented, but wrap around. For example, rolling the
  133.  * month up in the date "September 12, 1996" results in "October 12, 1996".
  134.  *
  135.  * <p>
  136.  * <code>Calendar</code> also provides a date arithmetic function for 
  137.  * adding the specified (signed) amount of time to a particular time field.
  138.  * For example, subtracting 5 days from the date "September 12, 1996" results
  139.  * in "September 7, 1996".
  140.  *
  141.  * @see          Date
  142.  * @see          GregorianCalendar
  143.  * @see          TimeZone
  144.  * @see          java.text.DateFormat
  145.  * @version      1.17 06 Jan 1997
  146.  * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu
  147.  */
  148. public abstract class Calendar implements Serializable, Cloneable {
  149.  
  150.     // Data flow in Calendar
  151.     // ---------------------
  152.     
  153.     // The current time is represented in two ways by Calendar: as UTC
  154.     // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local
  155.     // fields such as MONTH, HOUR, AM_PM, etc.  It is possible to compute the
  156.     // millis from the fields, and vice versa.  The data needed to do this
  157.     // conversion is encapsulated by a TimeZone object owned by the Calendar.
  158.     // The data provided by the TimeZone object may also be overridden if the
  159.     // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
  160.     // keeps track of what information was most recently set by the caller, and
  161.     // uses that to compute any other information as needed.
  162.  
  163.     // If the user sets the fields using set(), the data flow is as follows.
  164.     // This is implemented by the Calendar subclass's computeTime() method.
  165.     // During this process, certain fields may be ignored.  The disambiguation
  166.     // algorithm for resolving which fields to pay attention to is described
  167.     // above.
  168.  
  169.     //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
  170.     //           |
  171.     //           | Using Calendar-specific algorithm
  172.     //           V
  173.     //   local standard millis
  174.     //           |
  175.     //           | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
  176.     //           V
  177.     //   UTC millis (in time data member)
  178.  
  179.     // If the user sets the UTC millis using setTime(), the data flow is as
  180.     // follows.  This is implemented by the Calendar subclass's computeFields()
  181.     // method.
  182.  
  183.     //   UTC millis (in time data member)
  184.     //           |
  185.     //           | Using TimeZone getOffset()
  186.     //           V
  187.     //   local standard millis
  188.     //           |
  189.     //           | Using Calendar-specific algorithm
  190.     //           V
  191.     //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
  192.  
  193.     // In general, a round trip from fields, through local and UTC millis, and
  194.     // back out to fields is made when necessary.  This is implemented by the
  195.     // complete() method.  Resolving a partial set of fields into a UTC millis
  196.     // value allows all remaining fields to be generated from that value.  If
  197.     // the Calendar is lenient, the fields are also renormalized to standard
  198.     // ranges when they are regenerated.
  199.  
  200.     /**
  201.      * Useful constant for date and time. Used in time fields.
  202.      * ERA is calendar specific.
  203.      */
  204.     public final static int ERA = 0;
  205.     /**
  206.      * Useful constant for date and time. Used in time fields.
  207.      */
  208.     public final static int YEAR = 1;
  209.     /**
  210.      * Useful constant for date and time. Used in time fields.
  211.      */
  212.     public final static int MONTH = 2;
  213.     /**
  214.      * Useful constant for date and time. Used in time fields.
  215.      */
  216.     public final static int WEEK_OF_YEAR = 3;
  217.     /**
  218.      * Useful constant for date and time. Used in time fields.
  219.      */
  220.     public final static int WEEK_OF_MONTH = 4;
  221.     /**
  222.      * Useful constant for date and time. Used in time fields.
  223.      * This is a synonym for DAY_OF_MONTH.
  224.      */
  225.     public final static int DATE = 5;
  226.     /**
  227.      * Useful constant for date and time. Used in time fields.
  228.      * This is a synonym for DATE.
  229.      */
  230.     public final static int DAY_OF_MONTH = 5;
  231.     /**
  232.      * Useful constant for date and time. Used in time fields.
  233.      */
  234.     public final static int DAY_OF_YEAR = 6;
  235.     /**
  236.      * Useful constant for date and time. Used in time fields.
  237.      */
  238.     public final static int DAY_OF_WEEK = 7;
  239.     /**
  240.      * Useful constant for date and time. Used in time fields.
  241.      */
  242.     public final static int DAY_OF_WEEK_IN_MONTH = 8;
  243.     /**
  244.      * Useful constant for date and time. Used in time fields.
  245.      */
  246.     public final static int AM_PM = 9;
  247.     /**
  248.      * Useful constant for date and time. Used in time fields.
  249.      * HOUR is used for the 12-hour clock.
  250.      */
  251.     public final static int HOUR = 10;
  252.     /**
  253.      * Useful constant for date and time. Used in time fields.
  254.      * HOUR_OF_DAY is used for the 24-hour clock.
  255.      */
  256.     public final static int HOUR_OF_DAY = 11;
  257.     /**
  258.      * Useful constant for date and time. Used in time fields.
  259.      */
  260.     public final static int MINUTE = 12;
  261.     /**
  262.      * Useful constant for date and time. Used in time fields.
  263.      */
  264.     public final static int SECOND = 13;
  265.     /**
  266.      * Useful constant for date and time. Used in time fields.
  267.      */
  268.     public final static int MILLISECOND = 14;
  269.     /**
  270.      * Useful constant for date and time. Used in time fields.
  271.      */
  272.     public final static int ZONE_OFFSET = 15;
  273.     /**
  274.      * Useful constant for date and time. Used in time fields.
  275.      */
  276.     public final static int DST_OFFSET = 16;
  277.     /**
  278.      * Useful constant for date and time.
  279.      * FIELD_COUNT is used for the time field array creation.
  280.      */
  281.     public final static int FIELD_COUNT = 17;
  282.  
  283.     /**
  284.      * Useful constant for days of week. Used in GregorianCalendar.
  285.      */
  286.     public final static int SUNDAY = 1;
  287.     /**
  288.      * Useful constant for days of week. Used in GregorianCalendar.
  289.      */
  290.     public final static int MONDAY = 2;
  291.     /**
  292.      * Useful constant for days of week. Used in GregorianCalendar.
  293.      */
  294.     public final static int TUESDAY = 3;
  295.     /**
  296.      * Useful constant for days of week. Used in GregorianCalendar.
  297.      */
  298.     public final static int WEDNESDAY = 4;
  299.     /**
  300.      * Useful constant for days of week. Used in GregorianCalendar.
  301.      */
  302.     public final static int THURSDAY = 5;
  303.     /**
  304.      * Useful constant for days of week. Used in GregorianCalendar.
  305.      */
  306.     public final static int FRIDAY = 6;
  307.     /**
  308.      * Useful constant for days of week. Used in GregorianCalendar.
  309.      */
  310.     public final static int SATURDAY = 7;
  311.     /**
  312.      * Useful constant for month. Used in GregorianCalendar.
  313.      * Note: Calendar month is now 0-based.
  314.      */
  315.     public final static int JANUARY = 0;
  316.     /**
  317.      * Useful constant for month. Used in GregorianCalendar.
  318.      */
  319.     public final static int FEBRUARY = 1;
  320.     /**
  321.      * Useful constant for month. Used in GregorianCalendar.
  322.      */
  323.     public final static int MARCH = 2;
  324.     /**
  325.      * Useful constant for month. Used in GregorianCalendar.
  326.      */
  327.     public final static int APRIL = 3;
  328.     /**
  329.      * Useful constant for month. Used in GregorianCalendar.
  330.      */
  331.     public final static int MAY = 4;
  332.     /**
  333.      * Useful constant for month. Used in GregorianCalendar.
  334.      */
  335.     public final static int JUNE = 5;
  336.     /**
  337.      * Useful constant for month. Used in GregorianCalendar.
  338.      */
  339.     public final static int JULY = 6;
  340.     /**
  341.      * Useful constant for month. Used in GregorianCalendar.
  342.      */
  343.     public final static int AUGUST = 7;
  344.     /**
  345.      * Useful constant for month. Used in GregorianCalendar.
  346.      */
  347.     public final static int SEPTEMBER = 8;
  348.     /**
  349.      * Useful constant for month. Used in GregorianCalendar.
  350.      */
  351.     public final static int OCTOBER = 9;
  352.     /**
  353.      * Useful constant for month. Used in GregorianCalendar.
  354.      */
  355.     public final static int NOVEMBER = 10;
  356.     /**
  357.      * Useful constant for month. Used in GregorianCalendar.
  358.      */
  359.     public final static int DECEMBER = 11;
  360.     /**
  361.      * Useful constant for month. Used in GregorianCalendar.
  362.      * UNDECIMBER is an artifical name. This 13th month is for lunar
  363.      * calendars.
  364.      */
  365.     public final static int UNDECIMBER = 12;
  366.     /**
  367.      * Useful constant for hour in 12-hour clock. Used in GregorianCalendar.
  368.      */
  369.     public final static int AM = 0;
  370.     /**
  371.      * Useful constant for hour in 12-hour clock. Used in GregorianCalendar.
  372.      */
  373.     public final static int PM = 1;
  374.  
  375.     // Internal notes:
  376.     // Calendar contains two kinds of time representations: current "time" in
  377.     // milliseconds, and a set of time "fields" representing the current time.
  378.     // The two representations are usually in sync, but can get out of sync
  379.     // as follows.
  380.     // 1. Initially, no fields are set, and the time is invalid.
  381.     // 2. If the time is set, all fields are computed and in sync.
  382.     // 3. If a single field is set, the time is invalid.
  383.     // Recomputation of the time and fields happens when the object needs
  384.     // to return a result to the user, or use a result for a computation.
  385.  
  386.     /**
  387.      * The time fields containing values into which the millis is computed.
  388.      */
  389.     protected int           fields[];
  390.     /**
  391.      * The flags which tell if a specified time field for the calendar is set.
  392.      * A new object has no fields set.  After the first call to a method
  393.      * which generates the fields, they all remain set after that.
  394.      */
  395.     protected boolean       isSet[];
  396.  
  397.     /**
  398.      * True if the ZONE_OFFSET field was set by the user.  Meaningless if isSet[ZONE_OFFSET]
  399.      * is false.
  400.      *
  401.      * NOTE: MAKE PROTECTED AT NEXT API CHANGE, or ADD ACCESSOR METHODS.
  402.      */
  403.     transient boolean                 userSetZoneOffset;
  404.  
  405.     /**
  406.      * True if the DST_OFFSET field was set by the user.  Meaningless if isSet[ZONE_OFFSET]
  407.      * is false.
  408.      *
  409.      * NOTE: MAKE PROTECTED AT NEXT API CHANGE, or ADD ACCESSOR METHODS.
  410.      */
  411.     transient boolean                 userSetDSTOffset;
  412.  
  413.     /**
  414.      * The current time set for the calendar.
  415.      */
  416.     protected long          time;
  417.  
  418.     /**
  419.      * The flag which indicates if the current time is set for the calendar.
  420.      * The time is made invalid by the user setting an individual field.
  421.      */
  422.     protected boolean       isTimeSet;
  423.  
  424.     /**
  425.      * True if the fields are in sync with the currently set time of this Calendar.
  426.      * If false, then the next attempt to get the value of a field will
  427.      * force a recomputation of all fields from the current value of the time
  428.      * field.
  429.      *
  430.      * This should really be named areFieldsInSync, but the old name is retained
  431.      * for backward compatibility.
  432.      */
  433.     protected boolean       areFieldsSet;
  434.  
  435.     /**
  436.      * True if all fields have been set.
  437.      *
  438.      * NOTE: MAKE PROTECTED AT NEXT API CHANGE, or ADD ACCESSOR METHODS.
  439.      */
  440.     transient boolean                 areAllFieldsSet;
  441.  
  442.     /**
  443.      * @see #setLenient
  444.      */
  445.     private   boolean       lenient=true;
  446.  
  447.     /**
  448.      * Time zone affects the time calculation done by Calendar. Calendar uses
  449.      * the time zone data to produce the local time. Both firstDayOfWeek
  450.      * and minimalDaysInFirstWeek are locale-dependent. For example,
  451.      * in US locale, firstDayOfWeek is SUNDAY; minimalDaysInFirstWeek is 1.
  452.      * They are used to figure out the week count for a specific date for
  453.      * a given locale. These must be set when a Calendar is constructed.
  454.      */
  455.     private   TimeZone      zone;
  456.     private   int           firstDayOfWeek;
  457.     private   int           minimalDaysInFirstWeek;
  458.  
  459.     /**
  460.      * Constructs a Calendar with the default time zone as returned
  461.      * by TimeZone.getDefault(), and the default locale.
  462.      * @see     TimeZone#getDefault
  463.      */
  464.     protected Calendar()
  465.     {
  466.     this(TimeZone.getDefault(), Locale.getDefault());
  467.     }
  468.  
  469.     /**
  470.      * Constructs a Calendar with the given time zone and locale.
  471.      * @param zone the given time zone.
  472.      */
  473.     protected Calendar(TimeZone zone, Locale aLocale)
  474.     {
  475.         fields = new int[FIELD_COUNT];
  476.         isSet = new boolean[FIELD_COUNT];
  477.         userSetZoneOffset = false;
  478.         userSetDSTOffset = false;
  479.  
  480.         this.zone = zone;
  481.         setWeekCountData(aLocale);
  482.     }
  483.  
  484.     /**
  485.      * Gets a Calendar using the default timezone and locale.
  486.      * @return a Calendar.
  487.      */
  488.     public static synchronized Calendar getInstance()
  489.     {
  490.         return new GregorianCalendar();
  491.     }
  492.  
  493.     /**
  494.      * Gets a Calendar using the given timezone and default locale.
  495.      * @param zone the given timezone.
  496.      * @return a Calendar.
  497.      */
  498.     public static synchronized Calendar getInstance(TimeZone zone)
  499.     {
  500.         return new GregorianCalendar(zone, Locale.getDefault());
  501.     }
  502.  
  503.     /**
  504.      * Gets a Calendar using the default timezone and given locale.
  505.      * @param aLocale the given locale.
  506.      * @return a Calendar.
  507.      */
  508.     public static synchronized Calendar getInstance(Locale aLocale)
  509.     {
  510.         return new GregorianCalendar(TimeZone.getDefault(), aLocale);
  511.     }
  512.  
  513.     /**
  514.      * Gets a Calendar using the given timezone and given locale.
  515.      * @param zone the given timezone.
  516.      * @param aLocale the given locale.
  517.      * @return a Calendar.
  518.      */
  519.     public static synchronized Calendar getInstance(TimeZone zone,
  520.                                                    Locale aLocale)
  521.     {
  522.         return new GregorianCalendar(zone, aLocale);
  523.     }
  524.  
  525.     /**
  526.      * Gets the set of locales for which Calendars are installed.
  527.      * @return the set of locales for which Calendars are installed.
  528.      */
  529.     public static synchronized Locale[] getAvailableLocales()
  530.     {
  531.         return DateFormat.getAvailableLocales();
  532.     }
  533.  
  534.     /**
  535.      * Converts Calendar's time field values to UTC as milliseconds.
  536.      */
  537.     protected abstract void computeTime();
  538.  
  539.     /**
  540.      * Converts UTC as milliseconds to time field values.
  541.      * This allows you to sync up the time field values with
  542.      * a new time that is set for the calendar.  The time is <em>not</em>
  543.      * recomputed first; to recompute the time, then the fields, call the
  544.      * <code>complete</code> method.
  545.      * @see #complete
  546.      */
  547.     protected abstract void computeFields();
  548.  
  549.     /**
  550.      * Gets this Calendar's current time.
  551.      * @return the current time.
  552.      */
  553.     public final Date getTime() {
  554.         return new Date( getTimeInMillis() );
  555.     }
  556.  
  557.     /**
  558.      * Sets this Calendar's current time with the given Date.
  559.      * @param date the given Date.
  560.      */
  561.     public final void setTime(Date date) {
  562.         setTimeInMillis( date.getTime() );
  563.     }
  564.  
  565.     /**
  566.      * Gets this Calendar's current time as a long.
  567.      * @return the current time as UTC milliseconds from the epoch.
  568.      */
  569.     protected long getTimeInMillis() {
  570.         if (!isTimeSet) computeTime();
  571.             return time;
  572.     }
  573.  
  574.     /**
  575.      * Sets this Calendar's current time from the given long value.
  576.      * @param date the new time in UTC milliseconds from the epoch.
  577.      */
  578.     protected void setTimeInMillis( long millis ) {
  579.         isTimeSet = true;
  580.         time = millis;
  581.         areFieldsSet = false;
  582.         computeFields();
  583.     }
  584.  
  585.  
  586.     /**
  587.      * Gets the value for a given time field.
  588.      * @param field the given time field.
  589.      * @return the value for the given time field.
  590.      */
  591.     public final int get(int field)
  592.     {
  593.         complete();
  594.         return fields[field];
  595.     }
  596.  
  597.     /**
  598.      * Gets the value for a given time field. This is an internal
  599.      * fast time field value getter for the subclasses.
  600.      * @param field the given time field.
  601.      * @return the value for the given time field.
  602.      */
  603.     protected final int internalGet(int field)
  604.     {
  605.         return fields[field];
  606.     }
  607.  
  608.     /**
  609.      * Sets the value for the given time field.  This is an internal
  610.      * fast setter for subclasses.  It does not affect the areFieldsSet, isTimeSet,
  611.      * or areAllFieldsSet flags.  <strong>Note:</strong> The caller is responsible
  612.      * for setting the userSetZoneOffset and userSetDSTOffset flags to false if
  613.      * the caller modifies ZONE_OFFSET or DST_OFFSET using this method.
  614.      */
  615.     final void internalSet(int field, int value)
  616.     {
  617.         fields[field] = value;
  618.         // We track if the user set the zone and DST offsets to know if we should use these
  619.         // to override the TimeZone object.
  620.         // THE CALLER IS RESPONSIBLE FOR DOING THIS NOW:
  621.         // switch (field)
  622.         // {
  623.         // case ZONE_OFFSET:
  624.         //     userSetZoneOffset = false;
  625.         //     break;
  626.         // case DST_OFFSET:
  627.         //     userSetDSTOffset = false;
  628.         //     break;
  629.         // default:
  630.         //     break;
  631.         // }
  632.     }
  633.  
  634.     /**
  635.      * Sets the time field with the given value.
  636.      * @param field the given time field.
  637.      * @param value the value to be set for the given time field.
  638.      */
  639.     public final void set(int field, int value)
  640.     {
  641.         isTimeSet = false;
  642.         fields[field] = value;
  643.         isSet[field] = true;
  644.         areFieldsSet = false;
  645.         // We track if the user set the zone and DST offsets to know if we should use these
  646.         // to override the TimeZone object.
  647.         switch (field)
  648.         {
  649.         case ZONE_OFFSET:
  650.             userSetZoneOffset = true;
  651.             break;
  652.         case DST_OFFSET:
  653.             userSetDSTOffset = true;
  654.             break;
  655.         default:
  656.             break;
  657.         }
  658.     }
  659.  
  660.     /**
  661.      * Sets the values for the fields year, month, and date.
  662.      * Previous values of other fields are retained.  If this is not desired,
  663.      * call <code>clear</code> first.
  664.      * @param year the value used to set the YEAR time field.
  665.      * @param month the value used to set the MONTH time field.
  666.      * Month value is 0-based. e.g., 0 for January.
  667.      * @param date the value used to set the DATE time field.
  668.      */
  669.     public final void set(int year, int month, int date)
  670.     {
  671.         set(YEAR, year);
  672.         set(MONTH, month);
  673.         set(DATE, date);
  674.     }
  675.  
  676.     /**
  677.      * Sets the values for the fields year, month, date, hour, and minute.
  678.      * Previous values of other fields are retained.  If this is not desired,
  679.      * call <code>clear</code> first.
  680.      * @param year the value used to set the YEAR time field.
  681.      * @param month the value used to set the MONTH time field.
  682.      * Month value is 0-based. e.g., 0 for January.
  683.      * @param date the value used to set the DATE time field.
  684.      * @param hour the value used to set the HOUR_OF_DAY time field.
  685.      * @param minute the value used to set the MINUTE time field.
  686.      */
  687.     public final void set(int year, int month, int date, int hour, int minute)
  688.     {
  689.         set(YEAR, year);
  690.         set(MONTH, month);
  691.         set(DATE, date);
  692.         set(HOUR_OF_DAY, hour);
  693.         set(MINUTE, minute);
  694.     }
  695.  
  696.     /**
  697.      * Sets the values for the fields year, month, date, hour, minute, and second.
  698.      * Previous values of other fields are retained.  If this is not desired,
  699.      * call <code>clear</code> first.
  700.      * @param year the value used to set the YEAR time field.
  701.      * @param month the value used to set the MONTH time field.
  702.      * Month value is 0-based. e.g., 0 for January.
  703.      * @param date the value used to set the DATE time field.
  704.      * @param hour the value used to set the HOUR_OF_DAY time field.
  705.      * @param minute the value used to set the MINUTE time field.
  706.      * @param second the value used to set the SECOND time field.
  707.      */
  708.     public final void set(int year, int month, int date, int hour, int minute,
  709.                           int second)
  710.     {
  711.         set(YEAR, year);
  712.         set(MONTH, month);
  713.         set(DATE, date);
  714.         set(HOUR_OF_DAY, hour);
  715.         set(MINUTE, minute);
  716.         set(SECOND, second);
  717.     }
  718.  
  719.     /**
  720.      * Clears the values of all the time fields.
  721.      */
  722.     public final void clear()
  723.     {
  724.         isSet = new boolean[FIELD_COUNT];
  725.         fields = new int[FIELD_COUNT];
  726.         userSetZoneOffset = false;
  727.         userSetDSTOffset = false;
  728.         areFieldsSet = false;
  729.         areAllFieldsSet = false;
  730.     }
  731.  
  732.     /**
  733.      * Clears the value in the given time field.
  734.      * @param field the time field to be cleared.
  735.      */
  736.     public final void clear(int field)
  737.     {
  738.         isSet[field] = false;
  739.         fields[field] = 0;
  740.         areFieldsSet = false;
  741.         areAllFieldsSet = false;
  742.         // We track if the user set the zone and DST offsets to know if we should use these
  743.         // to override the TimeZone object.
  744.         switch (field)
  745.         {
  746.         case ZONE_OFFSET:
  747.             userSetZoneOffset = false;
  748.             break;
  749.         case DST_OFFSET:
  750.             userSetDSTOffset = false;
  751.             break;
  752.         default:
  753.             break;
  754.         }
  755.     }
  756.  
  757.     /**
  758.      * Determines if the given time field has a value set.
  759.      * @return true if the given time field has a value set; false otherwise.
  760.      */
  761.     public final boolean isSet(int field)
  762.     {
  763.         return isSet[field];
  764.     }
  765.  
  766.     /**
  767.      * Fills in any unset fields in the time field list.
  768.      */
  769.     protected void complete()
  770.     {
  771.         if (!isTimeSet)
  772.             computeTime();  // computes time from incomplete fields
  773.         if (!areFieldsSet)
  774.             computeFields();// fills in unset fields
  775.     }
  776.  
  777.     /**
  778.      * Compares the time field records.
  779.      * Equivalent to comparing result of conversion to UTC.
  780.      * @param when the Calendar to be compared with this Calendar.
  781.      * @return true if the current time of this Calendar is equal
  782.      * to the time of Calendar when; false otherwise.
  783.      */
  784.     abstract public boolean equals(Object when);
  785.  
  786.     /**
  787.      * Compares the time field records.
  788.      * Equivalent to comparing result of conversion to UTC.
  789.      * @param when the Calendar to be compared with this Calendar.
  790.      * @return true if the current time of this Calendar is before
  791.      * the time of Calendar when; false otherwise.
  792.      */
  793.     abstract public boolean before(Object when);
  794.  
  795.     /**
  796.      * Compares the time field records.
  797.      * Equivalent to comparing result of conversion to UTC.
  798.      * @param when the Calendar to be compared with this Calendar.
  799.      * @return true if the current time of this Calendar is after
  800.      * the time of Calendar when; false otherwise.
  801.      */
  802.     abstract public boolean after(Object when);
  803.  
  804.     /**
  805.      * Date Arithmetic function.
  806.      * Adds the specified (signed) amount of time to the given time field,
  807.      * based on the calendar's rules. For example, to subtract 5 days from
  808.      * the current time of the calendar, you can achieve it by calling:
  809.      * <p>add(Calendar.DATE, -5).
  810.      * @param field the time field.
  811.      * @param amount the amount of date or time to be added to the field.
  812.      */
  813.     abstract public void add(int field, int amount);
  814.  
  815.     /**
  816.      * Time Field Rolling function.
  817.      * Rolls (up/down) a single unit of time on the given time field. For
  818.      * example, to roll the current date up by one day, you can achieve it
  819.      * by calling:
  820.      * <p>roll(Calendar.DATE, true).
  821.      * When rolling on the year or Calendar.YEAR field, it will roll the year
  822.      * value in the range between 1 and the value returned by calling
  823.      * getMaximum(Calendar.YEAR).
  824.      * When rolling on the month or Calendar.MONTH field, other fields like
  825.      * date might conflict and, need to be changed. For instance,
  826.      * rolling the month on the date 01/31/96 will result in 03/02/96.
  827.      * When rolling on the hour-in-day or Calendar.HOUR_OF_DAY field, it will
  828.      * roll the hour value in the range between 0 and 23, which is zero-based.
  829.      * @param field the time field.
  830.      * @param up indicates if the value of the specified time field is to be
  831.      * rolled up or rolled down. Use true if rolling up, false otherwise.
  832.      */
  833.     abstract public void roll(int field, boolean up);
  834.  
  835.     /**
  836.      * Sets the time zone with the given time zone value.
  837.      * @param value the given time zone.
  838.      */
  839.     public void setTimeZone(TimeZone value)
  840.     {
  841.         zone = value;
  842.     }
  843.  
  844.     /**
  845.      * Gets the time zone.
  846.      * @return the time zone object associated with this calendar.
  847.      */
  848.     public TimeZone getTimeZone()
  849.     {
  850.         return zone;
  851.     }
  852.  
  853.     /**
  854.      * Specify whether or not date/time interpretation is to be lenient.  With
  855.      * lenient interpretation, a date such as "February 942, 1996" will be
  856.      * treated as being equivalent to the 941st day after February 1, 1996.
  857.      * With strict interpretation, such dates will cause an exception to be
  858.      * thrown.
  859.      *
  860.      * @see java.text.DateFormat#setLenient
  861.      */
  862.     public void setLenient(boolean lenient)
  863.     {
  864.         this.lenient = lenient;
  865.     }
  866.  
  867.     /**
  868.      * Tell whether date/time interpretation is to be lenient.
  869.      */
  870.     public boolean isLenient()
  871.     {
  872.         return lenient;
  873.     }
  874.  
  875.     /**
  876.      * Sets what the first day of the week is; e.g., Sunday in US,
  877.      * Monday in France.
  878.      * @param value the given first day of the week.
  879.      */
  880.     public void setFirstDayOfWeek(int value)
  881.     {
  882.         firstDayOfWeek = value;
  883.     }
  884.  
  885.     /**
  886.      * Gets what the first day of the week is; e.g., Sunday in US,
  887.      * Monday in France.
  888.      * @return the first day of the week.
  889.      */
  890.     public int getFirstDayOfWeek()
  891.     {
  892.         return firstDayOfWeek;
  893.     }
  894.  
  895.     /**
  896.      * Sets what the minimal days required in the first week of the year are;
  897.      * For example, if the first week is defined as one that contains the first
  898.      * day of the first month of a year, call the method with value 1. If it
  899.      * must be a full week, use value 7.
  900.      * @param value the given minimal days required in the first week
  901.      * of the year.
  902.      */
  903.     public void setMinimalDaysInFirstWeek(int value)
  904.     {
  905.         minimalDaysInFirstWeek = value;
  906.     }
  907.  
  908.     /**
  909.      * Gets what the minimal days required in the first week of the year are;
  910.      * e.g., if the first week is defined as one that contains the first day
  911.      * of the first month of a year, getMinimalDaysInFirstWeek returns 1. If
  912.      * the minimal days required must be a full week, getMinimalDaysInFirstWeek
  913.      * returns 7.
  914.      * @return the minimal days required in the first week of the year.
  915.      */
  916.     public int getMinimalDaysInFirstWeek()
  917.     {
  918.         return minimalDaysInFirstWeek;
  919.     }
  920.  
  921.     /**
  922.      * Gets the minimum value for the given time field.
  923.      * e.g., for Gregorian DAY_OF_MONTH, 1.
  924.      * @param field the given time field.
  925.      * @return the minimum value for the given time field.
  926.      */
  927.     abstract public int getMinimum(int field);
  928.  
  929.     /**
  930.      * Gets the maximum value for the given time field.
  931.      * e.g. for Gregorian DAY_OF_MONTH, 31.
  932.      * @param field the given time field.
  933.      * @return the maximum value for the given time field.
  934.      */
  935.     abstract public int getMaximum(int field);
  936.  
  937.     /**
  938.      * Gets the highest minimum value for the given field if varies.
  939.      * Otherwise same as getMinimum(). For Gregorian, no difference.
  940.      * @param field the given time field.
  941.      * @return the highest minimum value for the given time field.
  942.      */
  943.     abstract public int getGreatestMinimum(int field);
  944.  
  945.     /**
  946.      * Gets the lowest maximum value for the given field if varies.
  947.      * Otherwise same as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28.
  948.      * @param field the given time field.
  949.      * @return the lowest maximum value for the given time field.
  950.      */
  951.     abstract public int getLeastMaximum(int field);
  952.  
  953.     /**
  954.      * Overrides Cloneable
  955.      */
  956.     public Object clone()
  957.     {
  958.         try
  959.         {
  960.             Calendar other = (Calendar) super.clone();
  961.  
  962.             other.fields = new int[FIELD_COUNT];
  963.             other.isSet = new boolean[FIELD_COUNT];
  964.             System.arraycopy(this.fields, 0, other.fields, 0, FIELD_COUNT);
  965.             System.arraycopy(this.isSet, 0, other.isSet, 0, FIELD_COUNT);
  966.  
  967.             other.zone = (TimeZone) zone.clone();
  968.             return other;
  969.         }
  970.         catch (CloneNotSupportedException e)
  971.         {
  972.             // this shouldn't happen, since we are Cloneable
  973.             throw new InternalError();
  974.         }
  975.     }
  976.  
  977.  
  978.     // =======================privates===============================
  979.  
  980.     /**
  981.      * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent.
  982.      * They are used to figure out the week count for a specific date for
  983.      * a given locale. These must be set when a Calendar is constructed.
  984.      * @param desiredLocale the given locale.
  985.      */
  986.     private void setWeekCountData(Locale desiredLocale)
  987.     {
  988.         ResourceBundle resource
  989.             = ResourceBundle.getBundle("java.text.resources.LocaleElements",
  990.                                                desiredLocale);
  991.         String[] dateTimePatterns
  992.         = resource.getStringArray("DateTimeElements");
  993.  
  994.         firstDayOfWeek = Integer.parseInt(dateTimePatterns[0]);
  995.         minimalDaysInFirstWeek = Integer.parseInt(dateTimePatterns[1]);
  996.     }
  997.  
  998.     // Proclaim serialization compatibility with JDK 1.1
  999.     static final long serialVersionUID = -1807547505821590642L;
  1000. }
  1001.