0001: /*
0002: * Copyright 1996-2007 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025:
0026: /*
0027: * (C) Copyright Taligent, Inc. 1996-1998 - All Rights Reserved
0028: * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved
0029: *
0030: * The original version of this source code and documentation is copyrighted
0031: * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
0032: * materials are provided under terms of a License Agreement between Taligent
0033: * and Sun. This technology is protected by multiple US and International
0034: * patents. This notice and attribution to Taligent may not be removed.
0035: * Taligent is a registered trademark of Taligent, Inc.
0036: *
0037: */
0038:
0039: package java.util;
0040:
0041: import java.io.IOException;
0042: import java.io.ObjectInputStream;
0043: import java.io.ObjectOutputStream;
0044: import java.io.Serializable;
0045: import java.security.AccessController;
0046: import java.security.PrivilegedExceptionAction;
0047: import java.text.DateFormat;
0048: import java.text.DateFormatSymbols;
0049: import sun.util.BuddhistCalendar;
0050: import sun.util.calendar.ZoneInfo;
0051: import sun.util.resources.LocaleData;
0052:
0053: /**
0054: * The <code>Calendar</code> class is an abstract class that provides methods
0055: * for converting between a specific instant in time and a set of {@link
0056: * #fields calendar fields} such as <code>YEAR</code>, <code>MONTH</code>,
0057: * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, and so on, and for
0058: * manipulating the calendar fields, such as getting the date of the next
0059: * week. An instant in time can be represented by a millisecond value that is
0060: * an offset from the <a name="Epoch"><em>Epoch</em></a>, January 1, 1970
0061: * 00:00:00.000 GMT (Gregorian).
0062: *
0063: * <p>The class also provides additional fields and methods for
0064: * implementing a concrete calendar system outside the package. Those
0065: * fields and methods are defined as <code>protected</code>.
0066: *
0067: * <p>
0068: * Like other locale-sensitive classes, <code>Calendar</code> provides a
0069: * class method, <code>getInstance</code>, for getting a generally useful
0070: * object of this type. <code>Calendar</code>'s <code>getInstance</code> method
0071: * returns a <code>Calendar</code> object whose
0072: * calendar fields have been initialized with the current date and time:
0073: * <blockquote>
0074: * <pre>
0075: * Calendar rightNow = Calendar.getInstance();
0076: * </pre>
0077: * </blockquote>
0078: *
0079: * <p>A <code>Calendar</code> object can produce all the calendar field values
0080: * needed to implement the date-time formatting for a particular language and
0081: * calendar style (for example, Japanese-Gregorian, Japanese-Traditional).
0082: * <code>Calendar</code> defines the range of values returned by
0083: * certain calendar fields, as well as their meaning. For example,
0084: * the first month of the calendar system has value <code>MONTH ==
0085: * JANUARY</code> for all calendars. Other values are defined by the
0086: * concrete subclass, such as <code>ERA</code>. See individual field
0087: * documentation and subclass documentation for details.
0088: *
0089: * <h4>Getting and Setting Calendar Field Values</h4>
0090: *
0091: * <p>The calendar field values can be set by calling the <code>set</code>
0092: * methods. Any field values set in a <code>Calendar</code> will not be
0093: * interpreted until it needs to calculate its time value (milliseconds from
0094: * the Epoch) or values of the calendar fields. Calling the
0095: * <code>get</code>, <code>getTimeInMillis</code>, <code>getTime</code>,
0096: * <code>add</code> and <code>roll</code> involves such calculation.
0097: *
0098: * <h4>Leniency</h4>
0099: *
0100: * <p><code>Calendar</code> has two modes for interpreting the calendar
0101: * fields, <em>lenient</em> and <em>non-lenient</em>. When a
0102: * <code>Calendar</code> is in lenient mode, it accepts a wider range of
0103: * calendar field values than it produces. When a <code>Calendar</code>
0104: * recomputes calendar field values for return by <code>get()</code>, all of
0105: * the calendar fields are normalized. For example, a lenient
0106: * <code>GregorianCalendar</code> interprets <code>MONTH == JANUARY</code>,
0107: * <code>DAY_OF_MONTH == 32</code> as February 1.
0108:
0109: * <p>When a <code>Calendar</code> is in non-lenient mode, it throws an
0110: * exception if there is any inconsistency in its calendar fields. For
0111: * example, a <code>GregorianCalendar</code> always produces
0112: * <code>DAY_OF_MONTH</code> values between 1 and the length of the month. A
0113: * non-lenient <code>GregorianCalendar</code> throws an exception upon
0114: * calculating its time or calendar field values if any out-of-range field
0115: * value has been set.
0116: *
0117: * <h4>First Week</h4>
0118: *
0119: * <code>Calendar</code> defines a locale-specific seven day week using two
0120: * parameters: the first day of the week and the minimal days in first week
0121: * (from 1 to 7). These numbers are taken from the locale resource data when a
0122: * <code>Calendar</code> is constructed. They may also be specified explicitly
0123: * through the methods for setting their values.
0124: *
0125: * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or
0126: * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the
0127: * first week of the month or year as a reference point. The first week of a
0128: * month or year is defined as the earliest seven day period beginning on
0129: * <code>getFirstDayOfWeek()</code> and containing at least
0130: * <code>getMinimalDaysInFirstWeek()</code> days of that month or year. Weeks
0131: * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow
0132: * it. Note that the normalized numbering returned by <code>get()</code> may be
0133: * different. For example, a specific <code>Calendar</code> subclass may
0134: * designate the week before week 1 of a year as week <code><i>n</i></code> of
0135: * the previous year.
0136: *
0137: * <h4>Calendar Fields Resolution</h4>
0138: *
0139: * When computing a date and time from the calendar fields, there
0140: * may be insufficient information for the computation (such as only
0141: * year and month with no day of month), or there may be inconsistent
0142: * information (such as Tuesday, July 15, 1996 (Gregorian) -- July 15,
0143: * 1996 is actually a Monday). <code>Calendar</code> will resolve
0144: * calendar field values to determine the date and time in the
0145: * following way.
0146: *
0147: * <p>If there is any conflict in calendar field values,
0148: * <code>Calendar</code> gives priorities to calendar fields that have been set
0149: * more recently. The following are the default combinations of the
0150: * calendar fields. The most recent combination, as determined by the
0151: * most recently set single field, will be used.
0152: *
0153: * <p><a name="date_resolution">For the date fields</a>:
0154: * <blockquote>
0155: * <pre>
0156: * YEAR + MONTH + DAY_OF_MONTH
0157: * YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
0158: * YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
0159: * YEAR + DAY_OF_YEAR
0160: * YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
0161: * </pre></blockquote>
0162: *
0163: * <a name="time_resolution">For the time of day fields</a>:
0164: * <blockquote>
0165: * <pre>
0166: * HOUR_OF_DAY
0167: * AM_PM + HOUR
0168: * </pre></blockquote>
0169: *
0170: * <p>If there are any calendar fields whose values haven't been set in the selected
0171: * field combination, <code>Calendar</code> uses their default values. The default
0172: * value of each field may vary by concrete calendar systems. For example, in
0173: * <code>GregorianCalendar</code>, the default of a field is the same as that
0174: * of the start of the Epoch: i.e., <code>YEAR = 1970</code>, <code>MONTH =
0175: * JANUARY</code>, <code>DAY_OF_MONTH = 1</code>, etc.
0176: *
0177: * <p>
0178: * <strong>Note:</strong> There are certain possible ambiguities in
0179: * interpretation of certain singular times, which are resolved in the
0180: * following ways:
0181: * <ol>
0182: * <li> 23:59 is the last minute of the day and 00:00 is the first
0183: * minute of the next day. Thus, 23:59 on Dec 31, 1999 < 00:00 on
0184: * Jan 1, 2000 < 00:01 on Jan 1, 2000.
0185: *
0186: * <li> Although historically not precise, midnight also belongs to "am",
0187: * and noon belongs to "pm", so on the same day,
0188: * 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm
0189: * </ol>
0190: *
0191: * <p>
0192: * The date or time format strings are not part of the definition of a
0193: * calendar, as those must be modifiable or overridable by the user at
0194: * runtime. Use {@link DateFormat}
0195: * to format dates.
0196: *
0197: * <h4>Field Manipulation</h4>
0198: *
0199: * The calendar fields can be changed using three methods:
0200: * <code>set()</code>, <code>add()</code>, and <code>roll()</code>.</p>
0201: *
0202: * <p><strong><code>set(f, value)</code></strong> changes calendar field
0203: * <code>f</code> to <code>value</code>. In addition, it sets an
0204: * internal member variable to indicate that calendar field <code>f</code> has
0205: * been changed. Although calendar field <code>f</code> is changed immediately,
0206: * the calendar's time value in milliseconds is not recomputed until the next call to
0207: * <code>get()</code>, <code>getTime()</code>, <code>getTimeInMillis()</code>,
0208: * <code>add()</code>, or <code>roll()</code> is made. Thus, multiple calls to
0209: * <code>set()</code> do not trigger multiple, unnecessary
0210: * computations. As a result of changing a calendar field using
0211: * <code>set()</code>, other calendar fields may also change, depending on the
0212: * calendar field, the calendar field value, and the calendar system. In addition,
0213: * <code>get(f)</code> will not necessarily return <code>value</code> set by
0214: * the call to the <code>set</code> method
0215: * after the calendar fields have been recomputed. The specifics are determined by
0216: * the concrete calendar class.</p>
0217: *
0218: * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
0219: * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH,
0220: * Calendar.SEPTEMBER)</code> sets the date to September 31,
0221: * 1999. This is a temporary internal representation that resolves to
0222: * October 1, 1999 if <code>getTime()</code>is then called. However, a
0223: * call to <code>set(Calendar.DAY_OF_MONTH, 30)</code> before the call to
0224: * <code>getTime()</code> sets the date to September 30, 1999, since
0225: * no recomputation occurs after <code>set()</code> itself.</p>
0226: *
0227: * <p><strong><code>add(f, delta)</code></strong> adds <code>delta</code>
0228: * to field <code>f</code>. This is equivalent to calling <code>set(f,
0229: * get(f) + delta)</code> with two adjustments:</p>
0230: *
0231: * <blockquote>
0232: * <p><strong>Add rule 1</strong>. The value of field <code>f</code>
0233: * after the call minus the value of field <code>f</code> before the
0234: * call is <code>delta</code>, modulo any overflow that has occurred in
0235: * field <code>f</code>. Overflow occurs when a field value exceeds its
0236: * range and, as a result, the next larger field is incremented or
0237: * decremented and the field value is adjusted back into its range.</p>
0238: *
0239: * <p><strong>Add rule 2</strong>. If a smaller field is expected to be
0240: * invariant, but it is impossible for it to be equal to its
0241: * prior value because of changes in its minimum or maximum after field
0242: * <code>f</code> is changed or other constraints, such as time zone
0243: * offset changes, then its value is adjusted to be as close
0244: * as possible to its expected value. A smaller field represents a
0245: * smaller unit of time. <code>HOUR</code> is a smaller field than
0246: * <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields
0247: * that are not expected to be invariant. The calendar system
0248: * determines what fields are expected to be invariant.</p>
0249: * </blockquote>
0250: *
0251: * <p>In addition, unlike <code>set()</code>, <code>add()</code> forces
0252: * an immediate recomputation of the calendar's milliseconds and all
0253: * fields.</p>
0254: *
0255: * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
0256: * originally set to August 31, 1999. Calling <code>add(Calendar.MONTH,
0257: * 13)</code> sets the calendar to September 30, 2000. <strong>Add rule
0258: * 1</strong> sets the <code>MONTH</code> field to September, since
0259: * adding 13 months to August gives September of the next year. Since
0260: * <code>DAY_OF_MONTH</code> cannot be 31 in September in a
0261: * <code>GregorianCalendar</code>, <strong>add rule 2</strong> sets the
0262: * <code>DAY_OF_MONTH</code> to 30, the closest possible value. Although
0263: * it is a smaller field, <code>DAY_OF_WEEK</code> is not adjusted by
0264: * rule 2, since it is expected to change when the month changes in a
0265: * <code>GregorianCalendar</code>.</p>
0266: *
0267: * <p><strong><code>roll(f, delta)</code></strong> adds
0268: * <code>delta</code> to field <code>f</code> without changing larger
0269: * fields. This is equivalent to calling <code>add(f, delta)</code> with
0270: * the following adjustment:</p>
0271: *
0272: * <blockquote>
0273: * <p><strong>Roll rule</strong>. Larger fields are unchanged after the
0274: * call. A larger field represents a larger unit of
0275: * time. <code>DAY_OF_MONTH</code> is a larger field than
0276: * <code>HOUR</code>.</p>
0277: * </blockquote>
0278: *
0279: * <p><em>Example</em>: See {@link java.util.GregorianCalendar#roll(int, int)}.
0280: *
0281: * <p><strong>Usage model</strong>. To motivate the behavior of
0282: * <code>add()</code> and <code>roll()</code>, consider a user interface
0283: * component with increment and decrement buttons for the month, day, and
0284: * year, and an underlying <code>GregorianCalendar</code>. If the
0285: * interface reads January 31, 1999 and the user presses the month
0286: * increment button, what should it read? If the underlying
0287: * implementation uses <code>set()</code>, it might read March 3, 1999. A
0288: * better result would be February 28, 1999. Furthermore, if the user
0289: * presses the month increment button again, it should read March 31,
0290: * 1999, not March 28, 1999. By saving the original date and using either
0291: * <code>add()</code> or <code>roll()</code>, depending on whether larger
0292: * fields should be affected, the user interface can behave as most users
0293: * will intuitively expect.</p>
0294: *
0295: * @see java.lang.System#currentTimeMillis()
0296: * @see Date
0297: * @see GregorianCalendar
0298: * @see TimeZone
0299: * @see java.text.DateFormat
0300: * @version 1.95, 05/05/07
0301: * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu
0302: * @since JDK1.1
0303: */
0304: public abstract class Calendar implements Serializable, Cloneable,
0305: Comparable<Calendar> {
0306:
0307: // Data flow in Calendar
0308: // ---------------------
0309:
0310: // The current time is represented in two ways by Calendar: as UTC
0311: // milliseconds from the epoch (1 January 1970 0:00 UTC), and as local
0312: // fields such as MONTH, HOUR, AM_PM, etc. It is possible to compute the
0313: // millis from the fields, and vice versa. The data needed to do this
0314: // conversion is encapsulated by a TimeZone object owned by the Calendar.
0315: // The data provided by the TimeZone object may also be overridden if the
0316: // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
0317: // keeps track of what information was most recently set by the caller, and
0318: // uses that to compute any other information as needed.
0319:
0320: // If the user sets the fields using set(), the data flow is as follows.
0321: // This is implemented by the Calendar subclass's computeTime() method.
0322: // During this process, certain fields may be ignored. The disambiguation
0323: // algorithm for resolving which fields to pay attention to is described
0324: // in the class documentation.
0325:
0326: // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
0327: // |
0328: // | Using Calendar-specific algorithm
0329: // V
0330: // local standard millis
0331: // |
0332: // | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
0333: // V
0334: // UTC millis (in time data member)
0335:
0336: // If the user sets the UTC millis using setTime() or setTimeInMillis(),
0337: // the data flow is as follows. This is implemented by the Calendar
0338: // subclass's computeFields() method.
0339:
0340: // UTC millis (in time data member)
0341: // |
0342: // | Using TimeZone getOffset()
0343: // V
0344: // local standard millis
0345: // |
0346: // | Using Calendar-specific algorithm
0347: // V
0348: // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
0349:
0350: // In general, a round trip from fields, through local and UTC millis, and
0351: // back out to fields is made when necessary. This is implemented by the
0352: // complete() method. Resolving a partial set of fields into a UTC millis
0353: // value allows all remaining fields to be generated from that value. If
0354: // the Calendar is lenient, the fields are also renormalized to standard
0355: // ranges when they are regenerated.
0356:
0357: /**
0358: * Field number for <code>get</code> and <code>set</code> indicating the
0359: * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
0360: * value; see subclass documentation.
0361: *
0362: * @see GregorianCalendar#AD
0363: * @see GregorianCalendar#BC
0364: */
0365: public final static int ERA = 0;
0366:
0367: /**
0368: * Field number for <code>get</code> and <code>set</code> indicating the
0369: * year. This is a calendar-specific value; see subclass documentation.
0370: */
0371: public final static int YEAR = 1;
0372:
0373: /**
0374: * Field number for <code>get</code> and <code>set</code> indicating the
0375: * month. This is a calendar-specific value. The first month of
0376: * the year in the Gregorian and Julian calendars is
0377: * <code>JANUARY</code> which is 0; the last depends on the number
0378: * of months in a year.
0379: *
0380: * @see #JANUARY
0381: * @see #FEBRUARY
0382: * @see #MARCH
0383: * @see #APRIL
0384: * @see #MAY
0385: * @see #JUNE
0386: * @see #JULY
0387: * @see #AUGUST
0388: * @see #SEPTEMBER
0389: * @see #OCTOBER
0390: * @see #NOVEMBER
0391: * @see #DECEMBER
0392: * @see #UNDECIMBER
0393: */
0394: public final static int MONTH = 2;
0395:
0396: /**
0397: * Field number for <code>get</code> and <code>set</code> indicating the
0398: * week number within the current year. The first week of the year, as
0399: * defined by <code>getFirstDayOfWeek()</code> and
0400: * <code>getMinimalDaysInFirstWeek()</code>, has value 1. Subclasses define
0401: * the value of <code>WEEK_OF_YEAR</code> for days before the first week of
0402: * the year.
0403: *
0404: * @see #getFirstDayOfWeek
0405: * @see #getMinimalDaysInFirstWeek
0406: */
0407: public final static int WEEK_OF_YEAR = 3;
0408:
0409: /**
0410: * Field number for <code>get</code> and <code>set</code> indicating the
0411: * week number within the current month. The first week of the month, as
0412: * defined by <code>getFirstDayOfWeek()</code> and
0413: * <code>getMinimalDaysInFirstWeek()</code>, has value 1. Subclasses define
0414: * the value of <code>WEEK_OF_MONTH</code> for days before the first week of
0415: * the month.
0416: *
0417: * @see #getFirstDayOfWeek
0418: * @see #getMinimalDaysInFirstWeek
0419: */
0420: public final static int WEEK_OF_MONTH = 4;
0421:
0422: /**
0423: * Field number for <code>get</code> and <code>set</code> indicating the
0424: * day of the month. This is a synonym for <code>DAY_OF_MONTH</code>.
0425: * The first day of the month has value 1.
0426: *
0427: * @see #DAY_OF_MONTH
0428: */
0429: public final static int DATE = 5;
0430:
0431: /**
0432: * Field number for <code>get</code> and <code>set</code> indicating the
0433: * day of the month. This is a synonym for <code>DATE</code>.
0434: * The first day of the month has value 1.
0435: *
0436: * @see #DATE
0437: */
0438: public final static int DAY_OF_MONTH = 5;
0439:
0440: /**
0441: * Field number for <code>get</code> and <code>set</code> indicating the day
0442: * number within the current year. The first day of the year has value 1.
0443: */
0444: public final static int DAY_OF_YEAR = 6;
0445:
0446: /**
0447: * Field number for <code>get</code> and <code>set</code> indicating the day
0448: * of the week. This field takes values <code>SUNDAY</code>,
0449: * <code>MONDAY</code>, <code>TUESDAY</code>, <code>WEDNESDAY</code>,
0450: * <code>THURSDAY</code>, <code>FRIDAY</code>, and <code>SATURDAY</code>.
0451: *
0452: * @see #SUNDAY
0453: * @see #MONDAY
0454: * @see #TUESDAY
0455: * @see #WEDNESDAY
0456: * @see #THURSDAY
0457: * @see #FRIDAY
0458: * @see #SATURDAY
0459: */
0460: public final static int DAY_OF_WEEK = 7;
0461:
0462: /**
0463: * Field number for <code>get</code> and <code>set</code> indicating the
0464: * ordinal number of the day of the week within the current month. Together
0465: * with the <code>DAY_OF_WEEK</code> field, this uniquely specifies a day
0466: * within a month. Unlike <code>WEEK_OF_MONTH</code> and
0467: * <code>WEEK_OF_YEAR</code>, this field's value does <em>not</em> depend on
0468: * <code>getFirstDayOfWeek()</code> or
0469: * <code>getMinimalDaysInFirstWeek()</code>. <code>DAY_OF_MONTH 1</code>
0470: * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH
0471: * 1</code>; <code>8</code> through <code>14</code> correspond to
0472: * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on.
0473: * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before
0474: * <code>DAY_OF_WEEK_IN_MONTH 1</code>. Negative values count back from the
0475: * end of the month, so the last Sunday of a month is specified as
0476: * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>. Because
0477: * negative values count backward they will usually be aligned differently
0478: * within the month than positive values. For example, if a month has 31
0479: * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap
0480: * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>.
0481: *
0482: * @see #DAY_OF_WEEK
0483: * @see #WEEK_OF_MONTH
0484: */
0485: public final static int DAY_OF_WEEK_IN_MONTH = 8;
0486:
0487: /**
0488: * Field number for <code>get</code> and <code>set</code> indicating
0489: * whether the <code>HOUR</code> is before or after noon.
0490: * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>.
0491: *
0492: * @see #AM
0493: * @see #PM
0494: * @see #HOUR
0495: */
0496: public final static int AM_PM = 9;
0497:
0498: /**
0499: * Field number for <code>get</code> and <code>set</code> indicating the
0500: * hour of the morning or afternoon. <code>HOUR</code> is used for the
0501: * 12-hour clock (0 - 11). Noon and midnight are represented by 0, not by 12.
0502: * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10.
0503: *
0504: * @see #AM_PM
0505: * @see #HOUR_OF_DAY
0506: */
0507: public final static int HOUR = 10;
0508:
0509: /**
0510: * Field number for <code>get</code> and <code>set</code> indicating the
0511: * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock.
0512: * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22.
0513: *
0514: * @see #HOUR
0515: */
0516: public final static int HOUR_OF_DAY = 11;
0517:
0518: /**
0519: * Field number for <code>get</code> and <code>set</code> indicating the
0520: * minute within the hour.
0521: * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4.
0522: */
0523: public final static int MINUTE = 12;
0524:
0525: /**
0526: * Field number for <code>get</code> and <code>set</code> indicating the
0527: * second within the minute.
0528: * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15.
0529: */
0530: public final static int SECOND = 13;
0531:
0532: /**
0533: * Field number for <code>get</code> and <code>set</code> indicating the
0534: * millisecond within the second.
0535: * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250.
0536: */
0537: public final static int MILLISECOND = 14;
0538:
0539: /**
0540: * Field number for <code>get</code> and <code>set</code>
0541: * indicating the raw offset from GMT in milliseconds.
0542: * <p>
0543: * This field reflects the correct GMT offset value of the time
0544: * zone of this <code>Calendar</code> if the
0545: * <code>TimeZone</code> implementation subclass supports
0546: * historical GMT offset changes.
0547: */
0548: public final static int ZONE_OFFSET = 15;
0549:
0550: /**
0551: * Field number for <code>get</code> and <code>set</code> indicating the
0552: * daylight savings offset in milliseconds.
0553: * <p>
0554: * This field reflects the correct daylight saving offset value of
0555: * the time zone of this <code>Calendar</code> if the
0556: * <code>TimeZone</code> implementation subclass supports
0557: * historical Daylight Saving Time schedule changes.
0558: */
0559: public final static int DST_OFFSET = 16;
0560:
0561: /**
0562: * The number of distinct fields recognized by <code>get</code> and <code>set</code>.
0563: * Field numbers range from <code>0..FIELD_COUNT-1</code>.
0564: */
0565: public final static int FIELD_COUNT = 17;
0566:
0567: /**
0568: * Value of the {@link #DAY_OF_WEEK} field indicating
0569: * Sunday.
0570: */
0571: public final static int SUNDAY = 1;
0572:
0573: /**
0574: * Value of the {@link #DAY_OF_WEEK} field indicating
0575: * Monday.
0576: */
0577: public final static int MONDAY = 2;
0578:
0579: /**
0580: * Value of the {@link #DAY_OF_WEEK} field indicating
0581: * Tuesday.
0582: */
0583: public final static int TUESDAY = 3;
0584:
0585: /**
0586: * Value of the {@link #DAY_OF_WEEK} field indicating
0587: * Wednesday.
0588: */
0589: public final static int WEDNESDAY = 4;
0590:
0591: /**
0592: * Value of the {@link #DAY_OF_WEEK} field indicating
0593: * Thursday.
0594: */
0595: public final static int THURSDAY = 5;
0596:
0597: /**
0598: * Value of the {@link #DAY_OF_WEEK} field indicating
0599: * Friday.
0600: */
0601: public final static int FRIDAY = 6;
0602:
0603: /**
0604: * Value of the {@link #DAY_OF_WEEK} field indicating
0605: * Saturday.
0606: */
0607: public final static int SATURDAY = 7;
0608:
0609: /**
0610: * Value of the {@link #MONTH} field indicating the
0611: * first month of the year in the Gregorian and Julian calendars.
0612: */
0613: public final static int JANUARY = 0;
0614:
0615: /**
0616: * Value of the {@link #MONTH} field indicating the
0617: * second month of the year in the Gregorian and Julian calendars.
0618: */
0619: public final static int FEBRUARY = 1;
0620:
0621: /**
0622: * Value of the {@link #MONTH} field indicating the
0623: * third month of the year in the Gregorian and Julian calendars.
0624: */
0625: public final static int MARCH = 2;
0626:
0627: /**
0628: * Value of the {@link #MONTH} field indicating the
0629: * fourth month of the year in the Gregorian and Julian calendars.
0630: */
0631: public final static int APRIL = 3;
0632:
0633: /**
0634: * Value of the {@link #MONTH} field indicating the
0635: * fifth month of the year in the Gregorian and Julian calendars.
0636: */
0637: public final static int MAY = 4;
0638:
0639: /**
0640: * Value of the {@link #MONTH} field indicating the
0641: * sixth month of the year in the Gregorian and Julian calendars.
0642: */
0643: public final static int JUNE = 5;
0644:
0645: /**
0646: * Value of the {@link #MONTH} field indicating the
0647: * seventh month of the year in the Gregorian and Julian calendars.
0648: */
0649: public final static int JULY = 6;
0650:
0651: /**
0652: * Value of the {@link #MONTH} field indicating the
0653: * eighth month of the year in the Gregorian and Julian calendars.
0654: */
0655: public final static int AUGUST = 7;
0656:
0657: /**
0658: * Value of the {@link #MONTH} field indicating the
0659: * ninth month of the year in the Gregorian and Julian calendars.
0660: */
0661: public final static int SEPTEMBER = 8;
0662:
0663: /**
0664: * Value of the {@link #MONTH} field indicating the
0665: * tenth month of the year in the Gregorian and Julian calendars.
0666: */
0667: public final static int OCTOBER = 9;
0668:
0669: /**
0670: * Value of the {@link #MONTH} field indicating the
0671: * eleventh month of the year in the Gregorian and Julian calendars.
0672: */
0673: public final static int NOVEMBER = 10;
0674:
0675: /**
0676: * Value of the {@link #MONTH} field indicating the
0677: * twelfth month of the year in the Gregorian and Julian calendars.
0678: */
0679: public final static int DECEMBER = 11;
0680:
0681: /**
0682: * Value of the {@link #MONTH} field indicating the
0683: * thirteenth month of the year. Although <code>GregorianCalendar</code>
0684: * does not use this value, lunar calendars do.
0685: */
0686: public final static int UNDECIMBER = 12;
0687:
0688: /**
0689: * Value of the {@link #AM_PM} field indicating the
0690: * period of the day from midnight to just before noon.
0691: */
0692: public final static int AM = 0;
0693:
0694: /**
0695: * Value of the {@link #AM_PM} field indicating the
0696: * period of the day from noon to just before midnight.
0697: */
0698: public final static int PM = 1;
0699:
0700: /**
0701: * A style specifier for {@link #getDisplayNames(int, int, Locale)
0702: * getDisplayNames} indicating names in all styles, such as
0703: * "January" and "Jan".
0704: *
0705: * @see #SHORT
0706: * @see #LONG
0707: * @since 1.6
0708: */
0709: public static final int ALL_STYLES = 0;
0710:
0711: /**
0712: * A style specifier for {@link #getDisplayName(int, int, Locale)
0713: * getDisplayName} and {@link #getDisplayNames(int, int, Locale)
0714: * getDisplayNames} indicating a short name, such as "Jan".
0715: *
0716: * @see #LONG
0717: * @since 1.6
0718: */
0719: public static final int SHORT = 1;
0720:
0721: /**
0722: * A style specifier for {@link #getDisplayName(int, int, Locale)
0723: * getDisplayName} and {@link #getDisplayNames(int, int, Locale)
0724: * getDisplayNames} indicating a long name, such as "January".
0725: *
0726: * @see #SHORT
0727: * @since 1.6
0728: */
0729: public static final int LONG = 2;
0730:
0731: // Internal notes:
0732: // Calendar contains two kinds of time representations: current "time" in
0733: // milliseconds, and a set of calendar "fields" representing the current time.
0734: // The two representations are usually in sync, but can get out of sync
0735: // as follows.
0736: // 1. Initially, no fields are set, and the time is invalid.
0737: // 2. If the time is set, all fields are computed and in sync.
0738: // 3. If a single field is set, the time is invalid.
0739: // Recomputation of the time and fields happens when the object needs
0740: // to return a result to the user, or use a result for a computation.
0741:
0742: /**
0743: * The calendar field values for the currently set time for this calendar.
0744: * This is an array of <code>FIELD_COUNT</code> integers, with index values
0745: * <code>ERA</code> through <code>DST_OFFSET</code>.
0746: * @serial
0747: */
0748: protected int fields[];
0749:
0750: /**
0751: * The flags which tell if a specified calendar field for the calendar is set.
0752: * A new object has no fields set. After the first call to a method
0753: * which generates the fields, they all remain set after that.
0754: * This is an array of <code>FIELD_COUNT</code> booleans, with index values
0755: * <code>ERA</code> through <code>DST_OFFSET</code>.
0756: * @serial
0757: */
0758: protected boolean isSet[];
0759:
0760: /**
0761: * Pseudo-time-stamps which specify when each field was set. There
0762: * are two special values, UNSET and COMPUTED. Values from
0763: * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
0764: */
0765: transient private int stamp[];
0766:
0767: /**
0768: * The currently set time for this calendar, expressed in milliseconds after
0769: * January 1, 1970, 0:00:00 GMT.
0770: * @see #isTimeSet
0771: * @serial
0772: */
0773: protected long time;
0774:
0775: /**
0776: * True if then the value of <code>time</code> is valid.
0777: * The time is made invalid by a change to an item of <code>field[]</code>.
0778: * @see #time
0779: * @serial
0780: */
0781: protected boolean isTimeSet;
0782:
0783: /**
0784: * True if <code>fields[]</code> are in sync with the currently set time.
0785: * If false, then the next attempt to get the value of a field will
0786: * force a recomputation of all fields from the current value of
0787: * <code>time</code>.
0788: * @serial
0789: */
0790: protected boolean areFieldsSet;
0791:
0792: /**
0793: * True if all fields have been set.
0794: * @serial
0795: */
0796: transient boolean areAllFieldsSet;
0797:
0798: /**
0799: * <code>True</code> if this calendar allows out-of-range field values during computation
0800: * of <code>time</code> from <code>fields[]</code>.
0801: * @see #setLenient
0802: * @see #isLenient
0803: * @serial
0804: */
0805: private boolean lenient = true;
0806:
0807: /**
0808: * The <code>TimeZone</code> used by this calendar. <code>Calendar</code>
0809: * uses the time zone data to translate between locale and GMT time.
0810: * @serial
0811: */
0812: private TimeZone zone;
0813:
0814: /**
0815: * <code>True</code> if zone references to a shared TimeZone object.
0816: */
0817: transient private boolean sharedZone = false;
0818:
0819: /**
0820: * The first day of the week, with possible values <code>SUNDAY</code>,
0821: * <code>MONDAY</code>, etc. This is a locale-dependent value.
0822: * @serial
0823: */
0824: private int firstDayOfWeek;
0825:
0826: /**
0827: * The number of days required for the first week in a month or year,
0828: * with possible values from 1 to 7. This is a locale-dependent value.
0829: * @serial
0830: */
0831: private int minimalDaysInFirstWeek;
0832:
0833: /**
0834: * Cache to hold the firstDayOfWeek and minimalDaysInFirstWeek
0835: * of a Locale.
0836: */
0837: private static Hashtable<Locale, int[]> cachedLocaleData = new Hashtable<Locale, int[]>(
0838: 3);
0839:
0840: // Special values of stamp[]
0841: /**
0842: * The corresponding fields[] has no value.
0843: */
0844: private static final int UNSET = 0;
0845:
0846: /**
0847: * The value of the corresponding fields[] has been calculated internally.
0848: */
0849: private static final int COMPUTED = 1;
0850:
0851: /**
0852: * The value of the corresponding fields[] has been set externally. Stamp
0853: * values which are greater than 1 represents the (pseudo) time when the
0854: * corresponding fields[] value was set.
0855: */
0856: private static final int MINIMUM_USER_STAMP = 2;
0857:
0858: /**
0859: * The mask value that represents all of the fields.
0860: */
0861: static final int ALL_FIELDS = (1 << FIELD_COUNT) - 1;
0862:
0863: /**
0864: * The next available value for <code>stamp[]</code>, an internal array.
0865: * This actually should not be written out to the stream, and will probably
0866: * be removed from the stream in the near future. In the meantime,
0867: * a value of <code>MINIMUM_USER_STAMP</code> should be used.
0868: * @serial
0869: */
0870: private int nextStamp = MINIMUM_USER_STAMP;
0871:
0872: // the internal serial version which says which version was written
0873: // - 0 (default) for version up to JDK 1.1.5
0874: // - 1 for version from JDK 1.1.6, which writes a correct 'time' value
0875: // as well as compatible values for other fields. This is a
0876: // transitional format.
0877: // - 2 (not implemented yet) a future version, in which fields[],
0878: // areFieldsSet, and isTimeSet become transient, and isSet[] is
0879: // removed. In JDK 1.1.6 we write a format compatible with version 2.
0880: static final int currentSerialVersion = 1;
0881:
0882: /**
0883: * The version of the serialized data on the stream. Possible values:
0884: * <dl>
0885: * <dt><b>0</b> or not present on stream</dt>
0886: * <dd>
0887: * JDK 1.1.5 or earlier.
0888: * </dd>
0889: * <dt><b>1</b></dt>
0890: * <dd>
0891: * JDK 1.1.6 or later. Writes a correct 'time' value
0892: * as well as compatible values for other fields. This is a
0893: * transitional format.
0894: * </dd>
0895: * </dl>
0896: * When streaming out this class, the most recent format
0897: * and the highest allowable <code>serialVersionOnStream</code>
0898: * is written.
0899: * @serial
0900: * @since JDK1.1.6
0901: */
0902: private int serialVersionOnStream = currentSerialVersion;
0903:
0904: // Proclaim serialization compatibility with JDK 1.1
0905: static final long serialVersionUID = -1807547505821590642L;
0906:
0907: // Mask values for calendar fields
0908: final static int ERA_MASK = (1 << ERA);
0909: final static int YEAR_MASK = (1 << YEAR);
0910: final static int MONTH_MASK = (1 << MONTH);
0911: final static int WEEK_OF_YEAR_MASK = (1 << WEEK_OF_YEAR);
0912: final static int WEEK_OF_MONTH_MASK = (1 << WEEK_OF_MONTH);
0913: final static int DAY_OF_MONTH_MASK = (1 << DAY_OF_MONTH);
0914: final static int DATE_MASK = DAY_OF_MONTH_MASK;
0915: final static int DAY_OF_YEAR_MASK = (1 << DAY_OF_YEAR);
0916: final static int DAY_OF_WEEK_MASK = (1 << DAY_OF_WEEK);
0917: final static int DAY_OF_WEEK_IN_MONTH_MASK = (1 << DAY_OF_WEEK_IN_MONTH);
0918: final static int AM_PM_MASK = (1 << AM_PM);
0919: final static int HOUR_MASK = (1 << HOUR);
0920: final static int HOUR_OF_DAY_MASK = (1 << HOUR_OF_DAY);
0921: final static int MINUTE_MASK = (1 << MINUTE);
0922: final static int SECOND_MASK = (1 << SECOND);
0923: final static int MILLISECOND_MASK = (1 << MILLISECOND);
0924: final static int ZONE_OFFSET_MASK = (1 << ZONE_OFFSET);
0925: final static int DST_OFFSET_MASK = (1 << DST_OFFSET);
0926:
0927: /**
0928: * Constructs a Calendar with the default time zone
0929: * and locale.
0930: * @see TimeZone#getDefault
0931: */
0932: protected Calendar() {
0933: this (TimeZone.getDefaultRef(), Locale.getDefault());
0934: sharedZone = true;
0935: }
0936:
0937: /**
0938: * Constructs a calendar with the specified time zone and locale.
0939: *
0940: * @param zone the time zone to use
0941: * @param aLocale the locale for the week data
0942: */
0943: protected Calendar(TimeZone zone, Locale aLocale) {
0944: fields = new int[FIELD_COUNT];
0945: isSet = new boolean[FIELD_COUNT];
0946: stamp = new int[FIELD_COUNT];
0947:
0948: this .zone = zone;
0949: setWeekCountData(aLocale);
0950: }
0951:
0952: /**
0953: * Gets a calendar using the default time zone and locale. The
0954: * <code>Calendar</code> returned is based on the current time
0955: * in the default time zone with the default locale.
0956: *
0957: * @return a Calendar.
0958: */
0959: public static Calendar getInstance() {
0960: Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale
0961: .getDefault());
0962: cal.sharedZone = true;
0963: return cal;
0964: }
0965:
0966: /**
0967: * Gets a calendar using the specified time zone and default locale.
0968: * The <code>Calendar</code> returned is based on the current time
0969: * in the given time zone with the default locale.
0970: *
0971: * @param zone the time zone to use
0972: * @return a Calendar.
0973: */
0974: public static Calendar getInstance(TimeZone zone) {
0975: return createCalendar(zone, Locale.getDefault());
0976: }
0977:
0978: /**
0979: * Gets a calendar using the default time zone and specified locale.
0980: * The <code>Calendar</code> returned is based on the current time
0981: * in the default time zone with the given locale.
0982: *
0983: * @param aLocale the locale for the week data
0984: * @return a Calendar.
0985: */
0986: public static Calendar getInstance(Locale aLocale) {
0987: Calendar cal = createCalendar(TimeZone.getDefaultRef(), aLocale);
0988: cal.sharedZone = true;
0989: return cal;
0990: }
0991:
0992: /**
0993: * Gets a calendar with the specified time zone and locale.
0994: * The <code>Calendar</code> returned is based on the current time
0995: * in the given time zone with the given locale.
0996: *
0997: * @param zone the time zone to use
0998: * @param aLocale the locale for the week data
0999: * @return a Calendar.
1000: */
1001: public static Calendar getInstance(TimeZone zone, Locale aLocale) {
1002: return createCalendar(zone, aLocale);
1003: }
1004:
1005: private static Calendar createCalendar(TimeZone zone, Locale aLocale) {
1006: // If the specified locale is a Thai locale, returns a BuddhistCalendar
1007: // instance.
1008: if ("th".equals(aLocale.getLanguage())
1009: && ("TH".equals(aLocale.getCountry()))) {
1010: return new sun.util.BuddhistCalendar(zone, aLocale);
1011: } else if ("JP".equals(aLocale.getVariant())
1012: && "JP".equals(aLocale.getCountry())
1013: && "ja".equals(aLocale.getLanguage())) {
1014: return new JapaneseImperialCalendar(zone, aLocale);
1015: }
1016:
1017: // else create the default calendar
1018: return new GregorianCalendar(zone, aLocale);
1019: }
1020:
1021: /**
1022: * Returns an array of all locales for which the <code>getInstance</code>
1023: * methods of this class can return localized instances.
1024: * The array returned must contain at least a <code>Locale</code>
1025: * instance equal to {@link java.util.Locale#US Locale.US}.
1026: *
1027: * @return An array of locales for which localized
1028: * <code>Calendar</code> instances are available.
1029: */
1030: public static synchronized Locale[] getAvailableLocales() {
1031: return DateFormat.getAvailableLocales();
1032: }
1033:
1034: /**
1035: * Converts the current calendar field values in {@link #fields fields[]}
1036: * to the millisecond time value
1037: * {@link #time}.
1038: *
1039: * @see #complete()
1040: * @see #computeFields()
1041: */
1042: protected abstract void computeTime();
1043:
1044: /**
1045: * Converts the current millisecond time value {@link #time}
1046: * to calendar field values in {@link #fields fields[]}.
1047: * This allows you to sync up the calendar field values with
1048: * a new time that is set for the calendar. The time is <em>not</em>
1049: * recomputed first; to recompute the time, then the fields, call the
1050: * {@link #complete()} method.
1051: *
1052: * @see #computeTime()
1053: */
1054: protected abstract void computeFields();
1055:
1056: /**
1057: * Returns a <code>Date</code> object representing this
1058: * <code>Calendar</code>'s time value (millisecond offset from the <a
1059: * href="#Epoch">Epoch</a>").
1060: *
1061: * @return a <code>Date</code> representing the time value.
1062: * @see #setTime(Date)
1063: * @see #getTimeInMillis()
1064: */
1065: public final Date getTime() {
1066: return new Date(getTimeInMillis());
1067: }
1068:
1069: /**
1070: * Sets this Calendar's time with the given <code>Date</code>.
1071: * <p>
1072: * Note: Calling <code>setTime()</code> with
1073: * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code>
1074: * may yield incorrect field values from <code>get()</code>.
1075: *
1076: * @param date the given Date.
1077: * @see #getTime()
1078: * @see #setTimeInMillis(long)
1079: */
1080: public final void setTime(Date date) {
1081: setTimeInMillis(date.getTime());
1082: }
1083:
1084: /**
1085: * Returns this Calendar's time value in milliseconds.
1086: *
1087: * @return the current time as UTC milliseconds from the epoch.
1088: * @see #getTime()
1089: * @see #setTimeInMillis(long)
1090: */
1091: public long getTimeInMillis() {
1092: if (!isTimeSet) {
1093: updateTime();
1094: }
1095: return time;
1096: }
1097:
1098: /**
1099: * Sets this Calendar's current time from the given long value.
1100: *
1101: * @param millis the new time in UTC milliseconds from the epoch.
1102: * @see #setTime(Date)
1103: * @see #getTimeInMillis()
1104: */
1105: public void setTimeInMillis(long millis) {
1106: // If we don't need to recalculate the calendar field values,
1107: // do nothing.
1108: if (time == millis && isTimeSet && areFieldsSet
1109: && areAllFieldsSet && (zone instanceof ZoneInfo)
1110: && !((ZoneInfo) zone).isDirty()) {
1111: return;
1112: }
1113: time = millis;
1114: isTimeSet = true;
1115: areFieldsSet = false;
1116: computeFields();
1117: areAllFieldsSet = areFieldsSet = true;
1118: }
1119:
1120: /**
1121: * Returns the value of the given calendar field. In lenient mode,
1122: * all calendar fields are normalized. In non-lenient mode, all
1123: * calendar fields are validated and this method throws an
1124: * exception if any calendar fields have out-of-range values. The
1125: * normalization and validation are handled by the
1126: * {@link #complete()} method, which process is calendar
1127: * system dependent.
1128: *
1129: * @param field the given calendar field.
1130: * @return the value for the given calendar field.
1131: * @throws ArrayIndexOutOfBoundsException if the specified field is out of range
1132: * (<code>field < 0 || field >= FIELD_COUNT</code>).
1133: * @see #set(int,int)
1134: * @see #complete()
1135: */
1136: public int get(int field) {
1137: complete();
1138: return internalGet(field);
1139: }
1140:
1141: /**
1142: * Returns the value of the given calendar field. This method does
1143: * not involve normalization or validation of the field value.
1144: *
1145: * @param field the given calendar field.
1146: * @return the value for the given calendar field.
1147: * @see #get(int)
1148: */
1149: protected final int internalGet(int field) {
1150: return fields[field];
1151: }
1152:
1153: /**
1154: * Sets the value of the given calendar field. This method does
1155: * not affect any setting state of the field in this
1156: * <code>Calendar</code> instance.
1157: *
1158: * @throws IndexOutOfBoundsException if the specified field is out of range
1159: * (<code>field < 0 || field >= FIELD_COUNT</code>).
1160: * @see #areFieldsSet
1161: * @see #isTimeSet
1162: * @see #areAllFieldsSet
1163: * @see #set(int,int)
1164: */
1165: final void internalSet(int field, int value) {
1166: fields[field] = value;
1167: }
1168:
1169: /**
1170: * Sets the given calendar field to the given value. The value is not
1171: * interpreted by this method regardless of the leniency mode.
1172: *
1173: * @param field the given calendar field.
1174: * @param value the value to be set for the given calendar field.
1175: * @throws ArrayIndexOutOfBoundsException if the specified field is out of range
1176: * (<code>field < 0 || field >= FIELD_COUNT</code>).
1177: * in non-lenient mode.
1178: * @see #set(int,int,int)
1179: * @see #set(int,int,int,int,int)
1180: * @see #set(int,int,int,int,int,int)
1181: * @see #get(int)
1182: */
1183: public void set(int field, int value) {
1184: if (isLenient() && areFieldsSet && !areAllFieldsSet) {
1185: computeFields();
1186: }
1187: internalSet(field, value);
1188: isTimeSet = false;
1189: areFieldsSet = false;
1190: isSet[field] = true;
1191: stamp[field] = nextStamp++;
1192: if (nextStamp == Integer.MAX_VALUE) {
1193: adjustStamp();
1194: }
1195: }
1196:
1197: /**
1198: * Sets the values for the calendar fields <code>YEAR</code>,
1199: * <code>MONTH</code>, and <code>DAY_OF_MONTH</code>.
1200: * Previous values of other calendar fields are retained. If this is not desired,
1201: * call {@link #clear()} first.
1202: *
1203: * @param year the value used to set the <code>YEAR</code> calendar field.
1204: * @param month the value used to set the <code>MONTH</code> calendar field.
1205: * Month value is 0-based. e.g., 0 for January.
1206: * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field.
1207: * @see #set(int,int)
1208: * @see #set(int,int,int,int,int)
1209: * @see #set(int,int,int,int,int,int)
1210: */
1211: public final void set(int year, int month, int date) {
1212: set(YEAR, year);
1213: set(MONTH, month);
1214: set(DATE, date);
1215: }
1216:
1217: /**
1218: * Sets the values for the calendar fields <code>YEAR</code>,
1219: * <code>MONTH</code>, <code>DAY_OF_MONTH</code>,
1220: * <code>HOUR_OF_DAY</code>, and <code>MINUTE</code>.
1221: * Previous values of other fields are retained. If this is not desired,
1222: * call {@link #clear()} first.
1223: *
1224: * @param year the value used to set the <code>YEAR</code> calendar field.
1225: * @param month the value used to set the <code>MONTH</code> calendar field.
1226: * Month value is 0-based. e.g., 0 for January.
1227: * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field.
1228: * @param hourOfDay the value used to set the <code>HOUR_OF_DAY</code> calendar field.
1229: * @param minute the value used to set the <code>MINUTE</code> calendar field.
1230: * @see #set(int,int)
1231: * @see #set(int,int,int)
1232: * @see #set(int,int,int,int,int,int)
1233: */
1234: public final void set(int year, int month, int date, int hourOfDay,
1235: int minute) {
1236: set(YEAR, year);
1237: set(MONTH, month);
1238: set(DATE, date);
1239: set(HOUR_OF_DAY, hourOfDay);
1240: set(MINUTE, minute);
1241: }
1242:
1243: /**
1244: * Sets the values for the fields <code>YEAR</code>, <code>MONTH</code>,
1245: * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, <code>MINUTE</code>, and
1246: * <code>SECOND</code>.
1247: * Previous values of other fields are retained. If this is not desired,
1248: * call {@link #clear()} first.
1249: *
1250: * @param year the value used to set the <code>YEAR</code> calendar field.
1251: * @param month the value used to set the <code>MONTH</code> calendar field.
1252: * Month value is 0-based. e.g., 0 for January.
1253: * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field.
1254: * @param hourOfDay the value used to set the <code>HOUR_OF_DAY</code> calendar field.
1255: * @param minute the value used to set the <code>MINUTE</code> calendar field.
1256: * @param second the value used to set the <code>SECOND</code> calendar field.
1257: * @see #set(int,int)
1258: * @see #set(int,int,int)
1259: * @see #set(int,int,int,int,int)
1260: */
1261: public final void set(int year, int month, int date, int hourOfDay,
1262: int minute, int second) {
1263: set(YEAR, year);
1264: set(MONTH, month);
1265: set(DATE, date);
1266: set(HOUR_OF_DAY, hourOfDay);
1267: set(MINUTE, minute);
1268: set(SECOND, second);
1269: }
1270:
1271: /**
1272: * Sets all the calendar field values and the time value
1273: * (millisecond offset from the <a href="#Epoch">Epoch</a>) of
1274: * this <code>Calendar</code> undefined. This means that {@link
1275: * #isSet(int) isSet()} will return <code>false</code> for all the
1276: * calendar fields, and the date and time calculations will treat
1277: * the fields as if they had never been set. A
1278: * <code>Calendar</code> implementation class may use its specific
1279: * default field values for date/time calculations. For example,
1280: * <code>GregorianCalendar</code> uses 1970 if the
1281: * <code>YEAR</code> field value is undefined.
1282: *
1283: * @see #clear(int)
1284: */
1285: public final void clear() {
1286: for (int i = 0; i < fields.length;) {
1287: stamp[i] = fields[i] = 0; // UNSET == 0
1288: isSet[i++] = false;
1289: }
1290: areAllFieldsSet = areFieldsSet = false;
1291: isTimeSet = false;
1292: }
1293:
1294: /**
1295: * Sets the given calendar field value and the time value
1296: * (millisecond offset from the <a href="#Epoch">Epoch</a>) of
1297: * this <code>Calendar</code> undefined. This means that {@link
1298: * #isSet(int) isSet(field)} will return <code>false</code>, and
1299: * the date and time calculations will treat the field as if it
1300: * had never been set. A <code>Calendar</code> implementation
1301: * class may use the field's specific default value for date and
1302: * time calculations.
1303: *
1304: * <p>The {@link #HOUR_OF_DAY}, {@link #HOUR} and {@link #AM_PM}
1305: * fields are handled independently and the <a
1306: * href="#time_resolution">the resolution rule for the time of
1307: * day</a> is applied. Clearing one of the fields doesn't reset
1308: * the hour of day value of this <code>Calendar</code>. Use {@link
1309: * #set(int,int) set(Calendar.HOUR_OF_DAY, 0)} to reset the hour
1310: * value.
1311: *
1312: * @param field the calendar field to be cleared.
1313: * @see #clear()
1314: */
1315: public final void clear(int field) {
1316: fields[field] = 0;
1317: stamp[field] = UNSET;
1318: isSet[field] = false;
1319:
1320: areAllFieldsSet = areFieldsSet = false;
1321: isTimeSet = false;
1322: }
1323:
1324: /**
1325: * Determines if the given calendar field has a value set,
1326: * including cases that the value has been set by internal fields
1327: * calculations triggered by a <code>get</code> method call.
1328: *
1329: * @return <code>true</code> if the given calendar field has a value set;
1330: * <code>false</code> otherwise.
1331: */
1332: public final boolean isSet(int field) {
1333: return stamp[field] != UNSET;
1334: }
1335:
1336: /**
1337: * Returns the string representation of the calendar
1338: * <code>field</code> value in the given <code>style</code> and
1339: * <code>locale</code>. If no string representation is
1340: * applicable, <code>null</code> is returned. This method calls
1341: * {@link Calendar#get(int) get(field)} to get the calendar
1342: * <code>field</code> value if the string representation is
1343: * applicable to the given calendar <code>field</code>.
1344: *
1345: * <p>For example, if this <code>Calendar</code> is a
1346: * <code>GregorianCalendar</code> and its date is 2005-01-01, then
1347: * the string representation of the {@link #MONTH} field would be
1348: * "January" in the long style in an English locale or "Jan" in
1349: * the short style. However, no string representation would be
1350: * available for the {@link #DAY_OF_MONTH} field, and this method
1351: * would return <code>null</code>.
1352: *
1353: * <p>The default implementation supports the calendar fields for
1354: * which a {@link DateFormatSymbols} has names in the given
1355: * <code>locale</code>.
1356: *
1357: * @param field
1358: * the calendar field for which the string representation
1359: * is returned
1360: * @param style
1361: * the style applied to the string representation; one of
1362: * {@link #SHORT} or {@link #LONG}.
1363: * @param locale
1364: * the locale for the string representation
1365: * @return the string representation of the given
1366: * <code>field</code> in the given <code>style</code>, or
1367: * <code>null</code> if no string representation is
1368: * applicable.
1369: * @exception IllegalArgumentException
1370: * if <code>field</code> or <code>style</code> is invalid,
1371: * or if this <code>Calendar</code> is non-lenient and any
1372: * of the calendar fields have invalid values
1373: * @exception NullPointerException
1374: * if <code>locale</code> is null
1375: * @since 1.6
1376: */
1377: public String getDisplayName(int field, int style, Locale locale) {
1378: if (!checkDisplayNameParams(field, style, ALL_STYLES, LONG,
1379: locale, ERA_MASK | MONTH_MASK | DAY_OF_WEEK_MASK
1380: | AM_PM_MASK)) {
1381: return null;
1382: }
1383:
1384: DateFormatSymbols symbols = DateFormatSymbols
1385: .getInstance(locale);
1386: String[] strings = getFieldStrings(field, style, symbols);
1387: if (strings != null) {
1388: int fieldValue = get(field);
1389: if (fieldValue < strings.length) {
1390: return strings[fieldValue];
1391: }
1392: }
1393: return null;
1394: }
1395:
1396: /**
1397: * Returns a <code>Map</code> containing all names of the calendar
1398: * <code>field</code> in the given <code>style</code> and
1399: * <code>locale</code> and their corresponding field values. For
1400: * example, if this <code>Calendar</code> is a {@link
1401: * GregorianCalendar}, the returned map would contain "Jan" to
1402: * {@link #JANUARY}, "Feb" to {@link #FEBRUARY}, and so on, in the
1403: * {@linkplain #SHORT short} style in an English locale.
1404: *
1405: * <p>The values of other calendar fields may be taken into
1406: * account to determine a set of display names. For example, if
1407: * this <code>Calendar</code> is a lunisolar calendar system and
1408: * the year value given by the {@link #YEAR} field has a leap
1409: * month, this method would return month names containing the leap
1410: * month name, and month names are mapped to their values specific
1411: * for the year.
1412: *
1413: * <p>The default implementation supports display names contained in
1414: * a {@link DateFormatSymbols}. For example, if <code>field</code>
1415: * is {@link #MONTH} and <code>style</code> is {@link
1416: * #ALL_STYLES}, this method returns a <code>Map</code> containing
1417: * all strings returned by {@link DateFormatSymbols#getShortMonths()}
1418: * and {@link DateFormatSymbols#getMonths()}.
1419: *
1420: * @param field
1421: * the calendar field for which the display names are returned
1422: * @param style
1423: * the style applied to the display names; one of {@link
1424: * #SHORT}, {@link #LONG}, or {@link #ALL_STYLES}.
1425: * @param locale
1426: * the locale for the display names
1427: * @return a <code>Map</code> containing all display names in
1428: * <code>style</code> and <code>locale</code> and their
1429: * field values, or <code>null</code> if no display names
1430: * are defined for <code>field</code>
1431: * @exception IllegalArgumentException
1432: * if <code>field</code> or <code>style</code> is invalid,
1433: * or if this <code>Calendar</code> is non-lenient and any
1434: * of the calendar fields have invalid values
1435: * @exception NullPointerException
1436: * if <code>locale</code> is null
1437: * @since 1.6
1438: */
1439: public Map<String, Integer> getDisplayNames(int field, int style,
1440: Locale locale) {
1441: if (!checkDisplayNameParams(field, style, ALL_STYLES, LONG,
1442: locale, ERA_MASK | MONTH_MASK | DAY_OF_WEEK_MASK
1443: | AM_PM_MASK)) {
1444: return null;
1445: }
1446:
1447: // ALL_STYLES
1448: if (style == ALL_STYLES) {
1449: Map<String, Integer> shortNames = getDisplayNamesImpl(
1450: field, SHORT, locale);
1451: if (field == ERA || field == AM_PM) {
1452: return shortNames;
1453: }
1454: Map<String, Integer> longNames = getDisplayNamesImpl(field,
1455: LONG, locale);
1456: if (shortNames == null) {
1457: return longNames;
1458: }
1459: if (longNames != null) {
1460: shortNames.putAll(longNames);
1461: }
1462: return shortNames;
1463: }
1464:
1465: // SHORT or LONG
1466: return getDisplayNamesImpl(field, style, locale);
1467: }
1468:
1469: private Map<String, Integer> getDisplayNamesImpl(int field,
1470: int style, Locale locale) {
1471: DateFormatSymbols symbols = DateFormatSymbols
1472: .getInstance(locale);
1473: String[] strings = getFieldStrings(field, style, symbols);
1474: if (strings != null) {
1475: Map<String, Integer> names = new HashMap<String, Integer>();
1476: for (int i = 0; i < strings.length; i++) {
1477: if (strings[i].length() == 0) {
1478: continue;
1479: }
1480: names.put(strings[i], i);
1481: }
1482: return names;
1483: }
1484: return null;
1485: }
1486:
1487: boolean checkDisplayNameParams(int field, int style, int minStyle,
1488: int maxStyle, Locale locale, int fieldMask) {
1489: if (field < 0 || field >= fields.length || style < minStyle
1490: || style > maxStyle) {
1491: throw new IllegalArgumentException();
1492: }
1493: if (locale == null) {
1494: throw new NullPointerException();
1495: }
1496: return isFieldSet(fieldMask, field);
1497: }
1498:
1499: private String[] getFieldStrings(int field, int style,
1500: DateFormatSymbols symbols) {
1501: String[] strings = null;
1502: switch (field) {
1503: case ERA:
1504: strings = symbols.getEras();
1505: break;
1506:
1507: case MONTH:
1508: strings = (style == LONG) ? symbols.getMonths() : symbols
1509: .getShortMonths();
1510: break;
1511:
1512: case DAY_OF_WEEK:
1513: strings = (style == LONG) ? symbols.getWeekdays() : symbols
1514: .getShortWeekdays();
1515: break;
1516:
1517: case AM_PM:
1518: strings = symbols.getAmPmStrings();
1519: break;
1520: }
1521: return strings;
1522: }
1523:
1524: /**
1525: * Fills in any unset fields in the calendar fields. First, the {@link
1526: * #computeTime()} method is called if the time value (millisecond offset
1527: * from the <a href="#Epoch">Epoch</a>) has not been calculated from
1528: * calendar field values. Then, the {@link #computeFields()} method is
1529: * called to calculate all calendar field values.
1530: */
1531: protected void complete() {
1532: if (!isTimeSet)
1533: updateTime();
1534: if (!areFieldsSet || !areAllFieldsSet) {
1535: computeFields(); // fills in unset fields
1536: areAllFieldsSet = areFieldsSet = true;
1537: }
1538: }
1539:
1540: /**
1541: * Returns whether the value of the specified calendar field has been set
1542: * externally by calling one of the setter methods rather than by the
1543: * internal time calculation.
1544: *
1545: * @return <code>true</code> if the field has been set externally,
1546: * <code>false</code> otherwise.
1547: * @exception IndexOutOfBoundsException if the specified
1548: * <code>field</code> is out of range
1549: * (<code>field < 0 || field >= FIELD_COUNT</code>).
1550: * @see #selectFields()
1551: * @see #setFieldsComputed(int)
1552: */
1553: final boolean isExternallySet(int field) {
1554: return stamp[field] >= MINIMUM_USER_STAMP;
1555: }
1556:
1557: /**
1558: * Returns a field mask (bit mask) indicating all calendar fields that
1559: * have the state of externally or internally set.
1560: *
1561: * @return a bit mask indicating set state fields
1562: */
1563: final int getSetStateFields() {
1564: int mask = 0;
1565: for (int i = 0; i < fields.length; i++) {
1566: if (stamp[i] != UNSET) {
1567: mask |= 1 << i;
1568: }
1569: }
1570: return mask;
1571: }
1572:
1573: /**
1574: * Sets the state of the specified calendar fields to
1575: * <em>computed</em>. This state means that the specified calendar fields
1576: * have valid values that have been set by internal time calculation
1577: * rather than by calling one of the setter methods.
1578: *
1579: * @param fieldMask the field to be marked as computed.
1580: * @exception IndexOutOfBoundsException if the specified
1581: * <code>field</code> is out of range
1582: * (<code>field < 0 || field >= FIELD_COUNT</code>).
1583: * @see #isExternallySet(int)
1584: * @see #selectFields()
1585: */
1586: final void setFieldsComputed(int fieldMask) {
1587: if (fieldMask == ALL_FIELDS) {
1588: for (int i = 0; i < fields.length; i++) {
1589: stamp[i] = COMPUTED;
1590: isSet[i] = true;
1591: }
1592: areFieldsSet = areAllFieldsSet = true;
1593: } else {
1594: for (int i = 0; i < fields.length; i++) {
1595: if ((fieldMask & 1) == 1) {
1596: stamp[i] = COMPUTED;
1597: isSet[i] = true;
1598: } else {
1599: if (areAllFieldsSet && !isSet[i]) {
1600: areAllFieldsSet = false;
1601: }
1602: }
1603: fieldMask >>>= 1;
1604: }
1605: }
1606: }
1607:
1608: /**
1609: * Sets the state of the calendar fields that are <em>not</em> specified
1610: * by <code>fieldMask</code> to <em>unset</em>. If <code>fieldMask</code>
1611: * specifies all the calendar fields, then the state of this
1612: * <code>Calendar</code> becomes that all the calendar fields are in sync
1613: * with the time value (millisecond offset from the Epoch).
1614: *
1615: * @param fieldMask the field mask indicating which calendar fields are in
1616: * sync with the time value.
1617: * @exception IndexOutOfBoundsException if the specified
1618: * <code>field</code> is out of range
1619: * (<code>field < 0 || field >= FIELD_COUNT</code>).
1620: * @see #isExternallySet(int)
1621: * @see #selectFields()
1622: */
1623: final void setFieldsNormalized(int fieldMask) {
1624: if (fieldMask != ALL_FIELDS) {
1625: for (int i = 0; i < fields.length; i++) {
1626: if ((fieldMask & 1) == 0) {
1627: stamp[i] = fields[i] = 0; // UNSET == 0
1628: isSet[i] = false;
1629: }
1630: fieldMask >>= 1;
1631: }
1632: }
1633:
1634: // Some or all of the fields are in sync with the
1635: // milliseconds, but the stamp values are not normalized yet.
1636: areFieldsSet = true;
1637: areAllFieldsSet = false;
1638: }
1639:
1640: /**
1641: * Returns whether the calendar fields are partially in sync with the time
1642: * value or fully in sync but not stamp values are not normalized yet.
1643: */
1644: final boolean isPartiallyNormalized() {
1645: return areFieldsSet && !areAllFieldsSet;
1646: }
1647:
1648: /**
1649: * Returns whether the calendar fields are fully in sync with the time
1650: * value.
1651: */
1652: final boolean isFullyNormalized() {
1653: return areFieldsSet && areAllFieldsSet;
1654: }
1655:
1656: /**
1657: * Marks this Calendar as not sync'd.
1658: */
1659: final void setUnnormalized() {
1660: areFieldsSet = areAllFieldsSet = false;
1661: }
1662:
1663: /**
1664: * Returns whether the specified <code>field</code> is on in the
1665: * <code>fieldMask</code>.
1666: */
1667: static final boolean isFieldSet(int fieldMask, int field) {
1668: return (fieldMask & (1 << field)) != 0;
1669: }
1670:
1671: /**
1672: * Returns a field mask indicating which calendar field values
1673: * to be used to calculate the time value. The calendar fields are
1674: * returned as a bit mask, each bit of which corresponds to a field, i.e.,
1675: * the mask value of <code>field</code> is <code>(1 <<
1676: * field)</code>. For example, 0x26 represents the <code>YEAR</code>,
1677: * <code>MONTH</code>, and <code>DAY_OF_MONTH</code> fields (i.e., 0x26 is
1678: * equal to
1679: * <code>(1<<YEAR)|(1<<MONTH)|(1<<DAY_OF_MONTH))</code>.
1680: *
1681: * <p>This method supports the calendar fields resolution as described in
1682: * the class description. If the bit mask for a given field is on and its
1683: * field has not been set (i.e., <code>isSet(field)</code> is
1684: * <code>false</code>), then the default value of the field has to be
1685: * used, which case means that the field has been selected because the
1686: * selected combination involves the field.
1687: *
1688: * @return a bit mask of selected fields
1689: * @see #isExternallySet(int)
1690: * @see #setInternallySetState(int)
1691: */
1692: final int selectFields() {
1693: // This implementation has been taken from the GregorianCalendar class.
1694:
1695: // The YEAR field must always be used regardless of its SET
1696: // state because YEAR is a mandatory field to determine the date
1697: // and the default value (EPOCH_YEAR) may change through the
1698: // normalization process.
1699: int fieldMask = YEAR_MASK;
1700:
1701: if (stamp[ERA] != UNSET) {
1702: fieldMask |= ERA_MASK;
1703: }
1704: // Find the most recent group of fields specifying the day within
1705: // the year. These may be any of the following combinations:
1706: // MONTH + DAY_OF_MONTH
1707: // MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
1708: // MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
1709: // DAY_OF_YEAR
1710: // WEEK_OF_YEAR + DAY_OF_WEEK
1711: // We look for the most recent of the fields in each group to determine
1712: // the age of the group. For groups involving a week-related field such
1713: // as WEEK_OF_MONTH, DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR, both the
1714: // week-related field and the DAY_OF_WEEK must be set for the group as a
1715: // whole to be considered. (See bug 4153860 - liu 7/24/98.)
1716: int dowStamp = stamp[DAY_OF_WEEK];
1717: int monthStamp = stamp[MONTH];
1718: int domStamp = stamp[DAY_OF_MONTH];
1719: int womStamp = aggregateStamp(stamp[WEEK_OF_MONTH], dowStamp);
1720: int dowimStamp = aggregateStamp(stamp[DAY_OF_WEEK_IN_MONTH],
1721: dowStamp);
1722: int doyStamp = stamp[DAY_OF_YEAR];
1723: int woyStamp = aggregateStamp(stamp[WEEK_OF_YEAR], dowStamp);
1724:
1725: int bestStamp = domStamp;
1726: if (womStamp > bestStamp) {
1727: bestStamp = womStamp;
1728: }
1729: if (dowimStamp > bestStamp) {
1730: bestStamp = dowimStamp;
1731: }
1732: if (doyStamp > bestStamp) {
1733: bestStamp = doyStamp;
1734: }
1735: if (woyStamp > bestStamp) {
1736: bestStamp = woyStamp;
1737: }
1738:
1739: /* No complete combination exists. Look for WEEK_OF_MONTH,
1740: * DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR alone. Treat DAY_OF_WEEK alone
1741: * as DAY_OF_WEEK_IN_MONTH.
1742: */
1743: if (bestStamp == UNSET) {
1744: womStamp = stamp[WEEK_OF_MONTH];
1745: dowimStamp = Math
1746: .max(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp);
1747: woyStamp = stamp[WEEK_OF_YEAR];
1748: bestStamp = Math.max(Math.max(womStamp, dowimStamp),
1749: woyStamp);
1750:
1751: /* Treat MONTH alone or no fields at all as DAY_OF_MONTH. This may
1752: * result in bestStamp = domStamp = UNSET if no fields are set,
1753: * which indicates DAY_OF_MONTH.
1754: */
1755: if (bestStamp == UNSET) {
1756: bestStamp = domStamp = monthStamp;
1757: }
1758: }
1759:
1760: if (bestStamp == domStamp
1761: || (bestStamp == womStamp && stamp[WEEK_OF_MONTH] >= stamp[WEEK_OF_YEAR])
1762: || (bestStamp == dowimStamp && stamp[DAY_OF_WEEK_IN_MONTH] >= stamp[WEEK_OF_YEAR])) {
1763: fieldMask |= MONTH_MASK;
1764: if (bestStamp == domStamp) {
1765: fieldMask |= DAY_OF_MONTH_MASK;
1766: } else {
1767: assert (bestStamp == womStamp || bestStamp == dowimStamp);
1768: if (dowStamp != UNSET) {
1769: fieldMask |= DAY_OF_WEEK_MASK;
1770: }
1771: if (womStamp == dowimStamp) {
1772: // When they are equal, give the priority to
1773: // WEEK_OF_MONTH for compatibility.
1774: if (stamp[WEEK_OF_MONTH] >= stamp[DAY_OF_WEEK_IN_MONTH]) {
1775: fieldMask |= WEEK_OF_MONTH_MASK;
1776: } else {
1777: fieldMask |= DAY_OF_WEEK_IN_MONTH_MASK;
1778: }
1779: } else {
1780: if (bestStamp == womStamp) {
1781: fieldMask |= WEEK_OF_MONTH_MASK;
1782: } else {
1783: assert (bestStamp == dowimStamp);
1784: if (stamp[DAY_OF_WEEK_IN_MONTH] != UNSET) {
1785: fieldMask |= DAY_OF_WEEK_IN_MONTH_MASK;
1786: }
1787: }
1788: }
1789: }
1790: } else {
1791: assert (bestStamp == doyStamp || bestStamp == woyStamp || bestStamp == UNSET);
1792: if (bestStamp == doyStamp) {
1793: fieldMask |= DAY_OF_YEAR_MASK;
1794: } else {
1795: assert (bestStamp == woyStamp);
1796: if (dowStamp != UNSET) {
1797: fieldMask |= DAY_OF_WEEK_MASK;
1798: }
1799: fieldMask |= WEEK_OF_YEAR_MASK;
1800: }
1801: }
1802:
1803: // Find the best set of fields specifying the time of day. There
1804: // are only two possibilities here; the HOUR_OF_DAY or the
1805: // AM_PM and the HOUR.
1806: int hourOfDayStamp = stamp[HOUR_OF_DAY];
1807: int hourStamp = aggregateStamp(stamp[HOUR], stamp[AM_PM]);
1808: bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp
1809: : hourOfDayStamp;
1810:
1811: // if bestStamp is still UNSET, then take HOUR or AM_PM. (See 4846659)
1812: if (bestStamp == UNSET) {
1813: bestStamp = Math.max(stamp[HOUR], stamp[AM_PM]);
1814: }
1815:
1816: // Hours
1817: if (bestStamp != UNSET) {
1818: if (bestStamp == hourOfDayStamp) {
1819: fieldMask |= HOUR_OF_DAY_MASK;
1820: } else {
1821: fieldMask |= HOUR_MASK;
1822: if (stamp[AM_PM] != UNSET) {
1823: fieldMask |= AM_PM_MASK;
1824: }
1825: }
1826: }
1827: if (stamp[MINUTE] != UNSET) {
1828: fieldMask |= MINUTE_MASK;
1829: }
1830: if (stamp[SECOND] != UNSET) {
1831: fieldMask |= SECOND_MASK;
1832: }
1833: if (stamp[MILLISECOND] != UNSET) {
1834: fieldMask |= MILLISECOND_MASK;
1835: }
1836: if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP) {
1837: fieldMask |= ZONE_OFFSET_MASK;
1838: }
1839: if (stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) {
1840: fieldMask |= DST_OFFSET_MASK;
1841: }
1842:
1843: return fieldMask;
1844: }
1845:
1846: /**
1847: * Returns the pseudo-time-stamp for two fields, given their
1848: * individual pseudo-time-stamps. If either of the fields
1849: * is unset, then the aggregate is unset. Otherwise, the
1850: * aggregate is the later of the two stamps.
1851: */
1852: private static final int aggregateStamp(int stamp_a, int stamp_b) {
1853: if (stamp_a == UNSET || stamp_b == UNSET) {
1854: return UNSET;
1855: }
1856: return (stamp_a > stamp_b) ? stamp_a : stamp_b;
1857: }
1858:
1859: /**
1860: * Compares this <code>Calendar</code> to the specified
1861: * <code>Object</code>. The result is <code>true</code> if and only if
1862: * the argument is a <code>Calendar</code> object of the same calendar
1863: * system that represents the same time value (millisecond offset from the
1864: * <a href="#Epoch">Epoch</a>) under the same
1865: * <code>Calendar</code> parameters as this object.
1866: *
1867: * <p>The <code>Calendar</code> parameters are the values represented
1868: * by the <code>isLenient</code>, <code>getFirstDayOfWeek</code>,
1869: * <code>getMinimalDaysInFirstWeek</code> and <code>getTimeZone</code>
1870: * methods. If there is any difference in those parameters
1871: * between the two <code>Calendar</code>s, this method returns
1872: * <code>false</code>.
1873: *
1874: * <p>Use the {@link #compareTo(Calendar) compareTo} method to
1875: * compare only the time values.
1876: *
1877: * @param obj the object to compare with.
1878: * @return <code>true</code> if this object is equal to <code>obj</code>;
1879: * <code>false</code> otherwise.
1880: */
1881: public boolean equals(Object obj) {
1882: if (this == obj)
1883: return true;
1884: try {
1885: Calendar that = (Calendar) obj;
1886: return compareTo(getMillisOf(that)) == 0
1887: && lenient == that.lenient
1888: && firstDayOfWeek == that.firstDayOfWeek
1889: && minimalDaysInFirstWeek == that.minimalDaysInFirstWeek
1890: && zone.equals(that.zone);
1891: } catch (Exception e) {
1892: // Note: GregorianCalendar.computeTime throws
1893: // IllegalArgumentException if the ERA value is invalid
1894: // even it's in lenient mode.
1895: }
1896: return false;
1897: }
1898:
1899: /**
1900: * Returns a hash code for this calendar.
1901: *
1902: * @return a hash code value for this object.
1903: * @since 1.2
1904: */
1905: public int hashCode() {
1906: // 'otheritems' represents the hash code for the previous versions.
1907: int otheritems = (lenient ? 1 : 0) | (firstDayOfWeek << 1)
1908: | (minimalDaysInFirstWeek << 4)
1909: | (zone.hashCode() << 7);
1910: long t = getMillisOf(this );
1911: return (int) t ^ (int) (t >> 32) ^ otheritems;
1912: }
1913:
1914: /**
1915: * Returns whether this <code>Calendar</code> represents a time
1916: * before the time represented by the specified
1917: * <code>Object</code>. This method is equivalent to:
1918: * <pre><blockquote>
1919: * compareTo(when) < 0
1920: * </blockquote></pre>
1921: * if and only if <code>when</code> is a <code>Calendar</code>
1922: * instance. Otherwise, the method returns <code>false</code>.
1923: *
1924: * @param when the <code>Object</code> to be compared
1925: * @return <code>true</code> if the time of this
1926: * <code>Calendar</code> is before the time represented by
1927: * <code>when</code>; <code>false</code> otherwise.
1928: * @see #compareTo(Calendar)
1929: */
1930: public boolean before(Object when) {
1931: return when instanceof Calendar
1932: && compareTo((Calendar) when) < 0;
1933: }
1934:
1935: /**
1936: * Returns whether this <code>Calendar</code> represents a time
1937: * after the time represented by the specified
1938: * <code>Object</code>. This method is equivalent to:
1939: * <pre><blockquote>
1940: * compareTo(when) > 0
1941: * </blockquote></pre>
1942: * if and only if <code>when</code> is a <code>Calendar</code>
1943: * instance. Otherwise, the method returns <code>false</code>.
1944: *
1945: * @param when the <code>Object</code> to be compared
1946: * @return <code>true</code> if the time of this <code>Calendar</code> is
1947: * after the time represented by <code>when</code>; <code>false</code>
1948: * otherwise.
1949: * @see #compareTo(Calendar)
1950: */
1951: public boolean after(Object when) {
1952: return when instanceof Calendar
1953: && compareTo((Calendar) when) > 0;
1954: }
1955:
1956: /**
1957: * Compares the time values (millisecond offsets from the <a
1958: * href="#Epoch">Epoch</a>) represented by two
1959: * <code>Calendar</code> objects.
1960: *
1961: * @param anotherCalendar the <code>Calendar</code> to be compared.
1962: * @return the value <code>0</code> if the time represented by the argument
1963: * is equal to the time represented by this <code>Calendar</code>; a value
1964: * less than <code>0</code> if the time of this <code>Calendar</code> is
1965: * before the time represented by the argument; and a value greater than
1966: * <code>0</code> if the time of this <code>Calendar</code> is after the
1967: * time represented by the argument.
1968: * @exception NullPointerException if the specified <code>Calendar</code> is
1969: * <code>null</code>.
1970: * @exception IllegalArgumentException if the time value of the
1971: * specified <code>Calendar</code> object can't be obtained due to
1972: * any invalid calendar values.
1973: * @since 1.5
1974: */
1975: public int compareTo(Calendar anotherCalendar) {
1976: return compareTo(getMillisOf(anotherCalendar));
1977: }
1978:
1979: /**
1980: * Adds or subtracts the specified amount of time to the given calendar field,
1981: * based on the calendar's rules. For example, to subtract 5 days from
1982: * the current time of the calendar, you can achieve it by calling:
1983: * <p><code>add(Calendar.DAY_OF_MONTH, -5)</code>.
1984: *
1985: * @param field the calendar field.
1986: * @param amount the amount of date or time to be added to the field.
1987: * @see #roll(int,int)
1988: * @see #set(int,int)
1989: */
1990: abstract public void add(int field, int amount);
1991:
1992: /**
1993: * Adds or subtracts (up/down) a single unit of time on the given time
1994: * field without changing larger fields. For example, to roll the current
1995: * date up by one day, you can achieve it by calling:
1996: * <p>roll(Calendar.DATE, true).
1997: * When rolling on the year or Calendar.YEAR field, it will roll the year
1998: * value in the range between 1 and the value returned by calling
1999: * <code>getMaximum(Calendar.YEAR)</code>.
2000: * When rolling on the month or Calendar.MONTH field, other fields like
2001: * date might conflict and, need to be changed. For instance,
2002: * rolling the month on the date 01/31/96 will result in 02/29/96.
2003: * When rolling on the hour-in-day or Calendar.HOUR_OF_DAY field, it will
2004: * roll the hour value in the range between 0 and 23, which is zero-based.
2005: *
2006: * @param field the time field.
2007: * @param up indicates if the value of the specified time field is to be
2008: * rolled up or rolled down. Use true if rolling up, false otherwise.
2009: * @see Calendar#add(int,int)
2010: * @see Calendar#set(int,int)
2011: */
2012: abstract public void roll(int field, boolean up);
2013:
2014: /**
2015: * Adds the specified (signed) amount to the specified calendar field
2016: * without changing larger fields. A negative amount means to roll
2017: * down.
2018: *
2019: * <p>NOTE: This default implementation on <code>Calendar</code> just repeatedly calls the
2020: * version of {@link #roll(int,boolean) roll()} that rolls by one unit. This may not
2021: * always do the right thing. For example, if the <code>DAY_OF_MONTH</code> field is 31,
2022: * rolling through February will leave it set to 28. The <code>GregorianCalendar</code>
2023: * version of this function takes care of this problem. Other subclasses
2024: * should also provide overrides of this function that do the right thing.
2025: *
2026: * @param field the calendar field.
2027: * @param amount the signed amount to add to the calendar <code>field</code>.
2028: * @since 1.2
2029: * @see #roll(int,boolean)
2030: * @see #add(int,int)
2031: * @see #set(int,int)
2032: */
2033: public void roll(int field, int amount) {
2034: while (amount > 0) {
2035: roll(field, true);
2036: amount--;
2037: }
2038: while (amount < 0) {
2039: roll(field, false);
2040: amount++;
2041: }
2042: }
2043:
2044: /**
2045: * Sets the time zone with the given time zone value.
2046: *
2047: * @param value the given time zone.
2048: */
2049: public void setTimeZone(TimeZone value) {
2050: zone = value;
2051: sharedZone = false;
2052: /* Recompute the fields from the time using the new zone. This also
2053: * works if isTimeSet is false (after a call to set()). In that case
2054: * the time will be computed from the fields using the new zone, then
2055: * the fields will get recomputed from that. Consider the sequence of
2056: * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST).
2057: * Is cal set to 1 o'clock EST or 1 o'clock PST? Answer: PST. More
2058: * generally, a call to setTimeZone() affects calls to set() BEFORE AND
2059: * AFTER it up to the next call to complete().
2060: */
2061: areAllFieldsSet = areFieldsSet = false;
2062: }
2063:
2064: /**
2065: * Gets the time zone.
2066: *
2067: * @return the time zone object associated with this calendar.
2068: */
2069: public TimeZone getTimeZone() {
2070: // If the TimeZone object is shared by other Calendar instances, then
2071: // create a clone.
2072: if (sharedZone) {
2073: zone = (TimeZone) zone.clone();
2074: sharedZone = false;
2075: }
2076: return zone;
2077: }
2078:
2079: /**
2080: * Returns the time zone (without cloning).
2081: */
2082: TimeZone getZone() {
2083: return zone;
2084: }
2085:
2086: /**
2087: * Sets the sharedZone flag to <code>shared</code>.
2088: */
2089: void setZoneShared(boolean shared) {
2090: sharedZone = shared;
2091: }
2092:
2093: /**
2094: * Specifies whether or not date/time interpretation is to be lenient. With
2095: * lenient interpretation, a date such as "February 942, 1996" will be
2096: * treated as being equivalent to the 941st day after February 1, 1996.
2097: * With strict (non-lenient) interpretation, such dates will cause an exception to be
2098: * thrown. The default is lenient.
2099: *
2100: * @param lenient <code>true</code> if the lenient mode is to be turned
2101: * on; <code>false</code> if it is to be turned off.
2102: * @see #isLenient()
2103: * @see java.text.DateFormat#setLenient
2104: */
2105: public void setLenient(boolean lenient) {
2106: this .lenient = lenient;
2107: }
2108:
2109: /**
2110: * Tells whether date/time interpretation is to be lenient.
2111: *
2112: * @return <code>true</code> if the interpretation mode of this calendar is lenient;
2113: * <code>false</code> otherwise.
2114: * @see #setLenient(boolean)
2115: */
2116: public boolean isLenient() {
2117: return lenient;
2118: }
2119:
2120: /**
2121: * Sets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S.,
2122: * <code>MONDAY</code> in France.
2123: *
2124: * @param value the given first day of the week.
2125: * @see #getFirstDayOfWeek()
2126: * @see #getMinimalDaysInFirstWeek()
2127: */
2128: public void setFirstDayOfWeek(int value) {
2129: if (firstDayOfWeek == value) {
2130: return;
2131: }
2132: firstDayOfWeek = value;
2133: invalidateWeekFields();
2134: }
2135:
2136: /**
2137: * Gets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S.,
2138: * <code>MONDAY</code> in France.
2139: *
2140: * @return the first day of the week.
2141: * @see #setFirstDayOfWeek(int)
2142: * @see #getMinimalDaysInFirstWeek()
2143: */
2144: public int getFirstDayOfWeek() {
2145: return firstDayOfWeek;
2146: }
2147:
2148: /**
2149: * Sets what the minimal days required in the first week of the year are;
2150: * For example, if the first week is defined as one that contains the first
2151: * day of the first month of a year, call this method with value 1. If it
2152: * must be a full week, use value 7.
2153: *
2154: * @param value the given minimal days required in the first week
2155: * of the year.
2156: * @see #getMinimalDaysInFirstWeek()
2157: */
2158: public void setMinimalDaysInFirstWeek(int value) {
2159: if (minimalDaysInFirstWeek == value) {
2160: return;
2161: }
2162: minimalDaysInFirstWeek = value;
2163: invalidateWeekFields();
2164: }
2165:
2166: /**
2167: * Gets what the minimal days required in the first week of the year are;
2168: * e.g., if the first week is defined as one that contains the first day
2169: * of the first month of a year, this method returns 1. If
2170: * the minimal days required must be a full week, this method
2171: * returns 7.
2172: *
2173: * @return the minimal days required in the first week of the year.
2174: * @see #setMinimalDaysInFirstWeek(int)
2175: */
2176: public int getMinimalDaysInFirstWeek() {
2177: return minimalDaysInFirstWeek;
2178: }
2179:
2180: /**
2181: * Returns the minimum value for the given calendar field of this
2182: * <code>Calendar</code> instance. The minimum value is defined as
2183: * the smallest value returned by the {@link #get(int) get} method
2184: * for any possible time value. The minimum value depends on
2185: * calendar system specific parameters of the instance.
2186: *
2187: * @param field the calendar field.
2188: * @return the minimum value for the given calendar field.
2189: * @see #getMaximum(int)
2190: * @see #getGreatestMinimum(int)
2191: * @see #getLeastMaximum(int)
2192: * @see #getActualMinimum(int)
2193: * @see #getActualMaximum(int)
2194: */
2195: abstract public int getMinimum(int field);
2196:
2197: /**
2198: * Returns the maximum value for the given calendar field of this
2199: * <code>Calendar</code> instance. The maximum value is defined as
2200: * the largest value returned by the {@link #get(int) get} method
2201: * for any possible time value. The maximum value depends on
2202: * calendar system specific parameters of the instance.
2203: *
2204: * @param field the calendar field.
2205: * @return the maximum value for the given calendar field.
2206: * @see #getMinimum(int)
2207: * @see #getGreatestMinimum(int)
2208: * @see #getLeastMaximum(int)
2209: * @see #getActualMinimum(int)
2210: * @see #getActualMaximum(int)
2211: */
2212: abstract public int getMaximum(int field);
2213:
2214: /**
2215: * Returns the highest minimum value for the given calendar field
2216: * of this <code>Calendar</code> instance. The highest minimum
2217: * value is defined as the largest value returned by {@link
2218: * #getActualMinimum(int)} for any possible time value. The
2219: * greatest minimum value depends on calendar system specific
2220: * parameters of the instance.
2221: *
2222: * @param field the calendar field.
2223: * @return the highest minimum value for the given calendar field.
2224: * @see #getMinimum(int)
2225: * @see #getMaximum(int)
2226: * @see #getLeastMaximum(int)
2227: * @see #getActualMinimum(int)
2228: * @see #getActualMaximum(int)
2229: */
2230: abstract public int getGreatestMinimum(int field);
2231:
2232: /**
2233: * Returns the lowest maximum value for the given calendar field
2234: * of this <code>Calendar</code> instance. The lowest maximum
2235: * value is defined as the smallest value returned by {@link
2236: * #getActualMaximum(int)} for any possible time value. The least
2237: * maximum value depends on calendar system specific parameters of
2238: * the instance. For example, a <code>Calendar</code> for the
2239: * Gregorian calendar system returns 28 for the
2240: * <code>DAY_OF_MONTH</code> field, because the 28th is the last
2241: * day of the shortest month of this calendar, February in a
2242: * common year.
2243: *
2244: * @param field the calendar field.
2245: * @return the lowest maximum value for the given calendar field.
2246: * @see #getMinimum(int)
2247: * @see #getMaximum(int)
2248: * @see #getGreatestMinimum(int)
2249: * @see #getActualMinimum(int)
2250: * @see #getActualMaximum(int)
2251: */
2252: abstract public int getLeastMaximum(int field);
2253:
2254: /**
2255: * Returns the minimum value that the specified calendar field
2256: * could have, given the time value of this <code>Calendar</code>.
2257: *
2258: * <p>The default implementation of this method uses an iterative
2259: * algorithm to determine the actual minimum value for the
2260: * calendar field. Subclasses should, if possible, override this
2261: * with a more efficient implementation - in many cases, they can
2262: * simply return <code>getMinimum()</code>.
2263: *
2264: * @param field the calendar field
2265: * @return the minimum of the given calendar field for the time
2266: * value of this <code>Calendar</code>
2267: * @see #getMinimum(int)
2268: * @see #getMaximum(int)
2269: * @see #getGreatestMinimum(int)
2270: * @see #getLeastMaximum(int)
2271: * @see #getActualMaximum(int)
2272: * @since 1.2
2273: */
2274: public int getActualMinimum(int field) {
2275: int fieldValue = getGreatestMinimum(field);
2276: int endValue = getMinimum(field);
2277:
2278: // if we know that the minimum value is always the same, just return it
2279: if (fieldValue == endValue) {
2280: return fieldValue;
2281: }
2282:
2283: // clone the calendar so we don't mess with the real one, and set it to
2284: // accept anything for the field values
2285: Calendar work = (Calendar) this .clone();
2286: work.setLenient(true);
2287:
2288: // now try each value from getLeastMaximum() to getMaximum() one by one until
2289: // we get a value that normalizes to another value. The last value that
2290: // normalizes to itself is the actual minimum for the current date
2291: int result = fieldValue;
2292:
2293: do {
2294: work.set(field, fieldValue);
2295: if (work.get(field) != fieldValue) {
2296: break;
2297: } else {
2298: result = fieldValue;
2299: fieldValue--;
2300: }
2301: } while (fieldValue >= endValue);
2302:
2303: return result;
2304: }
2305:
2306: /**
2307: * Returns the maximum value that the specified calendar field
2308: * could have, given the time value of this
2309: * <code>Calendar</code>. For example, the actual maximum value of
2310: * the <code>MONTH</code> field is 12 in some years, and 13 in
2311: * other years in the Hebrew calendar system.
2312: *
2313: * <p>The default implementation of this method uses an iterative
2314: * algorithm to determine the actual maximum value for the
2315: * calendar field. Subclasses should, if possible, override this
2316: * with a more efficient implementation.
2317: *
2318: * @param field the calendar field
2319: * @return the maximum of the given calendar field for the time
2320: * value of this <code>Calendar</code>
2321: * @see #getMinimum(int)
2322: * @see #getMaximum(int)
2323: * @see #getGreatestMinimum(int)
2324: * @see #getLeastMaximum(int)
2325: * @see #getActualMinimum(int)
2326: * @since 1.2
2327: */
2328: public int getActualMaximum(int field) {
2329: int fieldValue = getLeastMaximum(field);
2330: int endValue = getMaximum(field);
2331:
2332: // if we know that the maximum value is always the same, just return it.
2333: if (fieldValue == endValue) {
2334: return fieldValue;
2335: }
2336:
2337: // clone the calendar so we don't mess with the real one, and set it to
2338: // accept anything for the field values.
2339: Calendar work = (Calendar) this .clone();
2340: work.setLenient(true);
2341:
2342: // if we're counting weeks, set the day of the week to Sunday. We know the
2343: // last week of a month or year will contain the first day of the week.
2344: if (field == WEEK_OF_YEAR || field == WEEK_OF_MONTH)
2345: work.set(DAY_OF_WEEK, firstDayOfWeek);
2346:
2347: // now try each value from getLeastMaximum() to getMaximum() one by one until
2348: // we get a value that normalizes to another value. The last value that
2349: // normalizes to itself is the actual maximum for the current date
2350: int result = fieldValue;
2351:
2352: do {
2353: work.set(field, fieldValue);
2354: if (work.get(field) != fieldValue) {
2355: break;
2356: } else {
2357: result = fieldValue;
2358: fieldValue++;
2359: }
2360: } while (fieldValue <= endValue);
2361:
2362: return result;
2363: }
2364:
2365: /**
2366: * Creates and returns a copy of this object.
2367: *
2368: * @return a copy of this object.
2369: */
2370: public Object clone() {
2371: try {
2372: Calendar other = (Calendar) super .clone();
2373:
2374: other.fields = new int[FIELD_COUNT];
2375: other.isSet = new boolean[FIELD_COUNT];
2376: other.stamp = new int[FIELD_COUNT];
2377: for (int i = 0; i < FIELD_COUNT; i++) {
2378: other.fields[i] = fields[i];
2379: other.stamp[i] = stamp[i];
2380: other.isSet[i] = isSet[i];
2381: }
2382: other.zone = (TimeZone) zone.clone();
2383: return other;
2384: } catch (CloneNotSupportedException e) {
2385: // this shouldn't happen, since we are Cloneable
2386: throw new InternalError();
2387: }
2388: }
2389:
2390: private static final String[] FIELD_NAME = { "ERA", "YEAR",
2391: "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH",
2392: "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH",
2393: "AM_PM", "HOUR", "HOUR_OF_DAY", "MINUTE", "SECOND",
2394: "MILLISECOND", "ZONE_OFFSET", "DST_OFFSET" };
2395:
2396: /**
2397: * Returns the name of the specified calendar field.
2398: *
2399: * @param field the calendar field
2400: * @return the calendar field name
2401: * @exception IndexOutOfBoundsException if <code>field</code> is negative,
2402: * equal to or greater then <code>FIELD_COUNT</code>.
2403: */
2404: static final String getFieldName(int field) {
2405: return FIELD_NAME[field];
2406: }
2407:
2408: /**
2409: * Return a string representation of this calendar. This method
2410: * is intended to be used only for debugging purposes, and the
2411: * format of the returned string may vary between implementations.
2412: * The returned string may be empty but may not be <code>null</code>.
2413: *
2414: * @return a string representation of this calendar.
2415: */
2416: public String toString() {
2417: // NOTE: BuddhistCalendar.toString() interprets the string
2418: // produced by this method so that the Gregorian year number
2419: // is substituted by its B.E. year value. It relies on
2420: // "...,YEAR=<year>,..." or "...,YEAR=?,...".
2421: StringBuilder buffer = new StringBuilder(800);
2422: buffer.append(getClass().getName()).append('[');
2423: appendValue(buffer, "time", isTimeSet, time);
2424: buffer.append(",areFieldsSet=").append(areFieldsSet);
2425: buffer.append(",areAllFieldsSet=").append(areAllFieldsSet);
2426: buffer.append(",lenient=").append(lenient);
2427: buffer.append(",zone=").append(zone);
2428: appendValue(buffer, ",firstDayOfWeek", true,
2429: (long) firstDayOfWeek);
2430: appendValue(buffer, ",minimalDaysInFirstWeek", true,
2431: (long) minimalDaysInFirstWeek);
2432: for (int i = 0; i < FIELD_COUNT; ++i) {
2433: buffer.append(',');
2434: appendValue(buffer, FIELD_NAME[i], isSet(i),
2435: (long) fields[i]);
2436: }
2437: buffer.append(']');
2438: return buffer.toString();
2439: }
2440:
2441: // =======================privates===============================
2442:
2443: private static final void appendValue(StringBuilder sb,
2444: String item, boolean valid, long value) {
2445: sb.append(item).append('=');
2446: if (valid) {
2447: sb.append(value);
2448: } else {
2449: sb.append('?');
2450: }
2451: }
2452:
2453: /**
2454: * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent.
2455: * They are used to figure out the week count for a specific date for
2456: * a given locale. These must be set when a Calendar is constructed.
2457: * @param desiredLocale the given locale.
2458: */
2459: private void setWeekCountData(Locale desiredLocale) {
2460: /* try to get the Locale data from the cache */
2461: int[] data = cachedLocaleData.get(desiredLocale);
2462: if (data == null) { /* cache miss */
2463: ResourceBundle bundle = LocaleData
2464: .getCalendarData(desiredLocale);
2465: data = new int[2];
2466: data[0] = Integer.parseInt(bundle
2467: .getString("firstDayOfWeek"));
2468: data[1] = Integer.parseInt(bundle
2469: .getString("minimalDaysInFirstWeek"));
2470: cachedLocaleData.put(desiredLocale, data);
2471: }
2472: firstDayOfWeek = data[0];
2473: minimalDaysInFirstWeek = data[1];
2474: }
2475:
2476: /**
2477: * Recomputes the time and updates the status fields isTimeSet
2478: * and areFieldsSet. Callers should check isTimeSet and only
2479: * call this method if isTimeSet is false.
2480: */
2481: private void updateTime() {
2482: computeTime();
2483: // The areFieldsSet and areAllFieldsSet values are no longer
2484: // controlled here (as of 1.5).
2485: isTimeSet = true;
2486: }
2487:
2488: private int compareTo(long t) {
2489: long this Time = getMillisOf(this );
2490: return (this Time > t) ? 1 : (this Time == t) ? 0 : -1;
2491: }
2492:
2493: private static final long getMillisOf(Calendar calendar) {
2494: if (calendar.isTimeSet) {
2495: return calendar.time;
2496: }
2497: Calendar cal = (Calendar) calendar.clone();
2498: cal.setLenient(true);
2499: return cal.getTimeInMillis();
2500: }
2501:
2502: /**
2503: * Adjusts the stamp[] values before nextStamp overflow. nextStamp
2504: * is set to the next stamp value upon the return.
2505: */
2506: private final void adjustStamp() {
2507: int max = MINIMUM_USER_STAMP;
2508: int newStamp = MINIMUM_USER_STAMP;
2509:
2510: for (;;) {
2511: int min = Integer.MAX_VALUE;
2512: for (int i = 0; i < stamp.length; i++) {
2513: int v = stamp[i];
2514: if (v >= newStamp && min > v) {
2515: min = v;
2516: }
2517: if (max < v) {
2518: max = v;
2519: }
2520: }
2521: if (max != min && min == Integer.MAX_VALUE) {
2522: break;
2523: }
2524: for (int i = 0; i < stamp.length; i++) {
2525: if (stamp[i] == min) {
2526: stamp[i] = newStamp;
2527: }
2528: }
2529: newStamp++;
2530: if (min == max) {
2531: break;
2532: }
2533: }
2534: nextStamp = newStamp;
2535: }
2536:
2537: /**
2538: * Sets the WEEK_OF_MONTH and WEEK_OF_YEAR fields to new values with the
2539: * new parameter value if they have been calculated internally.
2540: */
2541: private void invalidateWeekFields() {
2542: if (stamp[WEEK_OF_MONTH] != COMPUTED
2543: && stamp[WEEK_OF_YEAR] != COMPUTED) {
2544: return;
2545: }
2546:
2547: // We have to check the new values of these fields after changing
2548: // firstDayOfWeek and/or minimalDaysInFirstWeek. If the field values
2549: // have been changed, then set the new values. (4822110)
2550: Calendar cal = (Calendar) clone();
2551: cal.setLenient(true);
2552: cal.clear(WEEK_OF_MONTH);
2553: cal.clear(WEEK_OF_YEAR);
2554:
2555: if (stamp[WEEK_OF_MONTH] == COMPUTED) {
2556: int weekOfMonth = cal.get(WEEK_OF_MONTH);
2557: if (fields[WEEK_OF_MONTH] != weekOfMonth) {
2558: fields[WEEK_OF_MONTH] = weekOfMonth;
2559: }
2560: }
2561:
2562: if (stamp[WEEK_OF_YEAR] == COMPUTED) {
2563: int weekOfYear = cal.get(WEEK_OF_YEAR);
2564: if (fields[WEEK_OF_YEAR] != weekOfYear) {
2565: fields[WEEK_OF_YEAR] = weekOfYear;
2566: }
2567: }
2568: }
2569:
2570: /**
2571: * Save the state of this object to a stream (i.e., serialize it).
2572: *
2573: * Ideally, <code>Calendar</code> would only write out its state data and
2574: * the current time, and not write any field data out, such as
2575: * <code>fields[]</code>, <code>isTimeSet</code>, <code>areFieldsSet</code>,
2576: * and <code>isSet[]</code>. <code>nextStamp</code> also should not be part
2577: * of the persistent state. Unfortunately, this didn't happen before JDK 1.1
2578: * shipped. To be compatible with JDK 1.1, we will always have to write out
2579: * the field values and state flags. However, <code>nextStamp</code> can be
2580: * removed from the serialization stream; this will probably happen in the
2581: * near future.
2582: */
2583: private void writeObject(ObjectOutputStream stream)
2584: throws IOException {
2585: // Try to compute the time correctly, for the future (stream
2586: // version 2) in which we don't write out fields[] or isSet[].
2587: if (!isTimeSet) {
2588: try {
2589: updateTime();
2590: } catch (IllegalArgumentException e) {
2591: }
2592: }
2593:
2594: // If this Calendar has a ZoneInfo, save it and set a
2595: // SimpleTimeZone equivalent (as a single DST schedule) for
2596: // backward compatibility.
2597: TimeZone savedZone = null;
2598: if (zone instanceof ZoneInfo) {
2599: SimpleTimeZone stz = ((ZoneInfo) zone)
2600: .getLastRuleInstance();
2601: if (stz == null) {
2602: stz = new SimpleTimeZone(zone.getRawOffset(), zone
2603: .getID());
2604: }
2605: savedZone = zone;
2606: zone = stz;
2607: }
2608:
2609: // Write out the 1.1 FCS object.
2610: stream.defaultWriteObject();
2611:
2612: // Write out the ZoneInfo object
2613: // 4802409: we write out even if it is null, a temporary workaround
2614: // the real fix for bug 4844924 in corba-iiop
2615: stream.writeObject(savedZone);
2616: if (savedZone != null) {
2617: zone = savedZone;
2618: }
2619: }
2620:
2621: /**
2622: * Reconstitutes this object from a stream (i.e., deserialize it).
2623: */
2624: private void readObject(ObjectInputStream stream)
2625: throws IOException, ClassNotFoundException {
2626: final ObjectInputStream input = stream;
2627: input.defaultReadObject();
2628:
2629: stamp = new int[FIELD_COUNT];
2630:
2631: // Starting with version 2 (not implemented yet), we expect that
2632: // fields[], isSet[], isTimeSet, and areFieldsSet may not be
2633: // streamed out anymore. We expect 'time' to be correct.
2634: if (serialVersionOnStream >= 2) {
2635: isTimeSet = true;
2636: if (fields == null)
2637: fields = new int[FIELD_COUNT];
2638: if (isSet == null)
2639: isSet = new boolean[FIELD_COUNT];
2640: } else if (serialVersionOnStream >= 0) {
2641: for (int i = 0; i < FIELD_COUNT; ++i)
2642: stamp[i] = isSet[i] ? COMPUTED : UNSET;
2643: }
2644:
2645: serialVersionOnStream = currentSerialVersion;
2646:
2647: // If there's a ZoneInfo object, use it for zone.
2648: try {
2649: ZoneInfo zi = (ZoneInfo) AccessController
2650: .doPrivileged(new PrivilegedExceptionAction() {
2651: public Object run() throws Exception {
2652: return input.readObject();
2653: }
2654: });
2655: if (zi != null) {
2656: zone = zi;
2657: }
2658: } catch (Exception e) {
2659: }
2660:
2661: // If the deserialized object has a SimpleTimeZone, try to
2662: // replace it with a ZoneInfo equivalent (as of 1.4) in order
2663: // to be compatible with the SimpleTimeZone-based
2664: // implementation as much as possible.
2665: if (zone instanceof SimpleTimeZone) {
2666: String id = zone.getID();
2667: TimeZone zi = TimeZone.getTimeZone(id);
2668: if (zi != null && zi.hasSameRules(zone)
2669: && zi.getID().equals(id)) {
2670: zone = zi;
2671: }
2672: }
2673: }
2674: }
|