FileDocCategorySizeDatePackage
Calendar.javaAPI DocphoneME MR2 API (J2ME)39790Wed May 02 17:59:54 BST 2007java.util

Calendar

public abstract class Calendar extends Object
Calendar is an abstract class for getting and setting dates using a set of integer fields such as YEAR, MONTH, DAY, 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.

Like other locale-sensitive classes, Calendar provides a class method, getInstance, for getting a generally useful object of this type.

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).

When computing a Date from time fields, there may be insufficient information to compute the Date (such as only year and month but no day in the month).

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. In the J2SE calendar, it is possible to set fields inconsistently. However, in this subset, the DAY_OF_WEEK field cannot be set, and only a subset of the other J2SE Calendar fields are included. So it is not possible to set inconsistent data.

Note: The ambiguity in interpretation of what day midnight belongs to, is resolved as so: midnight "belongs" to the following day.
23:59 on Dec 31, 1969 < 00:00 on Jan 1, 1970.
12:00 PM is midday, and 12:00 AM is midnight.
11:59 PM on Jan 1 < 12:00 AM on Jan 2 < 12:01 AM on Jan 2.
11:59 AM on Mar 10 < 12:00 PM on Mar 10 < 12:01 PM on Mar 10.
24:00 or greater are invalid. Hours greater than 12 are invalid in AM/PM mode. Setting the time will never change the date.

If equivalent times are entered in AM/PM or 24 hour mode, equality will be determined by the actual time rather than the entered time.

This class is a subset for J2ME of the J2SE Calendar class. Many methods and variables have been pruned, and other methods simplified, in an effort to reduce the size of this class.

see
TimeZone
version
1.0 (J2ME MIDP)

Fields Summary
public static final int
YEAR
Field number for get and set indicating the year. This is a calendar-specific value.
public static final int
MONTH
Field number for get and set indicating the month. This is a calendar-specific value.
public static final int
DATE
Field number for get and set indicating the day of the month. This is a synonym for DAY_OF_MONTH.
public static final int
DAY_OF_MONTH
Field number for get and set indicating the day of the month. This is a synonym for DATE.
public static final int
DAY_OF_WEEK
Field number for get and set indicating the day of the week.
public static final int
AM_PM
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.
public static final int
HOUR
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.
public static final int
HOUR_OF_DAY
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.
public static final int
MINUTE
Field number for get and set indicating the minute within the hour. E.g., at 10:04:15.250 PM the MINUTE is 4.
public static final int
SECOND
Field number for get and set indicating the second within the minute. E.g., at 10:04:15.250 PM the SECOND is 15.
public static final int
MILLISECOND
Field number for get and set indicating the millisecond within the second. E.g., at 10:04:15.250 PM the MILLISECOND is 250.
public static final int
SUNDAY
Value of the DAY_OF_WEEK field indicating Sunday.
public static final int
MONDAY
Value of the DAY_OF_WEEK field indicating Monday.
public static final int
TUESDAY
Value of the DAY_OF_WEEK field indicating Tuesday.
public static final int
WEDNESDAY
Value of the DAY_OF_WEEK field indicating Wednesday.
public static final int
THURSDAY
Value of the DAY_OF_WEEK field indicating Thursday.
public static final int
FRIDAY
Value of the DAY_OF_WEEK field indicating Friday.
public static final int
SATURDAY
Value of the DAY_OF_WEEK field indicating Saturday.
public static final int
JANUARY
Value of the MONTH field indicating the first month of the year.
public static final int
FEBRUARY
Value of the MONTH field indicating the second month of the year.
public static final int
MARCH
Value of the MONTH field indicating the third month of the year.
public static final int
APRIL
Value of the MONTH field indicating the fourth month of the year.
public static final int
MAY
Value of the MONTH field indicating the fifth month of the year.
public static final int
JUNE
Value of the MONTH field indicating the sixth month of the year.
public static final int
JULY
Value of the MONTH field indicating the seventh month of the year.
public static final int
AUGUST
Value of the MONTH field indicating the eighth month of the year.
public static final int
SEPTEMBER
Value of the MONTH field indicating the ninth month of the year.
public static final int
OCTOBER
Value of the MONTH field indicating the tenth month of the year.
public static final int
NOVEMBER
Value of the MONTH field indicating the eleventh month of the year.
public static final int
DECEMBER
Value of the MONTH field indicating the twelfth month of the year.
public static final int
AM
Value of the AM_PM field indicating the period of the day from midnight to just before noon.
public static final int
PM
Value of the AM_PM field indicating the period of the day from noon to just before midnight.
private int
packed_time
private int
packed_date
private int
day_field
private int
dstOffset
private boolean
dstSet
private long
time
The currently set time for this calendar, expressed in milliseconds after January 1, 1970, 0:00:00 GMT.
private boolean
millisSet
True if then the value of time is valid. The time is made invalid by a change to an item of field[].
private TimeZone
zone
The TimeZone used by this calendar. Calendar uses the time zone data to translate between locale and GMT time.
private static final int
JAN_1_1_JULIAN_DAY
private static final int
EPOCH_JULIAN_DAY
private static final int
EPOCH_YEAR
private static final int[]
NUM_DAYS
private static final int[]
LEAP_NUM_DAYS
private static final int
ONE_SECOND
private static final int
ONE_MINUTE
private static final int
ONE_HOUR
private static final long
ONE_DAY
private static final long
ONE_WEEK
private static final long
gregorianCutover
The point at which the Gregorian calendar rules are used, measured in milliseconds from the standard epoch. Default is October 15, 1582 (Gregorian) 00:00:00 UTC or -12219292800000L. For this value, October 4, 1582 (Julian) is followed by October 15, 1582 (Gregorian). This corresponds to Julian day number 2299161.
private static final int
gregorianCutoverYear
The year of the gregorianCutover, with 0 representing 1 BC, -1 representing 2 BC, etc.
private Date
date
private int
hour_12hr
if both of these are set, the set() method will recalculate the HOUR_OF_DAY using 12hr time.
private int
am_pm_12hr
private static String
platform
The platform name
private static String
classRoot
The root of the classes
Constructors Summary
protected Calendar()
Constructs a Calendar with the default time zone and default locale.

see
TimeZone#getDefault


                      
    
    zone = TimeZone.getDefault();
    if (zone == null) {
        throw new RuntimeException(
/* #ifdef VERBOSE_EXCEPTIONS */
/// skipped                   "Could not find default timezone"
/* #endif */
        );
    }
    setTimeInMillis(System.currentTimeMillis());
  
Methods Summary
public booleanafter(java.lang.Object when)
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.

    return (when instanceof Calendar
            && getTimeInMillis() > ((Calendar)when).getTimeInMillis());
  
public booleanbefore(java.lang.Object when)
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.

    return (when instanceof Calendar
            && getTimeInMillis() < ((Calendar)when).getTimeInMillis());
  
private voidcalculateDstOffset()

    if (day_field == 0) {
      getTimeInMillis();
      calculateFields();
    }
    int rawOffset = zone.getRawOffset();
    long localMillis = time + rawOffset;
    long days = (long) (localMillis / ONE_DAY);
    int millisInDay = (int) (localMillis - (days * ONE_DAY));
    if (millisInDay < 0)
      millisInDay += ONE_DAY;
    dstOffset = zone.getOffset(1,
                               packed_date >> 9,
                               (packed_date >> 5) & 15,
                               packed_date & 31,
                               day_field,
                               millisInDay) - rawOffset;
    dstSet = true;
  
private voidcalculateFields()
Converts UTC as milliseconds to time field values.

    int rawOffset = zone.getRawOffset();
    long localMillis = time + rawOffset;

    /* Check for very extreme values -- millis near Long.MIN_VALUE or
     * Long.MAX_VALUE.  For these values, adding the zone offset can push
     * the millis past MAX_VALUE to MIN_VALUE, or vice versa.  This produces
     * the undesirable effect that the time can wrap around at the ends,
     * yielding, for example, a Date(Long.MAX_VALUE) with a big BC year
     * (should be AD).  Handle this by pinning such values to Long.MIN_VALUE
     * or Long.MAX_VALUE. - liu 8/11/98 CR 4149677 */
    if (time > 0 && localMillis < 0 && rawOffset > 0) {
      localMillis = Long.MAX_VALUE;
    } else if (time < 0 && localMillis > 0 && rawOffset < 0) {
      localMillis = Long.MIN_VALUE;
    }

    // Time to fields takes the wall millis (Standard or DST).
    timeToFields(localMillis);

    long days = (long) (localMillis / ONE_DAY);
    int millisInDay = (int) (localMillis - (days * ONE_DAY));
    if (millisInDay < 0) millisInDay += ONE_DAY;

    // Call getOffset() to get the TimeZone offset.  The millisInDay value must
    // be standard local millis.
    dstOffset = zone.getOffset(1,
                               packed_date >> 9,
                               (packed_date >> 5) & 15,
                               packed_date & 31,
                               day_field,
                               millisInDay) - rawOffset;
    dstSet = true;

    // Adjust our millisInDay for DST, if necessary.
    millisInDay += dstOffset;

    // If DST has pushed us into the next day, we must call timeToFields() again.
    // This happens in DST between 12:00 am and 1:00 am every day.  The call to
    // timeToFields() will give the wrong day, since the Standard time is in the
    // previous day.
    if (millisInDay >= ONE_DAY) {
      long dstMillis = localMillis + dstOffset;
      millisInDay -= ONE_DAY;
      // As above, check for and pin extreme values
      if (localMillis > 0 && dstMillis < 0 && dstOffset > 0) {
        dstMillis = Long.MAX_VALUE;
      } else if (localMillis < 0 && dstMillis > 0 && dstOffset < 0) {
        dstMillis = Long.MIN_VALUE;
      }
      timeToFields(dstMillis);
    }

    // Fill in all time-related fields based on millisInDay.
    // so as not to perturb flags.
    packed_time = (packed_time & (~1023)) | (millisInDay % 1000);
    millisInDay /= 1000;
    packed_time = (packed_time & (~(63<<10))) | ((millisInDay % 60) << 10);
    millisInDay /= 60;
    packed_time = (packed_time & (~(63<<16))) | ((millisInDay % 60) << 16);
    millisInDay /= 60;
    packed_time = (packed_time & (~(31<<22))) | ((millisInDay & 31) << 22);
  
private final longcalculateJulianDay(boolean isGregorian, int year)
Compute the Julian day number under either the Gregorian or the Julian calendar, using the given year and the remaining fields.

param
isGregorian if true, use the Gregorian calendar
param
year the adjusted year number, with 0 indicating the year 1 BC, -1 indicating 2 BC, etc.
return
the Julian day number

    int month = 0, y;
    long millis = 0;

    month = (packed_date >> 5) & 15 - JANUARY;

    // If the month is out of range, adjust it into range
    if (month < 0 || month > 11) {
      int[] rem = new int[1];
      year += floorDivide(month, 12, rem);
      month = rem[0];
    }

    boolean isLeap = year%4 == 0;
    y = year - 1;
    long julianDay = 365L*y + floorDivide(y, 4) + (JAN_1_1_JULIAN_DAY - 3);

    if (isGregorian) {
      isLeap = isLeap && ((year%100 != 0) || (year%400 == 0));
      // Add 2 because Gregorian calendar starts 2 days after Julian calendar
      julianDay += floorDivide(y, 400) - floorDivide(y, 100) + 2;
    }

    // At this point julianDay is the 0-based day BEFORE the first day of
    // January 1, year 1 of the given calendar.  If julianDay == 0, it
    // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian
    // or Gregorian).

    julianDay += isLeap ? LEAP_NUM_DAYS[month] : NUM_DAYS[month];
    julianDay += packed_date & 31;
    return julianDay;
  
private voidcalculateTime()
Converts time field values to UTC as milliseconds.

exception
IllegalArgumentException if any fields are invalid.


    // This function takes advantage of the fact that unset fields in
    // the time field list have a value of zero.

    // First, use the year to determine whether to use the Gregorian or the
    // Julian calendar. If the year is not the year of the cutover, this
    // computation will be correct. But if the year is the cutover year,
    // this may be incorrect. In that case, assume the Gregorian calendar,
    // make the computation, and then recompute if the resultant millis
    // indicate the wrong calendar has been assumed.

    // A date such as Oct. 10, 1582 does not exist in a Gregorian calendar
    // with the default changeover of Oct. 15, 1582, since in such a
    // calendar Oct. 4 (Julian) is followed by Oct. 15 (Gregorian).  This
    // algorithm will interpret such a date using the Julian calendar,
    // yielding Oct. 20, 1582 (Gregorian).
    int year_field = packed_date >> 9;
    boolean isGregorian = year_field >= gregorianCutoverYear;
    long julianDay = calculateJulianDay(isGregorian, year_field);
    long millis = julianDayToMillis(julianDay);

    // The following check handles portions of the cutover year BEFORE the
    // cutover itself happens. The check for the julianDate number is for a
    // rare case; it's a hardcoded number, but it's efficient.  The given
    // Julian day number corresponds to Dec 3, 292269055 BC, which
    // corresponds to millis near Long.MIN_VALUE.  The need for the check
    // arises because for extremely negative Julian day numbers, the millis
    // actually overflow to be positive values. Without the check, the
    // initial date is interpreted with the Gregorian calendar, even when
    // the cutover doesn't warrant it.
    if (isGregorian != (millis >= gregorianCutover) &&
        julianDay != -106749550580L) { // See above
      julianDay = calculateJulianDay(!isGregorian, year_field);
      millis = julianDayToMillis(julianDay);
    }

    // Do the time portion of the conversion.

    int millisInDay = 0;

    // Hours
    // Don't normalize here; let overflow bump into the next period.
    // This is consistent with how we handle other fields.
    millisInDay += (packed_time >> 22) & 31;

    millisInDay *= 60;
    millisInDay += (packed_time >> 16) & 63; // now have minutes
    millisInDay *= 60;
    millisInDay += (packed_time >> 10) & 63; // now have seconds
    millisInDay *= 1000;
    millisInDay += packed_time & 1023; // now have millis

    // Compute the time zone offset and DST offset.  There are two potential
    // ambiguities here.  We'll assume a 2:00 am (wall time) switchover time
    // for discussion purposes here.
    // 1. The transition into DST.  Here, a designated time of 2:00 am - 2:59 am
    //    can be in standard or in DST depending.  However, 2:00 am is an invalid
    //    representation (the representation jumps from 1:59:59 am Std to 3:00:00 am DST).
    //    We assume standard time.
    // 2. The transition out of DST.  Here, a designated time of 1:00 am - 1:59 am
    //    can be in standard or DST.  Both are valid representations (the rep
    //    jumps from 1:59:59 DST to 1:00:00 Std).
    //    Again, we assume standard time.
    // We use the TimeZone object to get the zone offset
    int zoneOffset = zone.getRawOffset();

    // Now add date and millisInDay together, to make millis contain local wall
    // millis, with no zone or DST adjustments
    millis += millisInDay;

    dstOffset = 0;
    /* Normalize the millisInDay to 0..ONE_DAY-1.  If the millis is out
     * of range, then we must call timeToFields() to recompute our
     * fields. */
    int[] normalizedMillisInDay = new int[1];
    floorDivide(millis, (int)ONE_DAY, normalizedMillisInDay);

    // We need to have the month, the day, and the day of the week.
    // Calling timeToFields will compute the MONTH and DATE fields.
    //
    // It's tempting to try to use DAY_OF_WEEK here, if it
    // is set, but we CAN'T.  Even if it's set, it might have
    // been set wrong by the user.  We should rely only on
    // the Julian day number, which has been computed correctly
    // using the disambiguation algorithm above. [LIU]
    int dow = julianDayToDayOfWeek(julianDay);

    // It's tempting to try to use DAY_OF_WEEK here, if it
    // is set, but we CAN'T.  Even if it's set, it might have
    // been set wrong by the user.  We should rely only on
    // the Julian day number, which has been computed correctly
    // using the disambiguation algorithm above. [LIU]
    dstOffset = zone.getOffset(1,
                               packed_date >> 9,
                               (packed_date >> 5) & 15,
                               packed_date & 31,
                               dow,
                               normalizedMillisInDay[0]) -
      zoneOffset;
    dstSet = true;
    // Note: Because we pass in wall millisInDay, rather than
    // standard millisInDay, we interpret "1:00 am" on the day
    // of cessation of DST as "1:00 am Std" (assuming the time
    // of cessation is 2:00 am).

    // Store our final computed GMT time, with timezone adjustments.
    time = millis - zoneOffset - dstOffset;
  
public booleanequals(java.lang.Object obj)
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.

    if (this == obj)
      return true;
    if (!(obj instanceof Calendar))
      return false;

    Calendar that = (Calendar)obj;

    return getTimeInMillis() == that.getTimeInMillis() && zone.equals(that.zone);
  
private static final longfloorDivide(long numerator, long denominator)
Divide two long integers, returning the floor of the quotient.

Unlike the built-in division, this is mathematically well-behaved. E.g., -1/4 => 0 but floorDivide(-1,4) => -1.

param
numerator the numerator
param
denominator a divisor which must be > 0
return
the floor of the quotient.

    // We do this computation in order to handle
    // a numerator of Long.MIN_VALUE correctly
    return (numerator >= 0) ?
      numerator / denominator :
      ((numerator + 1) / denominator) - 1;
  
private static final intfloorDivide(int numerator, int denominator)
Divide two integers, returning the floor of the quotient.

Unlike the built-in division, this is mathematically well-behaved. E.g., -1/4 => 0 but floorDivide(-1,4) => -1.

param
numerator the numerator
param
denominator a divisor which must be > 0
return
the floor of the quotient.

    // We do this computation in order to handle
    // a numerator of Integer.MIN_VALUE correctly
    return (numerator >= 0) ?
      numerator / denominator :
      ((numerator + 1) / denominator) - 1;
  
private static final intfloorDivide(int numerator, int denominator, int[] remainder)
Divide two integers, returning the floor of the quotient, and the modulus remainder.

Unlike the built-in division, this is mathematically well-behaved. E.g., -1/4 => 0 and -1%4 => -1, but floorDivide(-1,4) => -1 with remainder[0] => 3.

param
numerator the numerator
param
denominator a divisor which must be > 0
param
remainder an array of at least one element in which the value numerator mod denominator is returned. Unlike numerator % denominator, this will always be non-negative.
return
the floor of the quotient.

    if (numerator >= 0) {
      remainder[0] = numerator % denominator;
      return numerator / denominator;
    }
    int quotient = ((numerator + 1) / denominator) - 1;
    remainder[0] = numerator - (quotient * denominator);
    return quotient;
  
private static final intfloorDivide(long numerator, int denominator, int[] remainder)
Divide two integers, returning the floor of the quotient, and the modulus remainder.

Unlike the built-in division, this is mathematically well-behaved. E.g., -1/4 => 0 and -1%4 => -1, but floorDivide(-1,4) => -1 with remainder[0] => 3.

param
numerator the numerator
param
denominator a divisor which must be > 0
param
remainder an array of at least one element in which the value numerator mod denominator is returned. Unlike numerator % denominator, this will always be non-negative.
return
the floor of the quotient.

    if (numerator >= 0) {
      remainder[0] = (int)(numerator % denominator);
      return (int)(numerator / denominator);
    }
    int quotient = (int)(((numerator + 1) / denominator) - 1);
    remainder[0] = (int)(numerator - (quotient * denominator));
    return quotient;
  
public final intget(int field)
Gets the value for a given time field.

param
field the given time field (either YEAR, MONTH, DATE, DAY_OF_WEEK, HOUR_OF_DAY, HOUR, AM_PM, MINUTE, SECOND, or MILLISECOND
return
the value for the given time field.
exception
ArrayIndexOutOfBoundsException if the parameter is not one of the above.

    switch (field) {
    case YEAR:          return packed_date >> 9;
    case MONTH:         return (packed_date >> 5) & 15;
    case DATE:          return packed_date & 31;
    case DAY_OF_WEEK: {
      if (day_field == 0) {
        getTimeInMillis();
        calculateFields();
      }
      return day_field;
    }
    case HOUR_OF_DAY:   return packed_time >> 22;
    case HOUR: {
      int hr = (packed_time >> 22) % 12;
      return hr == 0? 12 : hr;
    }
    case AM_PM:         return (packed_time >> 22) < 12? AM: PM;
    case MINUTE:        return (packed_time >> 16) & 63;
    case SECOND:        return (packed_time >> 10) & 63;
    case MILLISECOND:   return packed_time & 1023;
    }
    throw new ArrayIndexOutOfBoundsException();
  
public static synchronized java.util.CalendargetInstance()
Gets a calendar using the default time zone and default locale.

return
a Calendar.

    if (platform == null) {
      /* Setup the platform name */
      platform = "j2me";

      /* See if there is an alternate protocol class root */
      classRoot = System.getProperty("microedition.implpath");
      if (classRoot == null) {
        classRoot = "com.sun.cldc";
      }
    }

    try {
      /* Using the platform and protocol names lookup a class to implement the connection */
      Class clazz = Class.forName(classRoot+".util."+platform+".CalendarImpl");

      /* Construct a new instance */
      return (Calendar)clazz.newInstance();
    }
    catch (Exception x) {}

    return null;
  
public static synchronized java.util.CalendargetInstance(java.util.TimeZone zone)
Gets a calendar using the specified time zone and default locale.

param
zone the time zone to use
return
a Calendar.

    Calendar cal = getInstance();
    cal.setTimeZone(zone);
    return cal;
  
public final java.util.DategetTime()
Gets this Calendar's current time.

return
the current time.
see
#setTime

    if (date == null)
      return date = new Date( getTimeInMillis() );
    else {
      synchronized (date) {
        date.setTime( getTimeInMillis() );
        return date;
      }
    }
  
protected longgetTimeInMillis()
Gets this Calendar's current time as a long expressed in milliseconds after January 1, 1970, 0:00:00 GMT (the epoch).

return
the current time as UTC milliseconds from the epoch.
see
#setTimeInMillis

    if (!millisSet) {
      calculateTime();
      millisSet = true;
    }
    return time;
  
public java.util.TimeZonegetTimeZone()
Gets the time zone.

return
the time zone object associated with this calendar.
see
#setTimeZone

    return zone;
  
private static final intjulianDayToDayOfWeek(long julian)

    // If julian is negative, then julian%7 will be negative, so we adjust
    // accordingly.  We add 1 because Julian day 0 is Monday.
    int dayOfWeek = (int)((julian + 1) % 7);
    return dayOfWeek + ((dayOfWeek < 0) ? (7 + SUNDAY) : SUNDAY);
  
private static final longjulianDayToMillis(long julian)
Converts Julian day to time as milliseconds.

param
julian the given Julian day number.
return
time as milliseconds.

    return (julian - EPOCH_JULIAN_DAY) * ONE_DAY;
  
private static final longmillisToJulianDay(long millis)
Converts time as milliseconds to Julian day.

param
millis the given milliseconds.
return
the Julian day number.

    return EPOCH_JULIAN_DAY + floorDivide(millis, ONE_DAY);
  
public final voidset(int field, int value)
Sets the time field with the given value.

param
field the given time field. Note that the DAY_OF_WEEK field cannot be set.
param
value the value to be set for the given time field.
exception
ArrayIndexOutOfBoundsException if an illegal field parameter is received.

    millisSet = false;
    day_field = 0;
    switch (field) {
    case YEAR: // 16383 = (2 to the power 14) - 1
      packed_date = (packed_date & 511) | (value << 9);
      break;
    case MONTH:
      packed_date = (packed_date & (~(15<<5))) | ((value & 15) << 5);
      break;
    case DATE:
      packed_date = (packed_date & (~31)) | (value & 31);
      break;
    case HOUR_OF_DAY:
      value = value % 24;
      packed_time = (packed_time & 4194303) | (value << 22);
      hour_12hr = am_pm_12hr = -1;
      break;
    case HOUR: {
      if (value > 12)
        value = 12;
      if (am_pm_12hr != -1) {
        if (am_pm_12hr == PM) {
          if (value != 12)
            value += 12;
        }
        else if (value == 12)
          value = 0;
        hour_12hr = am_pm_12hr = -1;
      }
      else
        hour_12hr = value;
      packed_time = (packed_time & 4194303) | (value << 22);
      break;
    }
    case AM_PM: {
      if (hour_12hr != -1) {
        if (value == PM) {
          if (hour_12hr != 12)
            hour_12hr += 12;
        }
        else if (hour_12hr == 12)
          hour_12hr = 0;
        packed_time = (packed_time & 4194303) | (hour_12hr << 22);
        hour_12hr = am_pm_12hr = -1;
      }
      else
        am_pm_12hr = value;
      break;
    }
    case MINUTE:
      packed_time = (packed_time & (~(63<<16))) | ((value & 63) << 16);
      break;
    case SECOND:
      packed_time = (packed_time & (~(63<<10))) | ((value & 63) << 10);
      break;
    case MILLISECOND:
      packed_time = (packed_time & (~1023)) | (value & 1023);
      break;
    default: throw new ArrayIndexOutOfBoundsException();
    }
    dstSet = false;
  
public final voidsetTime(java.util.Date date)
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 get().

param
date the given Date.
see
#getTime

    setTimeInMillis( date.getTime() );
  
protected voidsetTimeInMillis(long millis)
Sets this Calendar's current time from the given long value.

param
millis the new time in UTC milliseconds from the epoch.
see
#getTimeInMillis

    millisSet = true;
    day_field = 0;
    time = millis;
    calculateFields();
  
public voidsetTimeZone(java.util.TimeZone value)
Sets the time zone with the given time zone value.

param
value the given time zone.
see
#getTimeZone

    zone = value;
    getTimeInMillis();
    calculateFields();
  
private final voidtimeToFields(long theTime)
Convert the time as milliseconds to the date fields. Millis must be given as local wall millis to get the correct local day. For example, if it is 11:30 pm Standard, and DST is in effect, the correct DST millis must be passed in to get the right date.

Fields that are completed by this method: YEAR, MONTH, DATE, DAY_OF_WEEK.

param
theTime the time in wall millis (either Standard or DST), whichever is in effect
param
quick if true, only compute the YEAR, MONTH, DATE, and DAY_OF_WEEK.

    int dayOfYear, weekCount, year_field;
    boolean isLeap;

    // Compute the year, month, and day of month from the given millis
    if (theTime >= gregorianCutover) {
      // The Gregorian epoch day is zero for Monday January 1, year 1.
      long gregorianEpochDay = millisToJulianDay(theTime) - JAN_1_1_JULIAN_DAY;
      // Here we convert from the day number to the multiple radix
      // representation.  We use 400-year, 100-year, and 4-year cycles.
      // For example, the 4-year cycle has 4 years + 1 leap day; giving
      // 1461 == 365*4 + 1 days.
      int[] rem = new int[1];
      int n400 = floorDivide(gregorianEpochDay, 146097, rem); // 400-year cycle length
      int n100 = floorDivide(rem[0], 36524, rem); // 100-year cycle length
      int n4 = floorDivide(rem[0], 1461, rem); // 4-year cycle length
      int n1 = floorDivide(rem[0], 365, rem);
      year_field = 400*n400 + 100*n100 + 4*n4 + n1;
      dayOfYear = rem[0]; // zero-based day of year
      if (n100 == 4 || n1 == 4) dayOfYear = 365; // Dec 31 at end of 4- or 400-yr cycle
      else ++year_field;

      isLeap = ((year_field&0x3) == 0) && // equiv. to (year_field%4 == 0)
        (year_field%100 != 0 || year_field%400 == 0);

      // Gregorian day zero is a Monday
      day_field = (int)((gregorianEpochDay+1) % 7);
    }
    else {
      // The Julian epoch day (not the same as Julian Day)
      // is zero on Saturday December 30, 0 (Gregorian).
      long julianEpochDay = millisToJulianDay(theTime) - (JAN_1_1_JULIAN_DAY - 2);
      year_field = (int) floorDivide(4*julianEpochDay + 1464, 1461);

      // Compute the Julian calendar day number for January 1, year
      long january1 = 365*(year_field-1) + floorDivide(year_field-1, 4);
      dayOfYear = (int)(julianEpochDay - january1); // 0-based

      // Julian leap years occurred historically every 4 years starting
      // with 8 AD.  Before 8 AD the spacing is irregular; every 3 years
      // from 45 BC to 9 BC, and then none until 8 AD.  However, we don't
      // implement this historical detail; instead, we implement the
      // computationally cleaner proleptic calendar, which assumes
      // consistent 4-year cycles throughout time.
      isLeap = ((year_field&0x3) == 0); // equiv. to (year_field%4 == 0)

      // Julian calendar day zero is a Saturday
      day_field = (int)((julianEpochDay-1) % 7);
    }

    // Common Julian/Gregorian calculation
    int correction = 0;
    int march1 = isLeap ? 60 : 59; // zero-based DOY for March 1
    if (dayOfYear >= march1) correction = isLeap ? 1 : 2;
    int month_field = (12 * (dayOfYear + correction) + 6) / 367; // zero-based month
    int date_field = dayOfYear -
      (isLeap ? LEAP_NUM_DAYS[month_field] : NUM_DAYS[month_field]) + 1; // one-based DOM

    // Normalize day of week
    day_field += (day_field < 0) ? (SUNDAY+7) : SUNDAY;

    month_field += JANUARY; // 0-based

    packed_date =  year_field << 9;
    packed_date |= (month_field & 15) << 5;
    packed_date |= date_field & 31;