com.ibm.icu.util.Calendar Maven / Gradle / Ivy
/*
* Copyright (C) 1996-2012, International Business Machines
* Corporation and others. All Rights Reserved.
*/
package com.ibm.icu.util;
import java.io.Serializable;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.util.ULocale.Category;
/**
* {@icuenhanced java.util.Calendar}.{@icu _usage_}
*
* 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
* {@link Date}
* for information about the Date
class.)
*
*
Subclasses of Calendar
interpret a Date
* according to the rules of a specific calendar system. ICU4J contains
* several subclasses implementing different international calendar systems.
*
*
* Like other locale-sensitive classes, Calendar
provides a
* class method, getInstance
, for getting a generally useful
* object of this type. Calendar
's getInstance
method
* returns a calendar of a type appropriate to the locale, whose
* time fields have been initialized with the current date and time:
*
* Calendar rightNow = Calendar.getInstance()
*
*
* When a ULocale
is used by getInstance
, its
* 'calendar
' tag and value are retrieved if present. If a recognized
* value is supplied, a calendar is provided and configured as appropriate.
* Currently recognized tags are "buddhist", "chinese", "coptic", "ethiopic",
* "gregorian", "hebrew", "islamic", "islamic-civil", "japanese", and "roc". For
* example:
* Calendar cal = Calendar.getInstance(new ULocale("en_US@calendar=japanese"));
*
will return an instance of JapaneseCalendar (using en_US conventions for
* minimum days in first week, start day of week, et cetera).
*
* 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 ERA
and
* 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_MONTH
* values 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: for some non-Gregorian calendars, different
* fields may be necessary for complete disambiguation. For example, a full
* specification of the historial Arabic astronomical calendar requires year,
* month, day-of-month and day-of-week in some cases.
*
*
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
*
*
- Although historically not precise, midnight also belongs to "am",
* and noon belongs to "pm", so on the same day,
* 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 {@link DateFormat}
* to format dates.
*
*
Field manipulation methods
*
* Calendar
fields can be changed using three methods:
* set()
, add()
, and roll()
.
*
* set(f, value)
changes field
* f
to 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 {@link #roll roll} and {@link #add 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.
*
*
Calendar Architecture in ICU4J
*
* Recently the implementation of Calendar
has changed
* significantly in order to better support subclassing. The original
* Calendar
class was designed to support subclassing, but
* it had only one implemented subclass, GregorianCalendar
.
* With the implementation of several new calendar subclasses, including
* the BuddhistCalendar
, ChineseCalendar
,
* HebrewCalendar
, IslamicCalendar
, and
* JapaneseCalendar
, the subclassing API has been reworked
* thoroughly. This section details the new subclassing API and other
* ways in which com.ibm.icu.util.Calendar
differs from
* java.util.Calendar
.
*
*
* Changes
*
* Overview of changes between the classic Calendar
* architecture and the new architecture.
*
*
*
* - The
fields[]
array is private
now
* instead of protected
. Subclasses must access it
* using the methods {@link #internalSet} and
* {@link #internalGet}. Motivation: Subclasses should
* not directly access data members.
*
* - The
time
long word is private
now
* instead of protected
. Subclasses may access it using
* the method {@link #internalGetTimeInMillis}, which does not
* provoke an update. Motivation: Subclasses should not
* directly access data members.
*
* - The scope of responsibility of subclasses has been drastically
* reduced. As much functionality as possible is implemented in the
*
Calendar
base class. As a result, it is much easier
* to subclass Calendar
. Motivation: Subclasses
* should not have to reimplement common code. Certain behaviors are
* common across calendar systems: The definition and behavior of
* week-related fields and time fields, the arithmetic
* ({@link #add(int, int) add} and {@link #roll(int, int) roll}) behavior of many
* fields, and the field validation system.
*
* - The subclassing API has been completely redesigned.
*
* - The
Calendar
base class contains some Gregorian
* calendar algorithmic support that subclasses can use (specifically
* in {@link #handleComputeFields}). Subclasses can use the
* methods getGregorianXxx()
to obtain precomputed
* values. Motivation: This is required by all
* Calendar
subclasses in order to implement consistent
* time zone behavior, and Gregorian-derived systems can use the
* already computed data.
*
* - The
FIELD_COUNT
constant has been removed. Use
* {@link #getFieldCount}. In addition, framework API has been
* added to allow subclasses to define additional fields.
* Motivation: The number of fields is not constant across
* calendar systems.
*
* - The range of handled dates has been narrowed from +/-
* ~300,000,000 years to +/- ~5,000,000 years. In practical terms
* this should not affect clients. However, it does mean that client
* code cannot be guaranteed well-behaved results with dates such as
*
Date(Long.MIN_VALUE)
or
* Date(Long.MAX_VALUE)
. Instead, the
* Calendar
protected constants should be used.
* Motivation: With
* the addition of the {@link #JULIAN_DAY} field, Julian day
* numbers must be restricted to a 32-bit int
. This
* restricts the overall supported range. Furthermore, restricting
* the supported range simplifies the computations by removing
* special case code that was used to accomodate arithmetic overflow
* at millis near Long.MIN_VALUE
and
* Long.MAX_VALUE
.
*
* - New fields are implemented: {@link #JULIAN_DAY} defines
* single-field specification of the
* date. {@link #MILLISECONDS_IN_DAY} defines a single-field
* specification of the wall time. {@link #DOW_LOCAL} and
* {@link #YEAR_WOY} implement localized day-of-week and
* week-of-year behavior.
*
* - Subclasses can access protected millisecond constants
* defined in
Calendar
.
*
* - New API has been added to support calendar-specific subclasses
* of
DateFormat
.
*
* - Several subclasses have been implemented, representing
* various international calendar systems.
*
*
*
* Subclass API
*
* The original Calendar
API was based on the experience
* of implementing a only a single subclass,
* GregorianCalendar
. As a result, all of the subclassing
* kinks had not been worked out. The new subclassing API has been
* refined based on several implemented subclasses. This includes methods
* that must be overridden and methods for subclasses to call. Subclasses
* no longer have direct access to fields
and
* stamp
. Instead, they have new API to access
* these. Subclasses are able to allocate the fields
array
* through a protected framework method; this allows subclasses to
* specify additional fields.
*
* More functionality has been moved into the base class. The base
* class now contains much of the computational machinery to support the
* Gregorian calendar. This is based on two things: (1) Many calendars
* are based on the Gregorian calendar (such as the Buddhist and Japanese
* imperial calendars). (2) All calendars require basic
* Gregorian support in order to handle timezone computations.
*
* Common computations have been moved into
* Calendar
. Subclasses no longer compute the week related
* fields and the time related fields. These are commonly handled for all
* calendars by the base class.
*
* Subclass computation of time => fields
*
*
The {@link #ERA}, {@link #YEAR},
* {@link #EXTENDED_YEAR}, {@link #MONTH},
* {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields are
* computed by the subclass, based on the Julian day. All other fields
* are computed by Calendar
.
*
*
*
* - Subclasses should implement {@link #handleComputeFields}
* to compute the {@link #ERA}, {@link #YEAR},
* {@link #EXTENDED_YEAR}, {@link #MONTH},
* {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields,
* based on the value of the {@link #JULIAN_DAY} field. If there
* are calendar-specific fields not defined by
Calendar
,
* they must also be computed. These are the only fields that the
* subclass should compute. All other fields are computed by the base
* class, so time and week fields behave in a consistent way across
* all calendars. The default version of this method in
* Calendar
implements a proleptic Gregorian
* calendar. Within this method, subclasses may call
* getGregorianXxx()
to obtain the Gregorian calendar
* month, day of month, and extended year for the given date.
*
*
*
* Subclass computation of fields => time
*
*
The interpretation of most field values is handled entirely by
* Calendar
. Calendar
determines which fields
* are set, which are not, which are set more recently, and so on. In
* addition, Calendar
handles the computation of the time
* from the time fields and handles the week-related fields. The only
* thing the subclass must do is determine the extended year, based on
* the year fields, and then, given an extended year and a month, it must
* return a Julian day number.
*
*
*
* - Subclasses should implement {@link #handleGetExtendedYear}
* to return the extended year for this calendar system, based on the
* {@link #YEAR}, {@link #EXTENDED_YEAR}, and any fields that
* the calendar system uses that are larger than a year, such as
* {@link #ERA}.
*
* - Subclasses should implement {@link #handleComputeMonthStart}
* to return the Julian day number
* associated with a month and extended year. This is the Julian day
* number of the day before the first day of the month. The month
* number is zero-based. This computation should not depend on any
* field values.
*
*
*
* Other methods
*
*
*
* - Subclasses should implement {@link #handleGetMonthLength}
* to return the number of days in a
* given month of a given extended year. The month number, as always,
* is zero-based.
*
* - Subclasses should implement {@link #handleGetYearLength}
* to return the number of days in the given
* extended year. This method is used by
* computeWeekFields to compute the
* {@link #WEEK_OF_YEAR} and {@link #YEAR_WOY} fields.
*
* - Subclasses should implement {@link #handleGetLimit}
* to return the protected values of a field, depending on the value of
*
limitType
. This method only needs to handle the
* fields {@link #ERA}, {@link #YEAR}, {@link #MONTH},
* {@link #WEEK_OF_YEAR}, {@link #WEEK_OF_MONTH},
* {@link #DAY_OF_MONTH}, {@link #DAY_OF_YEAR},
* {@link #DAY_OF_WEEK_IN_MONTH}, {@link #YEAR_WOY}, and
* {@link #EXTENDED_YEAR}. Other fields are invariant (with
* respect to calendar system) and are handled by the base
* class.
*
* - Optionally, subclasses may override {@link #validateField}
* to check any subclass-specific fields. If the
* field's value is out of range, the method should throw an
*
IllegalArgumentException
. The method may call
* super.validateField(field)
to handle fields in a
* generic way, that is, to compare them to the range
* getMinimum(field)
..getMaximum(field)
.
*
* - Optionally, subclasses may override
* {@link #handleCreateFields} to create an
int[]
* array large enough to hold the calendar's fields. This is only
* necessary if the calendar defines additional fields beyond those
* defined by Calendar
. The length of the result must be
* be between the base and maximum field counts.
*
* - Optionally, subclasses may override
* {@link #handleGetDateFormat} to create a
*
DateFormat
appropriate to this calendar. This is only
* required if a calendar subclass redefines the use of a field (for
* example, changes the {@link #ERA} field from a symbolic field
* to a numeric one) or defines an additional field.
*
* - Optionally, subclasses may override {@link #roll roll} and
* {@link #add add} to handle fields that are discontinuous. For
* example, in the Hebrew calendar the month "Adar I" only
* occurs in leap years; in other years the calendar jumps from
* Shevat (month #4) to Adar (month #6). The {@link
* HebrewCalendar#add HebrewCalendar.add} and {@link
* HebrewCalendar#roll HebrewCalendar.roll} methods take this into
* account, so that adding 1 month to Shevat gives the proper result
* (Adar) in a non-leap year. The protected utility method {@link
* #pinField pinField} is often useful when implementing these two
* methods.
*
*
*
* Normalized behavior
*
*
The behavior of certain fields has been made consistent across all
* calendar systems and implemented in Calendar
.
*
*
*
* - Time is normalized. Even though some calendar systems transition
* between days at sunset or at other times, all ICU4J calendars
* transition between days at local zone midnight. This
* allows ICU4J to centralize the time computations in
*
Calendar
and to maintain basic correpsondences
* between calendar systems. Affected fields: {@link #AM_PM},
* {@link #HOUR}, {@link #HOUR_OF_DAY}, {@link #MINUTE},
* {@link #SECOND}, {@link #MILLISECOND},
* {@link #ZONE_OFFSET}, and {@link #DST_OFFSET}.
*
* - DST behavior is normalized. Daylight savings time behavior is
* computed the same for all calendar systems, and depends on the
* value of several
GregorianCalendar
fields: the
* {@link #YEAR}, {@link #MONTH}, and
* {@link #DAY_OF_MONTH}. As a result, Calendar
* always computes these fields, even for non-Gregorian calendar
* systems. These fields are available to subclasses.
*
* - Weeks are normalized. Although locales define the week
* differently, in terms of the day on which it starts, and the
* designation of week number one of a month or year, they all use a
* common mechanism. Furthermore, the day of the week has a simple
* and consistent definition throughout history. For example,
* although the Gregorian calendar introduced a discontinuity when
* first instituted, the day of week was not disrupted. For this
* reason, the fields {@link #DAY_OF_WEEK},
WEEK_OF_YEAR,
* WEEK_OF_MONTH
, {@link #DAY_OF_WEEK_IN_MONTH},
* {@link #DOW_LOCAL}, {@link #YEAR_WOY} are all computed in
* a consistent way in the base class, based on the
* {@link #EXTENDED_YEAR}, {@link #DAY_OF_YEAR},
* {@link #MONTH}, and {@link #DAY_OF_MONTH}, which are
* computed by the subclass.
*
*
*
* Supported range
*
*
The allowable range of Calendar
has been
* narrowed. GregorianCalendar
used to attempt to support
* the range of dates with millisecond values from
* Long.MIN_VALUE
to Long.MAX_VALUE
. This
* introduced awkward constructions (hacks) which slowed down
* performance. It also introduced non-uniform behavior at the
* boundaries. The new Calendar
protocol specifies the
* maximum range of supportable dates as those having Julian day numbers
* of -0x7F000000
to +0x7F000000
. This
* corresponds to years from ~5,000,000 BCE to ~5,000,000 CE. Programmers
* should use the protected constants in Calendar
to
* specify an extremely early or extremely late date.
*
* General notes
*
*
*
* - Calendars implementations are proleptic. For example,
* even though the Gregorian calendar was not instituted until the
* 16th century, the
GregorianCalendar
class supports
* dates before the historical onset of the calendar by extending the
* calendar system backward in time. Similarly, the
* HebrewCalendar
extends backward before the start of
* its epoch into zero and negative years. Subclasses do not throw
* exceptions because a date precedes the historical start of a
* calendar system. Instead, they implement
* {@link #handleGetLimit} to return appropriate limits on
* {@link #YEAR}, {@link #ERA}, etc. fields. Then, if the
* calendar is set to not be lenient, out-of-range field values will
* trigger an exception.
*
* - Calendar system subclasses compute a extended
* year. This differs from the {@link #YEAR} field in that
* it ranges over all integer values, including zero and negative
* values, and it encapsulates the information of the
* {@link #YEAR} field and all larger fields. Thus, for the
* Gregorian calendar, the {@link #EXTENDED_YEAR} is computed as
*
ERA==AD ? YEAR : 1-YEAR
. Another example is the Mayan
* long count, which has years (KUN
) and nested cycles
* of years (KATUN
and BAKTUN
). The Mayan
* {@link #EXTENDED_YEAR} is computed as TUN + 20 * (KATUN
* + 20 * BAKTUN)
. The Calendar
base class uses
* the {@link #EXTENDED_YEAR} field to compute the week-related
* fields.
*
*
*
* @see Date
* @see GregorianCalendar
* @see TimeZone
* @see DateFormat
* @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu, Laura Werner
* @stable ICU 2.0
*/
public class Calendar implements Serializable, Cloneable, Comparable {
private static final long serialVersionUID = 1L;
/**
* @internal
*/
public final java.util.Calendar calendar;
/**
* @internal
* @param delegate the Calendar to which to delegate
*/
public Calendar(java.util.Calendar delegate) {
this.calendar = delegate;
}
// Data flow in Calendar
// ---------------------
// The current time is represented in two ways by Calendar: as UTC
// milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local
// fields such as MONTH, HOUR, AM_PM, etc. It is possible to compute the
// millis from the fields, and vice versa. The data needed to do this
// conversion is encapsulated by a TimeZone object owned by the Calendar.
// The data provided by the TimeZone object may also be overridden if the
// user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
// keeps track of what information was most recently set by the caller, and
// uses that to compute any other information as needed.
// If the user sets the fields using set(), the data flow is as follows.
// This is implemented by the Calendar subclass's computeTime() method.
// During this process, certain fields may be ignored. The disambiguation
// algorithm for resolving which fields to pay attention to is described
// above.
// local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
// |
// | Using Calendar-specific algorithm
// V
// local standard millis
// |
// | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
// V
// UTC millis (in time data member)
// If the user sets the UTC millis using setTime(), the data flow is as
// follows. This is implemented by the Calendar subclass's computeFields()
// method.
// UTC millis (in time data member)
// |
// | Using TimeZone getOffset()
// V
// local standard millis
// |
// | Using Calendar-specific algorithm
// V
// local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
// In general, a round trip from fields, through local and UTC millis, and
// back out to fields is made when necessary. This is implemented by the
// complete() method. Resolving a partial set of fields into a UTC millis
// value allows all remaining fields to be generated from that value. If
// the Calendar is lenient, the fields are also renormalized to standard
// ranges when they are regenerated.
/**
* Field number for get
and set
indicating the
* era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
* value; see subclass documentation.
* @see GregorianCalendar#AD
* @see GregorianCalendar#BC
* @stable ICU 2.0
*/
public final static int ERA = 0;
/**
* Field number for get
and set
indicating the
* year. This is a calendar-specific value; see subclass documentation.
* @stable ICU 2.0
*/
public final static int YEAR = 1;
/**
* Field number for get
and set
indicating the
* month. This is a calendar-specific value. The first month of the year is
* JANUARY
; the last depends on the number of months in a year.
* @see #JANUARY
* @see #FEBRUARY
* @see #MARCH
* @see #APRIL
* @see #MAY
* @see #JUNE
* @see #JULY
* @see #AUGUST
* @see #SEPTEMBER
* @see #OCTOBER
* @see #NOVEMBER
* @see #DECEMBER
* @see #UNDECIMBER
* @stable ICU 2.0
*/
public final static int MONTH = 2;
/**
* Field number for get
and set
indicating the
* week number within the current year. The first week of the year, as
* defined by {@link #getFirstDayOfWeek()} and
* {@link #getMinimalDaysInFirstWeek()}, has value 1. Subclasses define
* the value of {@link #WEEK_OF_YEAR} for days before the first week of
* the year.
* @see #getFirstDayOfWeek
* @see #getMinimalDaysInFirstWeek
* @stable ICU 2.0
*/
public final static int WEEK_OF_YEAR = 3;
/**
* Field number for get
and set
indicating the
* week number within the current month. The first week of the month, as
* defined by {@link #getFirstDayOfWeek()} and
* {@link #getMinimalDaysInFirstWeek()}, has value 1. Subclasses define
* the value of {@link #WEEK_OF_MONTH} for days before the first week of
* the month.
* @see #getFirstDayOfWeek
* @see #getMinimalDaysInFirstWeek
* @stable ICU 2.0
*/
public final static int WEEK_OF_MONTH = 4;
/**
* Field number for get
and set
indicating the
* day of the month. This is a synonym for {@link #DAY_OF_MONTH}.
* The first day of the month has value 1.
* @see #DAY_OF_MONTH
* @stable ICU 2.0
*/
public final static int DATE = 5;
/**
* Field number for get
and set
indicating the
* day of the month. This is a synonym for {@link #DATE}.
* The first day of the month has value 1.
* @see #DATE
* @stable ICU 2.0
*/
public final static int DAY_OF_MONTH = 5;
/**
* Field number for get
and set
indicating the day
* number within the current year. The first day of the year has value 1.
* @stable ICU 2.0
*/
public final static int DAY_OF_YEAR = 6;
/**
* Field number for get
and set
indicating the day
* of the week. This field takes values {@link #SUNDAY},
* {@link #MONDAY}, {@link #TUESDAY}, {@link #WEDNESDAY},
* {@link #THURSDAY}, {@link #FRIDAY}, and {@link #SATURDAY}.
* @see #SUNDAY
* @see #MONDAY
* @see #TUESDAY
* @see #WEDNESDAY
* @see #THURSDAY
* @see #FRIDAY
* @see #SATURDAY
* @stable ICU 2.0
*/
public final static int DAY_OF_WEEK = 7;
/**
* Field number for get
and set
indicating the
* ordinal number of the day of the week within the current month. Together
* with the {@link #DAY_OF_WEEK} field, this uniquely specifies a day
* within a month. Unlike {@link #WEEK_OF_MONTH} and
* {@link #WEEK_OF_YEAR}, this field's value does not depend on
* {@link #getFirstDayOfWeek()} or
* {@link #getMinimalDaysInFirstWeek()}. DAY_OF_MONTH 1
* through 7
always correspond to DAY_OF_WEEK_IN_MONTH
* 1
; 8
through 15
correspond to
* DAY_OF_WEEK_IN_MONTH 2
, and so on.
* DAY_OF_WEEK_IN_MONTH 0
indicates the week before
* DAY_OF_WEEK_IN_MONTH 1
. Negative values count back from the
* end of the month, so the last Sunday of a month is specified as
* DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1
. Because
* negative values count backward they will usually be aligned differently
* within the month than positive values. For example, if a month has 31
* days, DAY_OF_WEEK_IN_MONTH -1
will overlap
* DAY_OF_WEEK_IN_MONTH 5
and the end of 4
.
* @see #DAY_OF_WEEK
* @see #WEEK_OF_MONTH
* @stable ICU 2.0
*/
public final static int DAY_OF_WEEK_IN_MONTH = 8;
/**
* Field number for get
and set
indicating
* whether the HOUR
is before or after noon.
* E.g., at 10:04:15.250 PM the AM_PM
is PM
.
* @see #AM
* @see #PM
* @see #HOUR
* @stable ICU 2.0
*/
public final static int AM_PM = 9;
/**
* Field number for get
and set
indicating the
* hour of the morning or afternoon. HOUR
is used for the 12-hour
* clock.
* E.g., at 10:04:15.250 PM the HOUR
is 10.
* @see #AM_PM
* @see #HOUR_OF_DAY
* @stable ICU 2.0
*/
public final static int HOUR = 10;
/**
* Field number for get
and set
indicating the
* hour of the day. HOUR_OF_DAY
is used for the 24-hour clock.
* E.g., at 10:04:15.250 PM the HOUR_OF_DAY
is 22.
* @see #HOUR
* @stable ICU 2.0
*/
public final static int HOUR_OF_DAY = 11;
/**
* Field number for get
and set
indicating the
* minute within the hour.
* E.g., at 10:04:15.250 PM the MINUTE
is 4.
* @stable ICU 2.0
*/
public final static int MINUTE = 12;
/**
* Field number for get
and set
indicating the
* second within the minute.
* E.g., at 10:04:15.250 PM the SECOND
is 15.
* @stable ICU 2.0
*/
public final static int SECOND = 13;
/**
* Field number for get
and set
indicating the
* millisecond within the second.
* E.g., at 10:04:15.250 PM the MILLISECOND
is 250.
* @stable ICU 2.0
*/
public final static int MILLISECOND = 14;
/**
* Field number for get
and set
indicating the
* raw offset from GMT in milliseconds.
* @stable ICU 2.0
*/
public final static int ZONE_OFFSET = 15;
/**
* Field number for get
and set
indicating the
* daylight savings offset in milliseconds.
* @stable ICU 2.0
*/
public final static int DST_OFFSET = 16;
// /**
// * {@icu} Field number for get()
and set()
// * indicating the extended year corresponding to the
// * {@link #WEEK_OF_YEAR} field. This may be one greater or less
// * than the value of {@link #EXTENDED_YEAR}.
// * @stable ICU 2.0
// */
// public static final int YEAR_WOY = 17;
//
// /**
// * {@icu} Field number for get()
and set()
// * indicating the localized day of week. This will be a value from 1
// * to 7 inclusive, with 1 being the localized first day of the week.
// * @stable ICU 2.0
// */
// public static final int DOW_LOCAL = 18;
//
// /**
// * {@icu} Field number for get()
and set()
// * indicating the extended year. This is a single number designating
// * the year of this calendar system, encompassing all supra-year
// * fields. For example, for the Julian calendar system, year numbers
// * are positive, with an era of BCE or CE. An extended year value for
// * the Julian calendar system assigns positive values to CE years and
// * negative values to BCE years, with 1 BCE being year 0.
// * @stable ICU 2.0
// */
// public static final int EXTENDED_YEAR = 19;
//
// /**
// * {@icu} Field number for get()
and set()
// * indicating the modified Julian day number. This is different from
// * the conventional Julian day number in two regards. First, it
// * demarcates days at local zone midnight, rather than noon GMT.
// * Second, it is a local number; that is, it depends on the local time
// * zone. It can be thought of as a single number that encompasses all
// * the date-related fields.
// * @stable ICU 2.0
// */
// public static final int JULIAN_DAY = 20;
//
// /**
// * {@icu} Field number for get()
and set()
// * indicating the milliseconds in the day. This ranges from 0 to
// * 23:59:59.999 (regardless of DST). This field behaves
// * exactly like a composite of all time-related fields, not
// * including the zone fields. As such, it also reflects
// * discontinuities of those fields on DST transition days. On a day of
// * DST onset, it will jump forward. On a day of DST cessation, it will
// * jump backward. This reflects the fact that is must be combined with
// * the DST_OFFSET field to obtain a unique local time value.
// * @stable ICU 2.0
// */
// public static final int MILLISECONDS_IN_DAY = 21;
//
// /**
// * {@icu} Field indicating whether or not the current month is a leap month.
// * Should have a value of 0 for non-leap months, and 1 for leap months.
// * @draft ICU 4.4
// * @provisional This API might change or be removed in a future release.
// */
// public static final int IS_LEAP_MONTH = 22;
/**
* Value of the DAY_OF_WEEK
field indicating
* Sunday.
* @stable ICU 2.0
*/
public final static int SUNDAY = 1;
/**
* Value of the DAY_OF_WEEK
field indicating
* Monday.
* @stable ICU 2.0
*/
public final static int MONDAY = 2;
/**
* Value of the DAY_OF_WEEK
field indicating
* Tuesday.
* @stable ICU 2.0
*/
public final static int TUESDAY = 3;
/**
* Value of the DAY_OF_WEEK
field indicating
* Wednesday.
* @stable ICU 2.0
*/
public final static int WEDNESDAY = 4;
/**
* Value of the DAY_OF_WEEK
field indicating
* Thursday.
* @stable ICU 2.0
*/
public final static int THURSDAY = 5;
/**
* Value of the DAY_OF_WEEK
field indicating
* Friday.
* @stable ICU 2.0
*/
public final static int FRIDAY = 6;
/**
* Value of the DAY_OF_WEEK
field indicating
* Saturday.
* @stable ICU 2.0
*/
public final static int SATURDAY = 7;
/**
* Value of the MONTH
field indicating the
* first month of the year.
* @stable ICU 2.0
*/
public final static int JANUARY = 0;
/**
* Value of the MONTH
field indicating the
* second month of the year.
* @stable ICU 2.0
*/
public final static int FEBRUARY = 1;
/**
* Value of the MONTH
field indicating the
* third month of the year.
* @stable ICU 2.0
*/
public final static int MARCH = 2;
/**
* Value of the MONTH
field indicating the
* fourth month of the year.
* @stable ICU 2.0
*/
public final static int APRIL = 3;
/**
* Value of the MONTH
field indicating the
* fifth month of the year.
* @stable ICU 2.0
*/
public final static int MAY = 4;
/**
* Value of the MONTH
field indicating the
* sixth month of the year.
* @stable ICU 2.0
*/
public final static int JUNE = 5;
/**
* Value of the MONTH
field indicating the
* seventh month of the year.
* @stable ICU 2.0
*/
public final static int JULY = 6;
/**
* Value of the MONTH
field indicating the
* eighth month of the year.
* @stable ICU 2.0
*/
public final static int AUGUST = 7;
/**
* Value of the MONTH
field indicating the
* ninth month of the year.
* @stable ICU 2.0
*/
public final static int SEPTEMBER = 8;
/**
* Value of the MONTH
field indicating the
* tenth month of the year.
* @stable ICU 2.0
*/
public final static int OCTOBER = 9;
/**
* Value of the MONTH
field indicating the
* eleventh month of the year.
* @stable ICU 2.0
*/
public final static int NOVEMBER = 10;
/**
* Value of the MONTH
field indicating the
* twelfth month of the year.
* @stable ICU 2.0
*/
public final static int DECEMBER = 11;
/**
* Value of the MONTH
field indicating the
* thirteenth month of the year. Although {@link GregorianCalendar}
* does not use this value, lunar calendars do.
* @stable ICU 2.0
*/
public final static int UNDECIMBER = 12;
/**
* Value of the AM_PM
field indicating the
* period of the day from midnight to just before noon.
* @stable ICU 2.0
*/
public final static int AM = 0;
/**
* Value of the AM_PM
field indicating the
* period of the day from noon to just before midnight.
* @stable ICU 2.0
*/
public final static int PM = 1;
/**
* {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
* weekday.
* @see #WEEKEND
* @see #WEEKEND_ONSET
* @see #WEEKEND_CEASE
* @see #getDayOfWeekType
* @stable ICU 2.0
*/
public static final int WEEKDAY = 0;
/**
* {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
* weekend day.
* @see #WEEKDAY
* @see #WEEKEND_ONSET
* @see #WEEKEND_CEASE
* @see #getDayOfWeekType
* @stable ICU 2.0
*/
public static final int WEEKEND = 1;
/**
* {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
* day that starts as a weekday and transitions to the weekend.
* Call getWeekendTransition() to get the point of transition.
* @see #WEEKDAY
* @see #WEEKEND
* @see #WEEKEND_CEASE
* @see #getDayOfWeekType
* @stable ICU 2.0
*/
public static final int WEEKEND_ONSET = 2;
/**
* {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
* day that starts as the weekend and transitions to a weekday.
* Call getWeekendTransition() to get the point of transition.
* @see #WEEKDAY
* @see #WEEKEND
* @see #WEEKEND_ONSET
* @see #getDayOfWeekType
* @stable ICU 2.0
*/
public static final int WEEKEND_CEASE = 3;
/**
* {@icu}Option used by {@link #setRepeatedWallTimeOption(int)} and
* {@link #setSkippedWallTimeOption(int)} specifying an ambiguous wall time
* to be interpreted as the latest.
* @see #setRepeatedWallTimeOption(int)
* @see #getRepeatedWallTimeOption()
* @see #setSkippedWallTimeOption(int)
* @see #getSkippedWallTimeOption()
* @draft ICU 49
* @provisional This API might change or be removed in a future release.
*/
public static final int WALLTIME_LAST = 0;
/**
* {@icu}Option used by {@link #setRepeatedWallTimeOption(int)} and
* {@link #setSkippedWallTimeOption(int)} specifying an ambiguous wall time
* to be interpreted as the earliest.
* @see #setRepeatedWallTimeOption(int)
* @see #getRepeatedWallTimeOption()
* @see #setSkippedWallTimeOption(int)
* @see #getSkippedWallTimeOption()
* @draft ICU 49
* @provisional This API might change or be removed in a future release.
*/
public static final int WALLTIME_FIRST = 1;
/**
* {@icu}Option used by {@link #setSkippedWallTimeOption(int)} specifying an
* ambiguous wall time to be interpreted as the next valid wall time.
* @see #setSkippedWallTimeOption(int)
* @see #getSkippedWallTimeOption()
* @draft ICU 49
* @provisional This API might change or be removed in a future release.
*/
public static final int WALLTIME_NEXT_VALID = 2;
/**
* Constructs a Calendar with the default time zone
* and locale.
* @see TimeZone#getDefault
* @stable ICU 2.0
*/
protected Calendar()
{
this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
}
/**
* Constructs a calendar with the specified time zone and locale.
* @param zone the time zone to use
* @param aLocale the locale for the week data
* @stable ICU 2.0
*/
protected Calendar(TimeZone zone, Locale aLocale)
{
this(zone, ULocale.forLocale(aLocale));
}
/**
* Constructs a calendar with the specified time zone and locale.
* @param zone the time zone to use
* @param locale the ulocale for the week data
* @stable ICU 3.2
*/
protected Calendar(TimeZone zone, ULocale locale)
{
calendar = java.util.Calendar.getInstance(zone.timeZone, locale.toLocale());
}
/**
* Returns a calendar using the default time zone and locale.
* @return a Calendar.
* @stable ICU 2.0
*/
public static synchronized Calendar getInstance()
{
return new Calendar(java.util.Calendar.getInstance(ULocale.getDefault(Category.FORMAT).toLocale()));
}
/**
* Returns a calendar using the specified time zone and default locale.
* @param zone the time zone to use
* @return a Calendar.
* @stable ICU 2.0
*/
public static synchronized Calendar getInstance(TimeZone zone)
{
return new Calendar(java.util.Calendar.getInstance(zone.timeZone, ULocale.getDefault(Category.FORMAT).toLocale()));
}
/**
* Returns a calendar using the default time zone and specified locale.
* @param aLocale the locale for the week data
* @return a Calendar.
* @stable ICU 2.0
*/
public static synchronized Calendar getInstance(Locale aLocale)
{
return new Calendar(java.util.Calendar.getInstance(aLocale));
}
/**
* Returns a calendar using the default time zone and specified locale.
* @param locale the ulocale for the week data
* @return a Calendar.
* @stable ICU 3.2
*/
public static synchronized Calendar getInstance(ULocale locale)
{
return new Calendar(java.util.Calendar.getInstance(locale.toLocale()));
}
/**
* Returns a calendar with the specified time zone and locale.
* @param zone the time zone to use
* @param aLocale the locale for the week data
* @return a Calendar.
* @stable ICU 2.0
*/
public static synchronized Calendar getInstance(TimeZone zone,
Locale aLocale) {
return new Calendar(java.util.Calendar.getInstance(zone.timeZone, aLocale));
}
/**
* Returns a calendar with the specified time zone and locale.
* @param zone the time zone to use
* @param locale the ulocale for the week data
* @return a Calendar.
* @stable ICU 3.2
*/
public static synchronized Calendar getInstance(TimeZone zone,
ULocale locale) {
return new Calendar(java.util.Calendar.getInstance(zone.timeZone, locale.toLocale()));
}
/**
* Returns the list of locales for which Calendars are installed.
* @return the list of locales for which Calendars are installed.
* @stable ICU 2.0
*/
public static Locale[] getAvailableLocales()
{
return java.util.Calendar.getAvailableLocales();
}
/**
* {@icu} Returns the list of locales for which Calendars are installed.
* @return the list of locales for which Calendars are installed.
* @draft ICU 3.2 (retain)
* @provisional This API might change or be removed in a future release.
*/
public static ULocale[] getAvailableULocales()
{
if (availableLocales == null) {
synchronized (Calendar.class) {
if (availableLocales == null) {
Locale[] locales = Locale.getAvailableLocales();
availableLocales = new ULocale[locales.length];
for (int i = 0; i < locales.length; i++) {
availableLocales[i] = ULocale.forLocale(locales[i]);
}
}
}
}
return availableLocales.clone();
}
private static volatile ULocale[] availableLocales;
// /**
// * {@icu} Given a key and a locale, returns an array of string values in a preferred
// * order that would make a difference. These are all and only those values where
// * the open (creation) of the service with the locale formed from the input locale
// * plus input keyword and that value has different behavior than creation with the
// * input locale alone.
// * @param key one of the keys supported by this service. For now, only
// * "calendar" is supported.
// * @param locale the locale
// * @param commonlyUsed if set to true it will return only commonly used values
// * with the given locale in preferred order. Otherwise,
// * it will return all the available values for the locale.
// * @return an array of string values for the given key and the locale.
// * @stable ICU 4.2
// */
// public static final String[] getKeywordValuesForLocale(String key, ULocale locale,
// boolean commonlyUsed) {
// throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
// }
/**
* Returns this Calendar's current time.
* @return the current time.
* @stable ICU 2.0
*/
public final Date getTime() {
return calendar.getTime();
}
/**
* Sets this Calendar's current time with the given Date.
*
* Note: Calling setTime
with
* Date(Long.MAX_VALUE)
or Date(Long.MIN_VALUE)
* may yield incorrect field values from {@link #get(int)}.
* @param date the given Date.
* @stable ICU 2.0
*/
public final void setTime(Date date) {
calendar.setTime(date);
}
/**
* Returns this Calendar's current time as a long.
* @return the current time as UTC milliseconds from the epoch.
* @stable ICU 2.0
*/
public long getTimeInMillis() {
return calendar.getTimeInMillis();
}
/**
* Sets this Calendar's current time from the given long value.
* @param millis the new time in UTC milliseconds from the epoch.
* @stable ICU 2.0
*/
public void setTimeInMillis( long millis ) {
calendar.setTimeInMillis(millis);
}
/**
* Returns the value for a given time field.
* @param field the given time field.
* @return the value for the given time field.
* @stable ICU 2.0
*/
public final int get(int field)
{
return calendar.get(getJDKField(field));
}
/**
* Sets the time field with the given value.
* @param field the given time field.
* @param value the value to be set for the given time field.
* @stable ICU 2.0
*/
public final void set(int field, int value)
{
calendar.set(getJDKField(field), value);
}
/**
* Sets the values for the fields year, month, and date.
* Previous values of other fields are retained. If this is not desired,
* call {@link #clear()} first.
* @param year the value used to set the YEAR time field.
* @param month the value used to set the MONTH time field.
* Month value is 0-based. e.g., 0 for January.
* @param date the value used to set the DATE time field.
* @stable ICU 2.0
*/
public final void set(int year, int month, int date)
{
calendar.set(getJDKField(YEAR), year);
calendar.set(getJDKField(MONTH), month);
calendar.set(getJDKField(DATE), date);
}
/**
* Sets the values for the fields year, month, date, hour, and minute.
* Previous values of other fields are retained. If this is not desired,
* call {@link #clear()} first.
* @param year the value used to set the YEAR time field.
* @param month the value used to set the MONTH time field.
* Month value is 0-based. e.g., 0 for January.
* @param date the value used to set the DATE time field.
* @param hour the value used to set the HOUR_OF_DAY time field.
* @param minute the value used to set the MINUTE time field.
* @stable ICU 2.0
*/
public final void set(int year, int month, int date, int hour, int minute)
{
calendar.set(getJDKField(YEAR), year);
calendar.set(getJDKField(MONTH), month);
calendar.set(getJDKField(DATE), date);
calendar.set(getJDKField(HOUR_OF_DAY), hour);
calendar.set(getJDKField(MINUTE), minute);
}
/**
* Sets the values for the fields year, month, date, hour, minute, and second.
* Previous values of other fields are retained. If this is not desired,
* call {@link #clear} first.
* @param year the value used to set the YEAR time field.
* @param month the value used to set the MONTH time field.
* Month value is 0-based. e.g., 0 for January.
* @param date the value used to set the DATE time field.
* @param hour the value used to set the HOUR_OF_DAY time field.
* @param minute the value used to set the MINUTE time field.
* @param second the value used to set the SECOND time field.
* @stable ICU 2.0
*/
public final void set(int year, int month, int date, int hour, int minute,
int second)
{
calendar.set(getJDKField(YEAR), year);
calendar.set(getJDKField(MONTH), month);
calendar.set(getJDKField(DATE), date);
calendar.set(getJDKField(HOUR_OF_DAY), hour);
calendar.set(getJDKField(MINUTE), minute);
calendar.set(getJDKField(SECOND), second);
}
/**
* Clears the values of all the time fields.
* @stable ICU 2.0
*/
public final void clear()
{
calendar.clear();
}
/**
* Clears the value in the given time field.
* @param field the time field to be cleared.
* @stable ICU 2.0
*/
public final void clear(int field)
{
calendar.clear(getJDKField(field));
}
/**
* Determines if the given time field has a value set.
* @return true if the given time field has a value set; false otherwise.
* @stable ICU 2.0
*/
public final boolean isSet(int field)
{
return calendar.isSet(getJDKField(field));
}
/**
* Compares this calendar to the specified object.
* The result is true
if and only if the argument is
* not null
and is a Calendar
object that
* represents the same calendar as this object.
* @param obj the object to compare with.
* @return true
if the objects are the same;
* false
otherwise.
* @stable ICU 2.0
*/
public boolean equals(Object obj) {
try {
return calendar.equals(((Calendar)obj).calendar);
} catch (Exception e) {
return false;
}
}
/**
* {@icu} Returns true if the given Calendar object is equivalent to this
* one. An equivalent Calendar will behave exactly as this one
* does, but it may be set to a different time. By contrast, for
* the equals() method to return true, the other Calendar must
* be set to the same time.
*
* @param other the Calendar to be compared with this Calendar
* @stable ICU 2.4
*/
public boolean isEquivalentTo(Calendar other) {
return calendar.getClass() == other.calendar.getClass() &&
calendar.isLenient() == other.calendar.isLenient() &&
calendar.getFirstDayOfWeek() == other.calendar.getFirstDayOfWeek() &&
calendar.getMinimalDaysInFirstWeek() == other.calendar.getMinimalDaysInFirstWeek() &&
calendar.getTimeZone().equals(other.calendar.getTimeZone());
}
/**
* Returns a hash code for this calendar.
* @return a hash code value for this object.
* @stable ICU 2.0
*/
public int hashCode() {
return calendar.hashCode();
}
/**
* Returns the difference in milliseconds between the moment this
* calendar is set to and the moment the given calendar or Date object
* is set to.
*/
private long compare(Object that) {
long thatMs;
if (that instanceof Calendar) {
thatMs = ((Calendar)that).getTimeInMillis();
} else if (that instanceof Date) {
thatMs = ((Date)that).getTime();
} else {
throw new IllegalArgumentException(that + "is not a Calendar or Date");
}
return getTimeInMillis() - thatMs;
}
/**
* Compares the time field records.
* Equivalent to comparing result of conversion to UTC.
* @param when the Calendar to be compared with this Calendar.
* @return true if the current time of this Calendar is before
* the time of Calendar when; false otherwise.
* @stable ICU 2.0
*/
public boolean before(Object when) {
return compare(when) < 0;
}
/**
* Compares the time field records.
* Equivalent to comparing result of conversion to UTC.
* @param when the Calendar to be compared with this Calendar.
* @return true if the current time of this Calendar is after
* the time of Calendar when; false otherwise.
* @stable ICU 2.0
*/
public boolean after(Object when) {
return compare(when) > 0;
}
/**
* Returns the maximum value that this field could have, given the
* current date. For example, with the Gregorian date February 3, 1997
* and the {@link #DAY_OF_MONTH DAY_OF_MONTH} field, the actual maximum
* is 28; for February 3, 1996 it is 29.
*
*
The actual maximum computation ignores smaller fields and the
* current value of like-sized fields. For example, the actual maximum
* of the DAY_OF_YEAR or MONTH depends only on the year and supra-year
* fields. The actual maximum of the DAY_OF_MONTH depends, in
* addition, on the MONTH field and any other fields at that
* granularity (such as IS_LEAP_MONTH). The
* DAY_OF_WEEK_IN_MONTH field does not depend on the current
* DAY_OF_WEEK; it returns the maximum for any day of week in the
* current month. Likewise for the WEEK_OF_MONTH and WEEK_OF_YEAR
* fields.
*
* @param field the field whose maximum is desired
* @return the maximum of the given field for the current date of this calendar
* @see #getMaximum
* @see #getLeastMaximum
* @stable ICU 2.0
*/
public int getActualMaximum(int field) {
return calendar.getActualMaximum(getJDKField(field));
}
/**
* Returns the minimum value that this field could have, given the current date.
* For most fields, this is the same as {@link #getMinimum getMinimum}
* and {@link #getGreatestMinimum getGreatestMinimum}. However, some fields,
* especially those related to week number, are more complicated.
*
* For example, assume {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
* returns 4 and {@link #getFirstDayOfWeek getFirstDayOfWeek} returns SUNDAY.
* If the first day of the month is Sunday, Monday, Tuesday, or Wednesday
* there will be four or more days in the first week, so it will be week number 1,
* and getActualMinimum(WEEK_OF_MONTH)
will return 1. However,
* if the first of the month is a Thursday, Friday, or Saturday, there are
* not four days in that week, so it is week number 0, and
* getActualMinimum(WEEK_OF_MONTH)
will return 0.
*
* @param field the field whose actual minimum value is desired.
* @return the minimum of the given field for the current date of this calendar
*
* @see #getMinimum
* @see #getGreatestMinimum
* @stable ICU 2.0
*/
public int getActualMinimum(int field) {
return calendar.getActualMinimum(getJDKField(field));
}
/**
* Rolls (up/down) a single unit of time on the given field. If the
* field is rolled past its maximum allowable value, it will "wrap" back
* to its minimum and continue rolling. For
* example, to roll the current date up by one day, you can call:
*
* roll({@link #DATE}, true)
*
* When rolling on the {@link #YEAR} field, it will roll the year
* value in the range between 1 and the value returned by calling
* {@link #getMaximum getMaximum}({@link #YEAR}).
*
* When rolling on certain fields, the values of other fields may conflict and
* need to be changed. For example, when rolling the MONTH
field
* for the Gregorian date 1/31/96 upward, the DAY_OF_MONTH
field
* must be adjusted so that the result is 2/29/96 rather than the invalid
* 2/31/96.
*
* Note: Calling roll(field, true) N times is not
* necessarily equivalent to calling roll(field, N). For example,
* imagine that you start with the date Gregorian date January 31, 1995. If you call
* roll(Calendar.MONTH, 2), the result will be March 31, 1995.
* But if you call roll(Calendar.MONTH, true), the result will be
* February 28, 1995. Calling it one more time will give March 28, 1995, which
* is usually not the desired result.
*
* 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.
*
* @param field the calendar field to roll.
*
* @param up indicates if the value of the specified time field is to be
* rolled up or rolled down. Use true
if rolling up,
* false
otherwise.
*
* @exception IllegalArgumentException if the field is invalid or refers
* to a field that cannot be handled by this method.
* @see #roll(int, int)
* @see #add
* @stable ICU 2.0
*/
public final void roll(int field, boolean up)
{
calendar.roll(getJDKField(field), up);
}
/**
* Rolls (up/down) a specified amount time on the given field. For
* example, to roll the current date up by three days, you can call
* roll(Calendar.DATE, 3)
. If the
* field is rolled past its maximum allowable value, it will "wrap" back
* to its minimum and continue rolling.
* For example, calling roll(Calendar.DATE, 10)
* on a Gregorian calendar set to 4/25/96 will result in the date 4/5/96.
*
* When rolling on certain fields, the values of other fields may conflict and
* need to be changed. For example, when rolling the {@link #MONTH MONTH} field
* for the Gregorian date 1/31/96 by +1, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
* must be adjusted so that the result is 2/29/96 rather than the invalid
* 2/31/96.
*
* {@icunote} the ICU implementation of this method is able to roll
* all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
* and {@link #ZONE_OFFSET ZONE_OFFSET}. Subclasses may, of course, add support for
* additional fields in their overrides of roll
.
*
* 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.
*
* Subclassing:
* This implementation of roll
assumes that the behavior of the
* field is continuous between its minimum and maximum, which are found by
* calling {@link #getActualMinimum getActualMinimum} and {@link #getActualMaximum getActualMaximum}.
* For most such fields, simple addition, subtraction, and modulus operations
* are sufficient to perform the roll. For week-related fields,
* the results of {@link #getFirstDayOfWeek getFirstDayOfWeek} and
* {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} are also necessary.
* Subclasses can override these two methods if their values differ from the defaults.
*
* Subclasses that have fields for which the assumption of continuity breaks
* down must overide roll
to handle those fields specially.
* For example, in the Hebrew calendar the month "Adar I"
* only occurs in leap years; in other years the calendar jumps from
* Shevat (month #4) to Adar (month #6). The
* {@link HebrewCalendar#roll HebrewCalendar.roll} method takes this into account,
* so that rolling the month of Shevat by one gives the proper result (Adar) in a
* non-leap year.
*
* @param field the calendar field to roll.
* @param amount the amount by which the field should be rolled.
*
* @exception IllegalArgumentException if the field is invalid or refers
* to a field that cannot be handled by this method.
* @see #roll(int, boolean)
* @see #add
* @stable ICU 2.0
*/
public void roll(int field, int amount) {
calendar.roll(getJDKField(field), amount);
}
/**
* Add a signed amount to a specified field, using this calendar's rules.
* For example, to add three days to the current date, you can call
* add(Calendar.DATE, 3)
.
*
* When adding to certain fields, the values of other fields may conflict and
* need to be changed. For example, when adding one to the {@link #MONTH MONTH} field
* for the Gregorian date 1/31/96, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
* must be adjusted so that the result is 2/29/96 rather than the invalid
* 2/31/96.
*
* {@icunote} The ICU implementation of this method is able to add to
* all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
* and {@link #ZONE_OFFSET ZONE_OFFSET}. Subclasses may, of course, add support for
* additional fields in their overrides of add
.
*
* 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.
*
* Subclassing:
* This implementation of add
assumes that the behavior of the
* field is continuous between its minimum and maximum, which are found by
* calling {@link #getActualMinimum getActualMinimum} and
* {@link #getActualMaximum getActualMaximum}.
* For such fields, simple arithmetic operations are sufficient to
* perform the add.
*
* Subclasses that have fields for which this assumption of continuity breaks
* down must overide add
to handle those fields specially.
* For example, in the Hebrew calendar the month "Adar I"
* only occurs in leap years; in other years the calendar jumps from
* Shevat (month #4) to Adar (month #6). The
* {@link HebrewCalendar#add HebrewCalendar.add} method takes this into account,
* so that adding one month
* to a date in Shevat gives the proper result (Adar) in a non-leap year.
*
* @param field the time field.
* @param amount the amount to add to the field.
*
* @exception IllegalArgumentException if the field is invalid or refers
* to a field that cannot be handled by this method.
* @see #roll(int, int)
* @stable ICU 2.0
*/
public void add(int field, int amount) {
calendar.add(getJDKField(field), amount);
}
private static String _getDisplayName(Calendar cal) {
String type = cal.getType();
if (type.equals("japanese")) {
return "Japanese Calendar";
} else if (type.equals("buddhist")) {
return "Buddhist Calendar";
}
return "Gregorian Calendar";
}
/**
* Returns the name of this calendar in the language of the given locale.
* @stable ICU 2.0
*/
public String getDisplayName(Locale loc) {
return _getDisplayName(this);
}
/**
* Returns the name of this calendar in the language of the given locale.
* @stable ICU 3.2
*/
public String getDisplayName(ULocale loc) {
return _getDisplayName(this);
}
/**
* Compares the times (in millis) represented by two
* Calendar
objects.
*
* @param that the Calendar
to compare to this.
* @return 0
if the time represented by
* this Calendar
is equal to the time represented
* by that Calendar
, a value less than
* 0
if the time represented by this is before
* the time represented by that, and a value greater than
* 0
if the time represented by this
* is after the time represented by that.
* @throws NullPointerException if that
* Calendar
is null.
* @throws IllegalArgumentException if the time of that
* Calendar
can't be obtained because of invalid
* calendar values.
* @stable ICU 3.4
*/
public int compareTo(Calendar that) {
return calendar.compareTo(that.calendar);
}
//-------------------------------------------------------------------------
// Interface for creating custon DateFormats for different types of Calendars
//-------------------------------------------------------------------------
/**
* {@icu} Returns a DateFormat
appropriate to this calendar.
* Subclasses wishing to specialize this behavior should override
* {@link #handleGetDateFormat}.
* @stable ICU 2.0
*/
public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, Locale loc) {
if (dateStyle != DateFormat.NONE) {
if (timeStyle == DateFormat.NONE) {
return DateFormat.getDateInstance((Calendar)this.clone(), dateStyle, loc);
} else {
return DateFormat.getDateTimeInstance((Calendar)this.clone(), dateStyle, timeStyle, loc);
}
} else if (timeStyle != DateFormat.NONE) {
return DateFormat.getTimeInstance((Calendar)this.clone(), timeStyle, loc);
} else {
return null;
}
}
/**
* {@icu} Returns a DateFormat
appropriate to this calendar.
* Subclasses wishing to specialize this behavior should override
* {@link #handleGetDateFormat}.
* @stable ICU 3.2
*/
public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, ULocale loc) {
return getDateTimeFormat(dateStyle, timeStyle, loc.toLocale());
}
//-------------------------------------------------------------------------
// Constants
//-------------------------------------------------------------------------
/**
* {@icu} Returns the difference between the given time and the time this
* calendar object is set to. If this calendar is set
* before the given time, the returned value will be
* positive. If this calendar is set after the given
* time, the returned value will be negative. The
* field
parameter specifies the units of the return
* value. For example, if fieldDifference(when,
* Calendar.MONTH)
returns 3, then this calendar is set to
* 3 months before when
, and possibly some additional
* time less than one month.
*
*
As a side effect of this call, this calendar is advanced
* toward when
by the given amount. That is, calling
* this method has the side effect of calling add(field,
* n)
, where n
is the return value.
*
*
Usage: To use this method, call it first with the largest
* field of interest, then with progressively smaller fields. For
* example:
*
*
* int y = cal.fieldDifference(when, Calendar.YEAR);
* int m = cal.fieldDifference(when, Calendar.MONTH);
* int d = cal.fieldDifference(when, Calendar.DATE);
*
* computes the difference between cal
and
* when
in years, months, and days.
*
* Note: fieldDifference()
is
* asymmetrical. That is, in the following code:
*
*
* cal.setTime(date1);
* int m1 = cal.fieldDifference(date2, Calendar.MONTH);
* int d1 = cal.fieldDifference(date2, Calendar.DATE);
* cal.setTime(date2);
* int m2 = cal.fieldDifference(date1, Calendar.MONTH);
* int d2 = cal.fieldDifference(date1, Calendar.DATE);
*
* one might expect that m1 == -m2 && d1 == -d2
.
* However, this is not generally the case, because of
* irregularities in the underlying calendar system (e.g., the
* Gregorian calendar has a varying number of days per month).
*
* @param when the date to compare this calendar's time to
* @param field the field in which to compute the result
* @return the difference, either positive or negative, between
* this calendar's time and when
, in terms of
* field
.
* @stable ICU 2.0
*/
public int fieldDifference(Date when, int field) {
int min = 0;
long startMs = getTimeInMillis();
long targetMs = when.getTime();
// Always add from the start millis. This accomodates
// operations like adding years from February 29, 2000 up to
// February 29, 2004. If 1, 1, 1, 1 is added to the year
// field, the DOM gets pinned to 28 and stays there, giving an
// incorrect DOM difference of 1. We have to add 1, reset, 2,
// reset, 3, reset, 4.
if (startMs < targetMs) {
int max = 1;
// Find a value that is too large
for (;;) {
setTimeInMillis(startMs);
add(field, max);
long ms = getTimeInMillis();
if (ms == targetMs) {
return max;
} else if (ms > targetMs) {
break;
} else {
max <<= 1;
if (max < 0) {
// Field difference too large to fit into int
throw new RuntimeException();
}
}
}
// Do a binary search
while ((max - min) > 1) {
int t = (min + max) / 2;
setTimeInMillis(startMs);
add(field, t);
long ms = getTimeInMillis();
if (ms == targetMs) {
return t;
} else if (ms > targetMs) {
max = t;
} else {
min = t;
}
}
} else if (startMs > targetMs) {
//Eclipse stated the following is "dead code"
/*if (false) {
// This works, and makes the code smaller, but costs
// an extra object creation and an extra couple cycles
// of calendar computation.
setTimeInMillis(targetMs);
min = -fieldDifference(new Date(startMs), field);
}*/
int max = -1;
// Find a value that is too small
for (;;) {
setTimeInMillis(startMs);
add(field, max);
long ms = getTimeInMillis();
if (ms == targetMs) {
return max;
} else if (ms < targetMs) {
break;
} else {
max <<= 1;
if (max == 0) {
// Field difference too large to fit into int
throw new RuntimeException();
}
}
}
// Do a binary search
while ((min - max) > 1) {
int t = (min + max) / 2;
setTimeInMillis(startMs);
add(field, t);
long ms = getTimeInMillis();
if (ms == targetMs) {
return t;
} else if (ms < targetMs) {
max = t;
} else {
min = t;
}
}
}
// Set calendar to end point
setTimeInMillis(startMs);
add(field, min);
return min;
}
/**
* Sets the time zone with the given time zone value.
* @param value the given time zone.
* @stable ICU 2.0
*/
public void setTimeZone(TimeZone value)
{
calendar.setTimeZone(value.timeZone);
}
/**
* Returns the time zone.
* @return the time zone object associated with this calendar.
* @stable ICU 2.0
*/
public TimeZone getTimeZone()
{
return new TimeZone(calendar.getTimeZone());
}
/**
* Specify whether or not date/time interpretation is to be lenient. With
* lenient interpretation, a date such as "February 942, 1996" will be
* treated as being equivalent to the 941st day after February 1, 1996.
* With strict interpretation, such dates will cause an exception to be
* thrown.
*
* @see DateFormat#setLenient
* @stable ICU 2.0
*/
public void setLenient(boolean lenient)
{
calendar.setLenient(lenient);
}
/**
* Tell whether date/time interpretation is to be lenient.
* @stable ICU 2.0
*/
public boolean isLenient()
{
return calendar.isLenient();
}
// /**
// * {@icu}Sets the behavior for handling wall time repeating multiple times
// * at negative time zone offset transitions. For example, 1:30 AM on
// * November 6, 2011 in US Eastern time (Ameirca/New_York) occurs twice;
// * 1:30 AM EDT, then 1:30 AM EST one hour later. When WALLTIME_FIRST
// * is used, the wall time 1:30AM in this example will be interpreted as 1:30 AM EDT
// * (first occurrence). When WALLTIME_LAST
is used, it will be
// * interpreted as 1:30 AM EST (last occurrence). The default value is
// * WALLTIME_LAST
.
// *
// * @param option the behavior for handling repeating wall time, either
// * WALLTIME_FIRST
or WALLTIME_LAST
.
// * @throws IllegalArgumentException when option
is neither
// * WALLTIME_FIRST
nor WALLTIME_LAST
.
// *
// * @see #getRepeatedWallTimeOption()
// * @see #WALLTIME_FIRST
// * @see #WALLTIME_LAST
// *
// * @draft ICU 49
// * @provisional This API might change or be removed in a future release.
// */
// public void setRepeatedWallTimeOption(int option) {
// if (option != WALLTIME_LAST) {
// throw new UnsupportedOperationException("The option not supported by com.ibm.icu.base");
// }
// }
/**
* {@icu}Gets the behavior for handling wall time repeating multiple times
* at negative time zone offset transitions.
*
* @return the behavior for handling repeating wall time, either
* WALLTIME_FIRST
or WALLTIME_LAST
.
*
* @see #setRepeatedWallTimeOption(int)
* @see #WALLTIME_FIRST
* @see #WALLTIME_LAST
*
* @draft ICU 49
* @provisional This API might change or be removed in a future release.
*/
public int getRepeatedWallTimeOption() {
return WALLTIME_LAST;
}
// /**
// * {@icu}Sets the behavior for handling skipped wall time at positive time zone offset
// * transitions. For example, 2:30 AM on March 13, 2011 in US Eastern time (America/New_York)
// * does not exist because the wall time jump from 1:59 AM EST to 3:00 AM EDT. When
// * WALLTIME_FIRST
is used, 2:30 AM is interpreted as 30 minutes before 3:00 AM
// * EDT, therefore, it will be resolved as 1:30 AM EST. When WALLTIME_LAST
// * is used, 2:30 AM is interpreted as 31 minutes after 1:59 AM EST, therefore, it will be
// * resolved as 3:30 AM EDT. When WALLTIME_NEXT_VALID
is used, 2:30 AM will
// * be resolved as next valid wall time, that is 3:00 AM EDT. The default value is
// * WALLTIME_LAST
.
// *
// * Note:This option is effective only when this calendar is {@link #isLenient() lenient}.
// * When the calendar is strict, such non-existing wall time will cause an exception.
// *
// * @param option the behavior for handling skipped wall time at positive time zone
// * offset transitions, one of WALLTIME_FIRST
, WALLTIME_LAST
and
// * WALLTIME_NEXT_VALID
.
// * @throws IllegalArgumentException when option
is not any of
// * WALLTIME_FIRST
, WALLTIME_LAST
and WALLTIME_NEXT_VALID
.
// *
// * @see #getSkippedWallTimeOption()
// * @see #WALLTIME_FIRST
// * @see #WALLTIME_LAST
// * @see #WALLTIME_NEXT_VALID
// *
// * @draft ICU 49
// * @provisional This API might change or be removed in a future release.
// */
// public void setSkippedWallTimeOption(int option) {
// if (option != WALLTIME_LAST) {
// throw new UnsupportedOperationException("The option not supported by com.ibm.icu.base");
// }
// }
/**
* {@icu}Gets the behavior for handling skipped wall time at positive time zone offset
* transitions.
*
* @return the behavior for handling skipped wall time, one of
* WALLTIME_FIRST
, WALLTIME_LAST
and WALLTIME_NEXT_VALID
.
*
* @see #setSkippedWallTimeOption(int)
* @see #WALLTIME_FIRST
* @see #WALLTIME_LAST
* @see #WALLTIME_NEXT_VALID
*
* @draft ICU 49
* @provisional This API might change or be removed in a future release.
*/
public int getSkippedWallTimeOption() {
return WALLTIME_LAST;
}
/**
* Sets what the first day of the week is; e.g., Sunday in US,
* Monday in France.
* @param value the given first day of the week.
* @stable ICU 2.0
*/
public void setFirstDayOfWeek(int value)
{
calendar.setFirstDayOfWeek(value);
}
/**
* Returns what the first day of the week is; e.g., Sunday in US,
* Monday in France.
* @return the first day of the week.
* @stable ICU 2.0
*/
public int getFirstDayOfWeek()
{
return calendar.getFirstDayOfWeek();
}
/**
* Sets what the minimal days required in the first week of the year are.
* For example, if the first week is defined as one that contains the first
* day of the first month of a year, call the method with value 1. If it
* must be a full week, use value 7.
* @param value the given minimal days required in the first week
* of the year.
* @stable ICU 2.0
*/
public void setMinimalDaysInFirstWeek(int value)
{
calendar.setMinimalDaysInFirstWeek(value);
}
/**
* Returns what the minimal days required in the first week of the year are;
* e.g., if the first week is defined as one that contains the first day
* of the first month of a year, getMinimalDaysInFirstWeek returns 1. If
* the minimal days required must be a full week, getMinimalDaysInFirstWeek
* returns 7.
* @return the minimal days required in the first week of the year.
* @stable ICU 2.0
*/
public int getMinimalDaysInFirstWeek()
{
return calendar.getMinimalDaysInFirstWeek();
}
/**
* Returns the minimum value for the given time field.
* e.g., for Gregorian DAY_OF_MONTH, 1.
* @param field the given time field.
* @return the minimum value for the given time field.
* @stable ICU 2.0
*/
public final int getMinimum(int field) {
return calendar.getMinimum(getJDKField(field));
}
/**
* Returns the maximum value for the given time field.
* e.g. for Gregorian DAY_OF_MONTH, 31.
* @param field the given time field.
* @return the maximum value for the given time field.
* @stable ICU 2.0
*/
public final int getMaximum(int field) {
return calendar.getMaximum(getJDKField(field));
}
/**
* Returns the highest minimum value for the given field if varies.
* Otherwise same as getMinimum(). For Gregorian, no difference.
* @param field the given time field.
* @return the highest minimum value for the given time field.
* @stable ICU 2.0
*/
public final int getGreatestMinimum(int field) {
return calendar.getGreatestMinimum(getJDKField(field));
}
/**
* Returns the lowest maximum value for the given field if varies.
* Otherwise same as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28.
* @param field the given time field.
* @return the lowest maximum value for the given time field.
* @stable ICU 2.0
*/
public final int getLeastMaximum(int field) {
return calendar.getLeastMaximum(getJDKField(field));
}
//-------------------------------------------------------------------------
// Weekend support -- determining which days of the week are the weekend
// in a given locale
//-------------------------------------------------------------------------
/**
* {@icu} Returns whether the given day of the week is a weekday, a
* weekend day, or a day that transitions from one to the other,
* in this calendar system. If a transition occurs at midnight,
* then the days before and after the transition will have the
* type WEEKDAY or WEEKEND. If a transition occurs at a time
* other than midnight, then the day of the transition will have
* the type WEEKEND_ONSET or WEEKEND_CEASE. In this case, the
* method getWeekendTransition() will return the point of
* transition.
* @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
* THURSDAY, FRIDAY, or SATURDAY
* @return either WEEKDAY, WEEKEND, WEEKEND_ONSET, or
* WEEKEND_CEASE
* @exception IllegalArgumentException if dayOfWeek is not
* between SUNDAY and SATURDAY, inclusive
* @see #WEEKDAY
* @see #WEEKEND
* @see #WEEKEND_ONSET
* @see #WEEKEND_CEASE
* @see #getWeekendTransition
* @see #isWeekend(Date)
* @see #isWeekend()
* @stable ICU 2.0
*/
public int getDayOfWeekType(int dayOfWeek) {
// weekend always full saturday and sunday with com.ibm.icu.base
if (dayOfWeek < SUNDAY || dayOfWeek > 7) {
throw new IllegalArgumentException("illegal day of week: " + dayOfWeek);
} else if (dayOfWeek == SATURDAY || dayOfWeek == SUNDAY) {
return WEEKEND;
}
return WEEKDAY;}
// /**
// * {@icu} Returns the time during the day at which the weekend begins or end in this
// * calendar system. If getDayOfWeekType(dayOfWeek) == WEEKEND_ONSET return the time
// * at which the weekend begins. If getDayOfWeekType(dayOfWeek) == WEEKEND_CEASE
// * return the time at which the weekend ends. If getDayOfWeekType(dayOfWeek) has some
// * other value, then throw an exception.
// * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
// * THURSDAY, FRIDAY, or SATURDAY
// * @return the milliseconds after midnight at which the
// * weekend begins or ends
// * @exception IllegalArgumentException if dayOfWeek is not
// * WEEKEND_ONSET or WEEKEND_CEASE
// * @see #getDayOfWeekType
// * @see #isWeekend(Date)
// * @see #isWeekend()
// * @stable ICU 2.0
// */
// public int getWeekendTransition(int dayOfWeek) {
// throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
// }
/**
* {@icu} Returns true if the given date and time is in the weekend in this calendar
* system. Equivalent to calling setTime() followed by isWeekend(). Note: This
* method changes the time this calendar is set to.
* @param date the date and time
* @return true if the given date and time is part of the
* weekend
* @see #getDayOfWeekType
* @see #getWeekendTransition
* @see #isWeekend()
* @stable ICU 2.0
*/
public boolean isWeekend(Date date) {
calendar.setTime(date);
return isWeekend();
}
/**
* {@icu} Returns true if this Calendar's current date and time is in the weekend in
* this calendar system.
* @return true if the given date and time is part of the
* weekend
* @see #getDayOfWeekType
* @see #getWeekendTransition
* @see #isWeekend(Date)
* @stable ICU 2.0
*/
public boolean isWeekend() {
// weekend always full saturday and sunday with com.ibm.icu.base
int dow = calendar.get(Calendar.DAY_OF_WEEK);
if (dow == SATURDAY || dow == SUNDAY) {
return true;
}
return false;
}
//-------------------------------------------------------------------------
// End of weekend support
//-------------------------------------------------------------------------
/**
* Overrides Cloneable
* @stable ICU 2.0
*/
public Object clone()
{
return new Calendar((java.util.Calendar)calendar.clone());
}
/**
* Returns a string representation of this calendar. This method
* is intended to be used only for debugging purposes, and the
* format of the returned string may vary between implementations.
* The returned string may be empty but may not be null
.
*
* @return a string representation of this calendar.
* @stable ICU 2.0
*/
public String toString() {
return calendar.toString();
}
/**
* {@icu} Returns the number of fields defined by this calendar. Valid field
* arguments to set()
and get()
are
* 0..getFieldCount()-1
.
* @stable ICU 2.0
*/
public final int getFieldCount() {
return FIELD_COUNT;
}
private static final int FIELD_COUNT = /* IS_LEAP_MONTH */ DST_OFFSET + 1;
/**
* {@icu} Returns the current Calendar type. Note, in 3.0 this function will return
* 'gregorian' in Calendar to emulate legacy behavior
* @return type of calendar (gregorian, etc)
* @stable ICU 3.8
*/
public String getType() {
// JDK supports Gregorian, Japanese and Buddhist
String name = calendar.getClass().getSimpleName().toLowerCase(Locale.US);
if (name.contains("japanese")) {
return "japanese";
} else if (name.contains("buddhist")) {
return "buddhist";
}
return "gregorian";
}
// -------- BEGIN ULocale boilerplate --------
// /**
// * {@icu} Returns the locale that was used to create this object, or null.
// * This may may differ from the locale requested at the time of
// * this object's creation. For example, if an object is created
// * for locale en_US_CALIFORNIA, the actual data may be
// * drawn from en (the actual locale), and
// * en_US may be the most specific locale that exists (the
// * valid locale).
// *
// *
Note: This method will be implemented in ICU 3.0; ICU 2.8
// * contains a partial preview implementation. The * actual
// * locale is returned correctly, but the valid locale is
// * not, in most cases.
// * @param type type of information requested, either {@link
// * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
// * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
// * @return the information specified by type, or null if
// * this object was not constructed from locale data.
// * @see com.ibm.icu.util.ULocale
// * @see com.ibm.icu.util.ULocale#VALID_LOCALE
// * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
// * @draft ICU 2.8 (retain)
// * @provisional This API might change or be removed in a future release.
// */
// public final ULocale getLocale(ULocale.Type type) {
// throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
// }
// -------- END ULocale boilerplate --------
private static int getJDKField(int icuField) {
switch (icuField) {
case ERA:
return java.util.Calendar.ERA;
case YEAR:
return java.util.Calendar.YEAR;
case MONTH:
return java.util.Calendar.MONTH;
case WEEK_OF_YEAR:
return java.util.Calendar.WEEK_OF_YEAR;
case WEEK_OF_MONTH:
return java.util.Calendar.WEEK_OF_MONTH;
case DATE:
return java.util.Calendar.DATE;
// case DAY_OF_MONTH:
// return java.util.Calendar.DAY_OF_MONTH;
case DAY_OF_YEAR:
return java.util.Calendar.DAY_OF_YEAR;
case DAY_OF_WEEK:
return java.util.Calendar.DAY_OF_WEEK;
case DAY_OF_WEEK_IN_MONTH:
return java.util.Calendar.DAY_OF_WEEK_IN_MONTH;
case AM_PM:
return java.util.Calendar.AM_PM;
case HOUR:
return java.util.Calendar.HOUR;
case HOUR_OF_DAY:
return java.util.Calendar.HOUR_OF_DAY;
case MINUTE:
return java.util.Calendar.MINUTE;
case SECOND:
return java.util.Calendar.SECOND;
case MILLISECOND:
return java.util.Calendar.MILLISECOND;
case ZONE_OFFSET:
return java.util.Calendar.ZONE_OFFSET;
case DST_OFFSET:
return java.util.Calendar.DST_OFFSET;
// case YEAR_WOY:
// case DOW_LOCAL:
// case EXTENDED_YEAR:
// case JULIAN_DAY:
// case MILLISECONDS_IN_DAY:
// // Unmappable
// throw new UnsupportedOperationException("Calendar field type not supported by com.ibm.icu.base");
default:
// Illegal
throw new ArrayIndexOutOfBoundsException("Specified calendar field is out of range");
}
}
}