Calendar is an abstract base class for converting between a
Date object and a set of integer fields such as
YEAR,
MONTH,
DAY,
HOUR, and so on. (A
Date object represents a
specific instant in time with millisecond precision. See
Date for
information about the
Date class.)
Subclasses of
Calendar interpret a
Dateaccording to the rules of a specific calendar system.
Like other locale-sensitive classes,
Calendar provides a class
method,
getInstance, for getting a default instance of
this class for general use.
Calendar's
getInstance method
returns a calendar whose locale is based on system settings and whose time fields
have been initialized with the current date and time:
Calendar rightNow = Calendar.getInstance()
A
Calendar object can produce all the time field values needed
to implement the date-time formatting for a particular language and calendar
style (for example, Japanese-Gregorian, Japanese-Traditional).
Calendar defines the range of values returned by certain
fields, as well as their meaning. For example, the first month of the year
has value
MONTH ==
JANUARY for all calendars.
Other values are defined by the concrete subclass, such as
ERAand
YEAR. See individual field documentation and subclass
documentation for details.
When a
Calendar is lenient, it accepts a wider
range of field values than it produces. For example, a lenient
GregorianCalendar interprets
MONTH ==
JANUARY,
DAY_OF_MONTH == 32 as February 1. A
non-lenient
GregorianCalendar throws an exception when given
out-of-range field settings. When calendars recompute field values for return
by
get(), they normalize them. For example, a
GregorianCalendar always produces
DAY_OF_MONTHvalues between 1 and the length of the month.
Calendar defines a locale-specific seven day week using two
parameters: the first day of the week and the minimal days in first week
(from 1 to 7). These numbers are taken from the locale resource data when a
Calendar is constructed. They may also be specified explicitly
through the API.
When setting or getting the
WEEK_OF_MONTH or
WEEK_OF_YEAR fields,
Calendar must determine
the first week of the month or year as a reference point. The first week of a
month or year is defined as the earliest seven day period beginning on
getFirstDayOfWeek() and containing at least
getMinimalDaysInFirstWeek() days of that month or year. Weeks
numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow
it. Note that the normalized numbering returned by
get() may
be different. For example, a specific
Calendar subclass may
designate the week before week 1 of a year as week n of the
previous year.
When computing a
Date from time fields, two special
circumstances may arise: there may be insufficient information to compute the
Date (such as only year and month but no day in the month), or
there may be inconsistent information (such as "Tuesday, July 15, 1996" --
July 15, 1996 is actually a Monday).
Insufficient information. The calendar will use default
information to specify the missing fields. This may vary by calendar; for the
Gregorian calendar, the default for a field is the same as that of the start
of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc.
Inconsistent information. If fields conflict, the calendar
will give preference to fields set more recently. For example, when
determining the day, the calendar will look for one of the following
combinations of fields. The most recent combination, as determined by the
most recently set single field, will be used.
MONTH + DAY_OF_MONTH
MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
DAY_OF_YEAR
DAY_OF_WEEK + WEEK_OF_YEAR
For the time of day:
HOUR_OF_DAY
AM_PM + HOUR
Note: There are certain possible ambiguities in
interpretation of certain singular times, which are resolved in the following
ways:
- 24:00:00 "belongs" to the following day. That is, 23:59 on Dec 31, 1969
< 24:00 on Jan 1, 1970 < 24:01:00 on Jan 1, 1970 form a sequence of
three consecutive minutes in time.
- Although historically not precise, midnight also belongs to "am", and
noon belongs to "pm", so on the same day, we have 12:00 am (midnight) < 12:01 am,
and 12:00 pm (noon) < 12:01 pm
The date or time format strings are not part of the definition of a calendar,
as those must be modifiable or overridable by the user at runtime. Use
java.text.DateFormat to format dates.
Field manipulation methods
Calendar fields can be changed using three methods:
set(),
add(), and
roll().
set(f, value) changes field
fto
value. In addition, it sets an internal member variable to
indicate that field
f has been changed. Although field
f is changed immediately, the calendar's milliseconds is not
recomputed until the next call to
get(),
getTime(), or
getTimeInMillis() is made. Thus,
multiple calls to
set() do not trigger multiple, unnecessary
computations. As a result of changing a field using
set(),
other fields may also change, depending on the field, the field value, and
the calendar system. In addition,
get(f) will not necessarily
return
value after the fields have been recomputed. The
specifics are determined by the concrete calendar class.
Example: Consider a
GregorianCalendar originally
set to August 31, 1999. Calling set(Calendar.MONTH,
Calendar.SEPTEMBER)
sets the calendar to September 31, 1999. This is a temporary internal
representation that resolves to October 1, 1999 if
getTime()is
then called. However, a call to
set(Calendar.DAY_OF_MONTH, 30)before the call to
getTime() sets the calendar to September
30, 1999, since no recomputation occurs after
set() itself.
add(f, delta) adds
delta to
field
f. This is equivalent to calling set(f,
get(f) + delta)
with two adjustments:
Add rule 1. The value of field
f after the
call minus the value of field
f before the call is
delta, modulo any overflow that has occurred in field
f. Overflow occurs when a field value exceeds its range and,
as a result, the next larger field is incremented or decremented and the
field value is adjusted back into its range.
Add rule 2. If a smaller field is expected to be invariant,
but  it is impossible for it to be equal to its prior value because of
changes in its minimum or maximum after field
f is changed,
then its value is adjusted to be as close as possible to its expected value.
A smaller field represents a smaller unit of time.
HOUR is a
smaller field than
DAY_OF_MONTH. No adjustment is made to
smaller fields that are not expected to be invariant. The calendar system
determines what fields are expected to be invariant.
In addition, unlike
set(),
add() forces an
immediate recomputation of the calendar's milliseconds and all fields.
Example: Consider a
GregorianCalendar originally
set to August 31, 1999. Calling
add(Calendar.MONTH, 13) sets
the calendar to September 30, 2000. Add rule 1 sets the
MONTH field to September, since adding 13 months to August
gives September of the next year. Since
DAY_OF_MONTH cannot be
31 in September in a
GregorianCalendar, add rule 2
sets the
DAY_OF_MONTH to 30, the closest possible value.
Although it is a smaller field,
DAY_OF_WEEK is not adjusted by
rule 2, since it is expected to change when the month changes in a
GregorianCalendar.
roll(f, delta) adds
delta to
field
f without changing larger fields. This is equivalent to
calling
add(f, delta) with the following adjustment:
Roll rule. Larger fields are unchanged after the call. A
larger field represents a larger unit of time.
DAY_OF_MONTH is
a larger field than
HOUR.
Example: Consider a
GregorianCalendar originally
set to August 31, 1999. Calling roll(Calendar.MONTH,
8)
sets
the calendar to April 30, 1999. Add rule 1 sets the
MONTH field to April. Using a
GregorianCalendar,
the
DAY_OF_MONTH cannot be 31 in the month April. Add rule 2
sets it to the closest possible value, 30. Finally, the roll rule
maintains the
YEAR field value of 1999.
Example: Consider a
GregorianCalendar originally
set to Sunday June 6, 1999. Calling
roll(Calendar.WEEK_OF_MONTH, -1) sets the calendar to Tuesday
June 1, 1999, whereas calling
add(Calendar.WEEK_OF_MONTH, -1)sets the calendar to Sunday May 30, 1999. This is because the roll rule
imposes an additional constraint: The
MONTH must not change
when the
WEEK_OF_MONTH is rolled. Taken together with add rule
1, the resultant date must be between Tuesday June 1 and Saturday June 5.
According to add rule 2, the
DAY_OF_WEEK, an invariant when
changing the
WEEK_OF_MONTH, is set to Tuesday, the closest
possible value to Sunday (where Sunday is the first day of the week).
Usage model. To motivate the behavior of
add()and
roll(), consider a user interface component with
increment and decrement buttons for the month, day, and year, and an
underlying
GregorianCalendar. If the interface reads January
31, 1999 and the user presses the month increment button, what should it
read? If the underlying implementation uses
set(), it might
read March 3, 1999. A better result would be February 28, 1999. Furthermore,
if the user presses the month increment button again, it should read March
31, 1999, not March 28, 1999. By saving the original date and using either
add() or
roll(), depending on whether larger
fields should be affected, the user interface can behave as most users will
intuitively expect.
Note: You should always use
roll and
add rather than
attempting to perform arithmetic operations directly on the fields of a
Calendar. It is quite possible for Calendar subclasses
to have fields with non-linear behavior, for example missing months or days
during non-leap years. The subclasses' add and roll
methods will take this into account, while simple arithmetic manipulations
may give invalid results.