/*
 *******************************************************************************
 * Copyright (C) 1996-2000, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/util/Attic/IBMCalendar.java,v $ 
 * $Date: 2000/03/10 04:17:58 $ 
 * $Revision: 1.5 $
 *
 *****************************************************************************************
 */
package com.ibm.util;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.TimeZone;
import java.text.MessageFormat;
import java.text.DateFormat;
import com.ibm.text.DateFormatSymbols;
import com.ibm.text.SimpleDateFormat;


/**
 * Calendar utility class.
 *
 * The API methods on this class fall into several categories:
 * <ul>
 *  <li>Static methods for retrieving {@link java.text.DateFormat} and
 *      {@link java.text.DateFormatSymbols} objects that match a particular
 *      subclass of <code>Calendar</code>.
 *
 *  <li>Methods that were added to {@link java.util.Calendar Calendar} in JDK 1.2 or that
 *      we hope to add in a later release.
 *
 *  <li>Methods that make <code>Calendar</code> easier to subclass.  This includes
 *      default implementations for methods declared abstract on Calendar,
 *      so that subclasses are not forced to implement them.  In addition,
 *      there are several new utility methods that make it easier for
 *      subclassers to implement methods such as roll, add, computeTime,
 *      and computeFields.
 *  </ul>
 * <p>
 * <b>Note:</b> You should always use {@link #roll roll} and {@link #add add} rather
 * than attempting to perform arithmetic operations directly on the fields
 * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
 * to have fields with non-linear behavior, for example missing months
 * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
 * methods will take this into account, while simple arithmetic manipulations
 * may give invalid results.
 *  <p>
 *  <b>Subclassing</b>
 *  <br>
 *  It is possible to create subclasses of IBMCalendar that interpret
 *  dates according to other calendar systems that are not yet supported
 *  by Sun or IBM.  In order to do so, you must do the following:
 *  <ul>
 *  <li>Override {@link #getMinimum getMinimum},
 *      {@link #getGreatestMinimum getGreatestMinimum},
 *      {@link #getMaximum getMaximum}, and 
 *      {@link #getLeastMaximum getLeastMaximum} to return
 *      appropriate values for the new calendar system.
 *
 *  <li>If there are any fields whose minimum or maximum value can vary
 *      depending on the actual date set in the calendar (e.g. the number
 *      of days in a month
 *      varies depending on the month and/or year), you must override
 *      {@link #getActualMaximum getActualMaximum} and/or
 *      {@link #getActualMinimum getActualMinimum}
 *      to take this into account.
 *
 *  <li>Override {@link #computeTime computeTime} and {@link #computeFields computeFields}
 *      to perform the conversion from field values to milliseconds and
 *      vice-versa.  These two methods are the real heart of any subclass
 *      and are typically the ones that require the most work.  The protected
 *      utility method {@link #weekNumber weekNumber} is often helpful when implementing
 *      these two methods.
 *
 *  <li>If there are any fields whose ranges are not always continuous, you
 *      must override {@link #roll roll} and {@link #add add} to take this
 *      into account.  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.
 *  </ul>
 *  See the individual descriptions of the above methods for more information
 *  on their implications for subclassing.
 *
 * @author Laura Werner
 */
public abstract class IBMCalendar extends java.util.Calendar {

    private static String copyright = "Copyright \u00a9 1997-1998 IBM Corp. All Rights Reserved.";

    protected IBMCalendar(TimeZone zone, Locale aLocale) {
        super(zone, aLocale);
    }
    
    /**
     * Compare this object to another {@link Calendar} or to a {@link Date}.
     * <p>
     * @param when  the {@link Calendar} or {@link Date} object to
     *              be compared against.
     *
     * @return true if this object's absolute time is before that
     *              represented by <code>when</code>, false otherwise.
     *
     * @throws IllegalArgumentException if <code>when</code> is null or is
     *          not a <code>Calendar</code> or <code>Date</code>.
     */
    public boolean before(Object when)
    {
        if (this == when) {
            return false;
        }
        else if (when instanceof Calendar) {
            return getTime().before(((Calendar)when).getTime());
        }
        else if (when instanceof Date) {
            return getTime().before((Date)when);
        } else {
            throw new IllegalArgumentException("argument must be a non-null Calendar or Date");
        }
    }

    /**
     * Compare this object to another {@link Calendar} or to a {@link Date}.
     * <p>
     * @param when  the {@link Calendar} or {@link Date} object to be compared against.
     *
     * @return true if this object's absolute time is after that
     *              represented by <code>when</code>, false otherwise.
     *
     * @throws IllegalArgumentException if <code>when</code> is null or is
     *          not a <code>Calendar</code> or <code>Date</code>.
     */
    public boolean after(Object when)
    {
        if (this == when) {
            return false;
        }
        else if (when instanceof Calendar) {
            return getTime().after(((Calendar)when).getTime());
        }
        else if (when instanceof Date) {
            return getTime().after((Date)when);
        } else {
            throw new IllegalArgumentException("argument must be a non-null Calendar or Date");
        }            
    }

    /**
     * Compares this object to another {@link Calendar} and returns <code>true</code>
     * if they are the same.  Unlike {@link #before before} and {@link #after after},
     * this method
     * compares all of the properties of the calendar rather than comparing only
     * its time in milliseconds.
     * <p>
     * @param obj the {@link Calendar} object to compair against.
     */
    public boolean equals(Object obj)
    {
        if (this == obj) return true;
        if (obj == null) return false;
        if (this.getClass() != obj.getClass()) return false;

        Calendar that = (Calendar) obj;

        return
            getTimeInMillis() == that.getTime().getTime() &&
            isLenient() == that.isLenient() &&
            getFirstDayOfWeek() == that.getFirstDayOfWeek() &&
            getMinimalDaysInFirstWeek() == that.getMinimalDaysInFirstWeek() &&
            getTimeZone().equals(that.getTimeZone());
    }
    
    /**
     * Return the maximum value that this field could have, given the current date.
     * For example, with the Gregorian date "Feb 3, 1997" and the
     * {@link #DAY_OF_MONTH DAY_OF_MONTH} field, the actual
     * maximum is 28; for "Feb 3, 1996" it is 29.
     * <p>
     * <b>Note:</b>This method has been added to {@link java.util.Calendar} in JDK 1.2; it
     * is provided here so that 1.1 clients can take advantage of it as well.
     * <p>
     * <b>Subclassing:</b><br>
     * For the {@link #WEEK_OF_YEAR WEEK_OF_YEAR}, {@link #WEEK_OF_MONTH WEEK_OF_MONTH},
     * and {@link #DAY_OF_WEEK_IN_MONTH DAY_OF_WEEK_IN_MONTH} fields, this method
     * calls <code>getActualMaximum(DAY_OF_YEAR)</code> or
     * <code>getActualMaximum(DAY_OF_MONTH)</code> and then uses that value in a call to
     * {@link #weekNumber weekNumber} to determine the result.  However, for all other
     * fields it iterates between the values returned by
     * {@link #getLeastMaximum getLeastMaximum} and {@link #getMaximum getMaximum}
     * to determine the actual maximum value for the field.
     * <p>
     * There is almost always a more efficient way to accomplish this,
     * and thus you should almost always override this method in your subclass.
     * For most fields, you can simply return the same thing as
     * {@link #getMaximum getMaximum}.  If your class has an internal method that
     * calculates the number of days in a month or year, your getActualMaximum override
     * can use those functions in its implementation.  For fields that you cannot
     * handle efficiently, you can simply call <code>super.getActualMaximum(field)</code>.
     * <p>
     * @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
     */
    public int getActualMaximum(int field) {
        int result;
        
        switch (field) {
            //
            // For the week-related fields, there's a shortcut.  Since we know the
            // current DAY_OF_WEEK and DAY_OF_MONTH or DAY_OF_YEAR, we can compute
            // the the maximum for this field in terms of the maximum DAY_OF_*,
            // on the theory that's easier to determine.
            //
            case WEEK_OF_YEAR:
                result = weekNumber(getActualMaximum(DAY_OF_YEAR),
                                    get(DAY_OF_YEAR), get(DAY_OF_WEEK));
                break;
                
            case WEEK_OF_MONTH:
                result = weekNumber(getActualMaximum(DAY_OF_MONTH),
                                    get(DAY_OF_MONTH), get(DAY_OF_WEEK));
                break;
          
            case DAY_OF_WEEK_IN_MONTH:
                int weekLength = getMaximum(DAY_OF_WEEK) - getMinimum(DAY_OF_WEEK) + 1;
                result = (getActualMaximum(DAY_OF_MONTH) - 1) / weekLength + 1;
                break;
            
            // For all other fields, do it the hard way....
            default:
                result = getActualHelper(field, getLeastMaximum(field), getMaximum(field));
                break;
        }
        return result;
    }
    
    /**
     * Return 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.
     * <p>
     * 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 <code>getActualMinimum(WEEK_OF_MONTH)</code> will return 1.  However,
     * if the first of the month is a Thursday, Friday, or Saturday, there are
     * <em>not</em> four days in that week, so it is week number 0, and 
     * <code>getActualMinimum(WEEK_OF_MONTH)</code> will return 0.
     * <p>
     * <b>Note:</b>This method has been added to java.util.Calendar in JDK 1.2; it
     * is provided here so that 1.1 clients can take advantage of it as well.
     * <p>
     * <b>Subclassing:</b><br>
     * For the {@link #WEEK_OF_YEAR WEEK_OF_YEAR}, {@link #WEEK_OF_MONTH WEEK_OF_MONTH},
     * and {@link #DAY_OF_WEEK_IN_MONTH DAY_OF_WEEK_IN_MONTH} fields, this method
     * calls <code>getActualMinimum(DAY_OF_YEAR)</code> or
     * <code>getActualMinimum(DAY_OF_MONTH)</code> and then uses that value in a call to
     * {@link #weekNumber weekNumber} to determine the result.  However, for all other
     * fields it iterates between the values returned by
     * {@link #getMinimum getMinimum} and {@link #getGreatestMinimum getGreatestMinimum}
     * to determine the actual maximum value for the field.
     * <p>
     * There is almost always a more efficient way to accomplish this,
     * and thus you should almost always override this method in your subclass.
     * For most fields, you can simply return the same thing as
     * {@link #getMinimum getMinimum}.  For fields that you cannot
     * handle efficiently, you can simply call <code>super.getActualMaximum(field)</code>.
     * <p>
     * @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
     */
    public int getActualMinimum(int field) {
        int result;
        
        switch (field) {
            //
            // For the week-related fields, there's a shortcut.  Since we know the
            // current DAY_OF_WEEK and DAY_OF_MONTH or DAY_OF_YEAR, we can compute
            // the the maximum for this field in terms of the maximum DAY_OF_*,
            // on the theory that's easier to determine.
            //
            case WEEK_OF_YEAR:
                result = weekNumber(getActualMinimum(DAY_OF_YEAR),
                                    get(DAY_OF_YEAR), get(DAY_OF_WEEK));
                break;
                
            case WEEK_OF_MONTH:
                result = weekNumber(getActualMinimum(DAY_OF_MONTH),
                                    get(DAY_OF_MONTH), get(DAY_OF_WEEK));
                break;
          
            case DAY_OF_WEEK_IN_MONTH:
                int weekLength = getMaximum(DAY_OF_WEEK) - getMinimum(DAY_OF_WEEK) + 1;
                result = (getActualMinimum(DAY_OF_MONTH) - 1) / weekLength + 1;
                break;
            
            // For all other fields, do it the hard way....
            default:
                result = getActualHelper(field, getGreatestMinimum(field), getMinimum(field));
                break;
        }
        return result;
    }

    private int getActualHelper(int field, int startValue, int endValue)
    {
        int result = startValue;
        
        if (startValue == endValue) {
            // if we know that the maximum value is always the same, just return it
            result = startValue;
        } 
        else if (startValue != endValue) {
            // clone the calendar so we don't mess with the real one, and set it to
            // accept anything for the field values
            Calendar work = (Calendar)this.clone();
            work.setLenient(true);

            //
            // now try each value from the start to the end one by one until
            // we get a value that normalizes to another value.  The last value that
            // normalizes to itself is the actual maximum for the current date
            //
            int delta = (endValue > startValue) ? 1 : -1;
            
            startValue += delta;
            result = startValue;

            while (result != endValue) {
                work.set(field, startValue);
                if (work.get(field) != startValue) {
                    break;
                } else {
                    result = startValue;
                    startValue += delta;
                }
            }
        }
        return result;
    }
    
    /**
     * 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:
     * <p>
     * <code>roll({@link #DATE}, true)</code>
     * <p>
     * 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}).
     * <p>
     * When rolling on certain fields, the values of other fields may conflict and
     * need to be changed.  For example, when rolling the <code>MONTH</code> field
     * for the Gregorian date 1/31/96 upward, the <code>DAY_OF_MONTH</code> field
     * must be adjusted so that the result is 2/29/96 rather than the invalid
     * 2/31/96.
     * <p>
     * <b>Note:</b> Calling <tt>roll(field, true)</tt> N times is <em>not</em>
     * necessarily equivalent to calling <tt>roll(field, N)</tt>.  For example,
     * imagine that you start with the date Gregorian date January 31, 1995.  If you call
     * <tt>roll(Calendar.MONTH, 2)</tt>, the result will be March 31, 1995.
     * But if you call <tt>roll(Calendar.MONTH, true)</tt>, the result will be
     * February 28, 1995.  Calling it one more time will give March 28, 1995, which
     * is usually not the desired result.
     * <p>
     * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
     * than attempting to perform arithmetic operations directly on the fields
     * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
     * to have fields with non-linear behavior, for example missing months
     * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
     * methods will take this into account, while simple arithmetic manipulations
     * may give invalid results.
     * <p>
     * @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 <code>true</code> if rolling up,
     *              <code>false</code> 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
     */
    public final void roll(int field, boolean up)
    {
        roll(field, up ? +1 : -1);
    }

    /**
     * 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
     * <code>roll(Calendar.DATE, 3)</code>.  If the
     * field is rolled past its maximum allowable value, it will "wrap" back
     * to its minimum and continue rolling.  
     * For example, calling <code>roll(Calendar.DATE, 10)</code>
     * on a Gregorian calendar set to 4/25/96 will result in the date 4/5/96.
     * <p>
     * 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.
     * <p>
     * The <code>IBMCalendar</code> 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 <code>roll</code>.
     * <p>
     * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
     * than attempting to perform arithmetic operations directly on the fields
     * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
     * to have fields with non-linear behavior, for example missing months
     * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
     * methods will take this into account, while simple arithmetic manipulations
     * may give invalid results.
     * <p>
     * <b>Subclassing:</b><br>
     * This implementation of <code>roll</code> 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.
     * <p>
     * Subclasses that have fields for which the assumption of continuity breaks
     * down must overide <code>roll</code> 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.
     * <p>
     * @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
     */
    public void roll(int field, int amount)
    {
        if (amount == 0) return; // Nothing to do

        complete();

        switch (field) {
        case DAY_OF_MONTH:
        case AM_PM:
        case MINUTE:
        case SECOND:
        case MILLISECOND:
            // These are the standard roll instructions.  These work for all
            // simple cases, that is, cases in which the limits are fixed, such
            // as the hour, the day of the month, and the era.
            {
                int min = getActualMinimum(field);
                int max = getActualMaximum(field);
                int gap = max - min + 1;

                int value = internalGet(field) + amount;
                value = (value - min) % gap;
                if (value < 0) value += gap;
                value += min;

                set(field, value);
                return;
            }

        case HOUR:
        case HOUR_OF_DAY:
            // Rolling the hour is difficult on the ONSET and CEASE days of
            // daylight savings.  For example, if the change occurs at
            // 2 AM, we have the following progression:
            // ONSET: 12 Std -> 1 Std -> 3 Dst -> 4 Dst
            // CEASE: 12 Dst -> 1 Dst -> 1 Std -> 2 Std
            // To get around this problem we don't use fields; we manipulate
            // the time in millis directly.
            {
                // Assume min == 0 in calculations below
                Date start = getTime();
                int oldHour = internalGet(field);
                int max = getActualMaximum(field);
                int newHour = (oldHour + amount) % (max + 1);
                if (newHour < 0) {
                    newHour += max + 1;
                }
                setTime(new Date(start.getTime() + HOUR_MS * (newHour - oldHour)));
                return;
            }

        case MONTH:
            // Rolling the month involves both pinning the final value
            // and adjusting the DAY_OF_MONTH if necessary.  We only adjust the
            // DAY_OF_MONTH if, after updating the MONTH field, it is illegal.
            // E.g., <jan31>.roll(MONTH, 1) -> <feb28> or <feb29>.
            {
                int max = getActualMaximum(MONTH);
                int mon = (internalGet(MONTH) + amount) % (max+1);
                
                if (mon < 0) mon += (max + 1);
                set(MONTH, mon);
                
                // Keep the day of month in range.  We don't want to spill over
                // into the next month; e.g., we don't want jan31 + 1 mo -> feb31 ->
                // mar3.
                pinField(DAY_OF_MONTH);
                return;
            }

        case YEAR:
            // Rolling the year can involve pinning the DAY_OF_MONTH.
            set(YEAR, internalGet(YEAR) + amount);
            pinField(MONTH);
            pinField(DAY_OF_MONTH);
            return;

        case WEEK_OF_MONTH:
            {
                // This is tricky, because during the roll we may have to shift
                // to a different day of the week.  For example:

                //    s  m  t  w  r  f  s
                //          1  2  3  4  5
                //    6  7  8  9 10 11 12

                // When rolling from the 6th or 7th back one week, we go to the
                // 1st (assuming that the first partial week counts).  The same
                // thing happens at the end of the month.

                // The other tricky thing is that we have to figure out whether
                // the first partial week actually counts or not, based on the
                // minimal first days in the week.  And we have to use the
                // correct first day of the week to delineate the week
                // boundaries.

                // Here's our algorithm.  First, we find the real boundaries of
                // the month.  Then we discard the first partial week if it
                // doesn't count in this locale.  Then we fill in the ends with
                // phantom days, so that the first partial week and the last
                // partial week are full weeks.  We then have a nice square
                // block of weeks.  We do the usual rolling within this block,
                // as is done elsewhere in this method.  If we wind up on one of
                // the phantom days that we added, we recognize this and pin to
                // the first or the last day of the month.  Easy, eh?

                // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
                // in this locale.  We have dow in 0..6.
                int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();
                if (dow < 0) dow += 7;

                // Find the day of the week (normalized for locale) for the first
                // of the month.
                int fdm = (dow - internalGet(DAY_OF_MONTH) + 1) % 7;
                if (fdm < 0) fdm += 7;

                // Get the first day of the first full week of the month,
                // including phantom days, if any.  Figure out if the first week
                // counts or not; if it counts, then fill in phantom days.  If
                // not, advance to the first real full week (skip the partial week).
                int start;
                if ((7 - fdm) < getMinimalDaysInFirstWeek())
                    start = 8 - fdm; // Skip the first partial week
                else
                    start = 1 - fdm; // This may be zero or negative

                // Get the day of the week (normalized for locale) for the last
                // day of the month.
                int monthLen = getActualMaximum(DAY_OF_MONTH);
                int ldm = (monthLen - internalGet(DAY_OF_MONTH) + dow) % 7;
                // We know monthLen >= DAY_OF_MONTH so we skip the += 7 step here.

                // Get the limit day for the blocked-off rectangular month; that
                // is, the day which is one past the last day of the month,
                // after the month has already been filled in with phantom days
                // to fill out the last week.  This day has a normalized DOW of 0.
                int limit = monthLen + 7 - ldm;

                // Now roll between start and (limit - 1).
                int gap = limit - start;
                int day_of_month = (internalGet(DAY_OF_MONTH) + amount*7 -
                                    start) % gap;
                if (day_of_month < 0) day_of_month += gap;
                day_of_month += start;

                // Finally, pin to the real start and end of the month.
                if (day_of_month < 1) day_of_month = 1;
                if (day_of_month > monthLen) day_of_month = monthLen;

                // Set the DAY_OF_MONTH.  We rely on the fact that this field
                // takes precedence over everything else (since all other fields
                // are also set at this point).  If this fact changes (if the
                // disambiguation algorithm changes) then we will have to unset
                // the appropriate fields here so that DAY_OF_MONTH is attended
                // to.
                set(DAY_OF_MONTH, day_of_month);
                return;
            }
        case WEEK_OF_YEAR:
            {
                // This follows the outline of WEEK_OF_MONTH, except it applies
                // to the whole year.  Please see the comment for WEEK_OF_MONTH
                // for general notes.

                // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
                // in this locale.  We have dow in 0..6.
                int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();
                if (dow < 0) dow += 7;

                // Find the day of the week (normalized for locale) for the first
                // of the year.
                int fdy = (dow - internalGet(DAY_OF_YEAR) + 1) % 7;
                if (fdy < 0) fdy += 7;

                // Get the first day of the first full week of the year,
                // including phantom days, if any.  Figure out if the first week
                // counts or not; if it counts, then fill in phantom days.  If
                // not, advance to the first real full week (skip the partial week).
                int start;
                if ((7 - fdy) < getMinimalDaysInFirstWeek())
                    start = 8 - fdy; // Skip the first partial week
                else
                    start = 1 - fdy; // This may be zero or negative

                // Get the day of the week (normalized for locale) for the last
                // day of the year.
                int yearLen = getActualMaximum(DAY_OF_YEAR);
                int ldy = (yearLen - internalGet(DAY_OF_YEAR) + dow) % 7;
                // We know yearLen >= DAY_OF_YEAR so we skip the += 7 step here.

                // Get the limit day for the blocked-off rectangular year; that
                // is, the day which is one past the last day of the year,
                // after the year has already been filled in with phantom days
                // to fill out the last week.  This day has a normalized DOW of 0.
                int limit = yearLen + 7 - ldy;

                // Now roll between start and (limit - 1).
                int gap = limit - start;
                int day_of_year = (internalGet(DAY_OF_YEAR) + amount*7 -
                                    start) % gap;
                if (day_of_year < 0) day_of_year += gap;
                day_of_year += start;

                // Finally, pin to the real start and end of the month.
                if (day_of_year < 1) day_of_year = 1;
                if (day_of_year > yearLen) day_of_year = yearLen;

                // Make sure that the year and day of year are attended to by
                // clearing other fields which would normally take precedence.
                // If the disambiguation algorithm is changed, this section will
                // have to be updated as well.
                set(DAY_OF_YEAR, day_of_year);
                clear(MONTH);
                return;
            }
        case DAY_OF_YEAR:
            {
                // Roll the day of year using millis.  Compute the millis for
                // the start of the year, and get the length of the year.
                long delta = amount * DAY_MS; // Scale up from days to millis
                long min2 = time - (internalGet(DAY_OF_YEAR) - 1) * DAY_MS;
                int yearLength = getActualMaximum(DAY_OF_YEAR);
                time = (time + delta - min2) % (yearLength*DAY_MS);
                if (time < 0) time += yearLength*DAY_MS;
                setTimeInMillis(time + min2);
                return;
            }
        case DAY_OF_WEEK:
            {
                // Roll the day of week using millis.  Compute the millis for
                // the start of the week, using the first day of week setting.
                // Restrict the millis to [start, start+7days).
                long delta = amount * DAY_MS; // Scale up from days to millis
                // Compute the number of days before the current day in this
                // week.  This will be a value 0..6.
                int leadDays = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();
                if (leadDays < 0) leadDays += 7;
                long min2 = time - leadDays * DAY_MS;
                time = (time + delta - min2) % WEEK_MS;
                if (time < 0) time += WEEK_MS;
                setTimeInMillis(time + min2);
                return;
            }
        case DAY_OF_WEEK_IN_MONTH:
            {
                // Roll the day of week in the month using millis.  Determine
                // the first day of the week in the month, and then the last,
                // and then roll within that range.
                long delta = amount * WEEK_MS; // Scale up from weeks to millis
                // Find the number of same days of the week before this one
                // in this month.
                int preWeeks = (internalGet(DAY_OF_MONTH) - 1) / 7;
                // Find the number of same days of the week after this one
                // in this month.
                int postWeeks = (getActualMaximum(DAY_OF_MONTH) -
                                 internalGet(DAY_OF_MONTH)) / 7;
                // From these compute the min and gap millis for rolling.
                long min2 = time - preWeeks * WEEK_MS;
                long gap2 = WEEK_MS * (preWeeks + postWeeks + 1); // Must add 1!
                // Roll within this range
                time = (time + delta - min2) % gap2;
                if (time < 0) time += gap2;
                setTimeInMillis(time + min2);
                return;
            }
        default:
            // Other fields cannot be rolled by this method
            throw new IllegalArgumentException("IBMCalendar.roll: field not supported");
        }
    }
    
    /**
     * 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
     * <code>add(Calendar.DATE, 3)</code>. 
     * <p>
     * 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.
     * <p>
     * The <code>IBMCalendar</code> 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 <code>add</code>.
     * <p>
     * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
     * than attempting to perform arithmetic operations directly on the fields
     * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
     * to have fields with non-linear behavior, for example missing months
     * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
     * methods will take this into account, while simple arithmetic manipulations
     * may give invalid results.
     * <p>
     * <b>Subclassing:</b><br>
     * This implementation of <code>add</code> 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.
     * <p>
     * Subclasses that have fields for which this assumption of continuity breaks
     * down must overide <code>add</code> 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.
     * <p>
     * @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)
     */
    public void add(int field, int amount)
    {
        if (amount == 0) return;   // Do nothing!

        long delta = amount;

        switch (field) {
        case YEAR:
            {
                int year = get(YEAR) + amount;
                set(YEAR, year);
                pinField(DAY_OF_MONTH);
                return;
            }
        
        case MONTH:
            // About the best we can do for a default implementation is
            // assume a constant number of months per year.  Subclasses
            // with a variable number of months will have to do this
            // one themselves
            {
                int month = this.get(MONTH) + amount;
                int year = get(YEAR);
                int length = getMaximum(MONTH) + 1;
                
                if (month >= 0) {
                    set(YEAR, year + month/length);
                    set(MONTH, month % length);
                } else {
                    set(YEAR, year + (month + 1)/length - 1);
                    month %= length;
                    if (month < 0) {
                        month += length;
                    }
                    set(MONTH, month);
                }
                pinField(DAY_OF_MONTH);
                return;
            }
            
        case WEEK_OF_YEAR:
        case WEEK_OF_MONTH:
        case DAY_OF_WEEK_IN_MONTH:
            delta *= WEEK_MS;
            break;

        case AM_PM:
            delta *= 12 * HOUR_MS;
            break;

        case DAY_OF_MONTH:
        case DAY_OF_YEAR:
        case DAY_OF_WEEK:
            delta *= DAY_MS;
            break;

        case HOUR_OF_DAY:
        case HOUR:
            delta *= HOUR_MS;
            break;

        case MINUTE:
            delta *= MINUTE_MS;
            break;

        case SECOND:
            delta *= SECOND_MS;
            break;

        case MILLISECOND:
            break;

        default:
            throw new IllegalArgumentException("IBMCalendar.add: field not supported");
        }
        setTimeInMillis(getTimeInMillis() + delta);
    }

    
    /**
     * Return the name of this calendar in the language of the given locale.
     */
    public String getDisplayName(Locale loc) {
        return this.getClass().getName();
    }
    
    //-------------------------------------------------------------------------
    // Public static interface for creating custon DateFormats for different
    // types of Calendars.
    //-------------------------------------------------------------------------
    
    /**
     * Create a {@link DateFormat} object that can be used to format dates in
     * the calendar system specified by <code>cal</code>.
     * <p>
     * <b>Note:</b> When this functionality is moved into the core JDK, this method
     * will probably be replaced by a new overload of {@link DateFormat#getInstance}.
     * <p>
     * @param cal   The calendar system for which a date format is desired.
     *
     * @param dateStyle The type of date format desired.  This can be
     *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
     *              etc.
     *
     * @param locale The locale for which the date format is desired.
     *
     * @see java.text.DateFormat#getDateInstance
     */
    static public DateFormat getDateFormat(Calendar cal, int dateStyle, Locale locale)
    {
        return getDateTimeFormat(cal, locale, dateStyle, -1);
    }
    
    /**
     * Create a {@link DateFormat} object that can be used to format times in
     * the calendar system specified by <code>cal</code>.
     * <p>
     * <b>Note:</b> When this functionality is moved into the core JDK, this method
     * will probably be replaced by a new overload of {@link DateFormat#getInstance}.
     * <p>
     * @param cal   The calendar system for which a time format is desired.
     *
     * @param timeStyle The type of time format desired.  This can be
     *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
     *              etc.
     *
     * @param locale The locale for which the time format is desired.
     *
     * @see java.text.DateFormat#getTimeInstance
     */
    static public DateFormat getTimeFormat(Calendar cal, int timeStyle, Locale locale)
    {
        return getDateTimeFormat(cal, locale, -1, timeStyle);
    }
    
    /**
     * Create a {@link DateFormat} object that can be used to format dates and times in
     * the calendar system specified by <code>cal</code>.
     * <p>
     * <b>Note:</b> When this functionality is moved into the core JDK, this method
     * will probably be replaced by a new overload of {@link DateFormat#getInstance}.
     * <p>
     * @param cal   The calendar system for which a date/time format is desired.
     *
     * @param dateStyle The type of date format desired.  This can be
     *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
     *              etc.
     *
     * @param timeStyle The type of time format desired.  This can be
     *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
     *              etc.
     *
     * @param locale The locale for which the date/time format is desired.
     *
     * @see java.text.DateFormat#getDateTimeInstance
     */
    static public DateFormat getDateTimeFormat(Calendar cal, int dateStyle,
                                        int timeStyle, Locale locale)
    {
        return getDateTimeFormat(cal, locale, dateStyle, timeStyle);
    }

    /**
     * Get the {@link DateFormatSymbols} object that should be used to format a
     * calendar system's dates in the given locale.
     * <p>
     * <b>Note:</b> When this functionality is moved into the core JDK, this method
     * will probably be replace by a new constructor on <tt>DateFormatSymbols</tt>.
     * <p>
     * <b>Subclassing:</b><br>
     * When creating a new Calendar subclass, you must create the
     * {@link ResourceBundle ResourceBundle}
     * containing its {@link DateFormatSymbols DateFormatSymbols} in a specific place.
     * The resource bundle name is based on the calendar's fully-specified
     * class name, with ".resources" inserted at the end of the package name
     * (just before the class name) and "Symbols" appended to the end.
     * For example, the bundle corresponding to "com.ibm.util.HebrewCalendar"
     * is "com.ibm.util.resources.HebrewCalendarSymbols".
     * <p>
     * Within the ResourceBundle, this method searches for five keys: 
     * <ul>
     * <li><b>DayNames</b> -
     *      An array of strings corresponding to each possible
     *      value of the <code>DAY_OF_WEEK</code> field.  Even though
     *      <code>DAY_OF_WEEK</code> starts with <code>SUNDAY</code> = 1,
     *      This array is 0-based; the name for Sunday goes in the
     *      first position, at index 0.  If this key is not found
     *      in the bundle, the day names are inherited from the
     *      default <code>DateFormatSymbols</code> for the requested locale.
     *
     * <li><b>DayAbbreviations</b> -
     *      An array of abbreviated day names corresponding
     *      to the values in the "DayNames" array.  If this key
     *      is not found in the resource bundle, the "DayNames"
     *      values are used instead.  If neither key is found,
     *      the day abbreviations are inherited from the default
     *      <code>DateFormatSymbols</code> for the locale.
     *
     * <li><b>MonthNames</b> -
     *      An array of strings corresponding to each possible
     *      value of the <code>MONTH</code> field.  If this key is not found
     *      in the bundle, the month names are inherited from the
     *      default <code>DateFormatSymbols</code> for the requested locale.
     *
     * <li><b>MonthAbbreviations</b> -
     *      An array of abbreviated day names corresponding
     *      to the values in the "MonthNames" array.  If this key
     *      is not found in the resource bundle, the "MonthNames"
     *      values are used instead.  If neither key is found,
     *      the day abbreviations are inherited from the default
     *      <code>DateFormatSymbols</code> for the locale.
     *
     * <li><b>Eras</b> -
     *      An array of strings corresponding to each possible
     *      value of the <code>ERA</code> field.  If this key is not found
     *      in the bundle, the era names are inherited from the
     *      default <code>DateFormatSymbols</code> for the requested locale.
     * </ul>
     * <p>
     * @param cal       The calendar system whose date format symbols are desired.
     * @param locale    The locale whose symbols are desired.
     *
     * @see java.text.DateFormatSymbols#DateFormatSymbols(java.util.Locale)
     */
    static public DateFormatSymbols getDateFormatSymbols(Calendar cal,
                                                         Locale locale)
    {
        ResourceBundle bundle = null;
        try {
            bundle = getDateFormatBundle(cal, locale);
        }
        catch (MissingResourceException e) {
            if (!(cal instanceof GregorianCalendar)) {
                // Ok for symbols to be missing for a Gregorian calendar, but
                // not for any other type.
                throw e;
            }
        }
        return getDateFormatSymbols(null, bundle, locale);
    }

    /**
     * Fetch a custom calendar's DateFormatSymbols out of the given resource
     * bundle.  Symbols that are not overridden are inherited from the
     * default DateFormatSymbols for the locale.
     * @see java.text.DateFormatSymbols#DateFormatSymbols
     */
    static protected DateFormatSymbols getDateFormatSymbols(DateFormatSymbols result,
                                                            ResourceBundle bundle,
                                                            Locale locale)
    {
        // Get the default symbols for the locale, since most calendars will only
        // need to override month names and will want everything else the same
        if (result == null) {
            result = new DateFormatSymbols(locale);
        }

        //
        // Fetch the day names from the resource bundle.  If they're not found,
        // it's ok; we'll just use the default ones.
        // Allow a null ResourceBundle just for the sake of completeness;
        // this is useful for calendars that don't have any overridden symbols
        //
        if (bundle != null) {
            try {
                String[] temp = bundle.getStringArray("DayNames");
                result.setWeekdays(temp);
                result.setShortWeekdays(temp);

                temp = bundle.getStringArray("DayAbbreviations");
                result.setShortWeekdays( temp );
            }
            catch (MissingResourceException e) {
            }

            try {
                String[] temp = bundle.getStringArray("MonthNames");
                result.setMonths( temp );
                result.setShortMonths( temp );

                temp = bundle.getStringArray("MonthAbbreviations");
                result.setShortMonths( temp );
            }
            catch (MissingResourceException e) {
            }

            try {
                String[] temp = bundle.getStringArray("Eras");
                result.setEras( temp );
            }
            catch (MissingResourceException e) {
            }
        }
        return result;
    }

    protected DateFormatSymbols getDateFormatSymbols(Locale locale) {
        return getDateFormatSymbols(null, getDateFormatBundle(this, locale), locale);
    }
    
    /**
     * Private utility method to retrive a date and/or time format
     * for the specified calendar and locale.  This method has knowledge of
     * (and is partly copied from) the corresponding code in SimpleDateFormat,
     * but it knows how to find the right resource bundle based on the calendar class.
     * <p>
     * @param cal       The calendar system whose date/time format is desired.
     *
     * @param timeStyle The type of time format desired.  This can be
     *                  <code>DateFormat.SHORT</code>, etc, or -1 if the time
     *                  of day should not be included in the format.
     *
     * @param dateStyle The type of date format desired.  This can be
     *                  <code>DateFormat.SHORT</code>, etc, or -1 if the date
     *                  should not be included in the format.
     *
     * @param loc       The locale for which the date/time format is desired.
     *
     * @see java.text.DateFormat#getDateTimeInstance
     */
    static private DateFormat getDateTimeFormat(Calendar cal, Locale loc,
                                            int dateStyle, int timeStyle)
    {
        if (cal instanceof IBMCalendar) {
            return ((IBMCalendar)cal).getDateTimeFormat(dateStyle,timeStyle,loc);
        } else {
            return formatHelper(cal, loc, dateStyle, timeStyle);
        }
    }
    
    protected DateFormat getDateTimeFormat(int dateStyle, int timeStyle, Locale loc) {
        return formatHelper(this, loc, dateStyle, timeStyle);
    }
    
    static private DateFormat formatHelper(Calendar cal, Locale loc,
                                            int dateStyle, int timeStyle)
    {
        // See if there are any custom resources for this calendar
        // If not, just use the default DateFormat
        DateFormat result = null;
        DateFormatSymbols symbols = null;

        ResourceBundle bundle = getDateFormatBundle(cal, loc);

        if (bundle != null) {
            if (cal instanceof IBMCalendar) {
                symbols = ((IBMCalendar)cal).getDateFormatSymbols(loc);
            } else {
                symbols = getDateFormatSymbols(null, bundle, loc);
            }
            
            try {
                String[] patterns = bundle.getStringArray("DateTimePatterns");

                String pattern = null;
                if ((timeStyle >= 0) && (dateStyle >= 0)) {
                    Object[] dateTimeArgs = { patterns[timeStyle],
                                             patterns[dateStyle + 4] };
                    pattern = MessageFormat.format(patterns[8], dateTimeArgs);
                }
                else if (timeStyle >= 0) {
                    pattern = patterns[timeStyle];
                }
                else if (dateStyle >= 0) {
                    pattern = patterns[dateStyle + 4];
                }
                else {
                    throw new IllegalArgumentException("No date or time style specified");
                }
                result = new SimpleDateFormat(pattern, symbols);
            } catch (MissingResourceException e) {
                // No custom patterns
                if (dateStyle == -1) {
	                result = SimpleDateFormat.getTimeInstance(timeStyle, loc);
	            } else if (timeStyle == -1) {
	                result = SimpleDateFormat.getDateInstance(dateStyle, loc);
	            } else {
	                result = SimpleDateFormat.getDateTimeInstance(dateStyle, timeStyle, loc);
	            }
                ((java.text.SimpleDateFormat)result).setDateFormatSymbols(oldStyleSymbols(symbols, loc));
            }
        } else {
            if (dateStyle == -1) {
	            result = SimpleDateFormat.getTimeInstance(timeStyle, loc);
	        } else if (timeStyle == -1) {
	            result = SimpleDateFormat.getDateInstance(dateStyle, loc);
	        } else {
	            result = SimpleDateFormat.getDateTimeInstance(dateStyle, timeStyle, loc);
	        }
        }
        result.setCalendar(cal);
        return result;
    }
    
    private static final java.text.DateFormatSymbols oldStyleSymbols(DateFormatSymbols syms, Locale loc) {
        java.text.DateFormatSymbols result = new java.text.DateFormatSymbols(loc);
        result.setAmPmStrings(syms.getAmPmStrings());
        result.setEras(syms.getEras());
        result.setLocalPatternChars(syms.getLocalPatternChars());
        result.setMonths(syms.getMonths());
        result.setShortMonths(syms.getShortMonths());
        result.setShortWeekdays(syms.getShortWeekdays());
        result.setWeekdays(syms.getWeekdays());
        result.setZoneStrings(syms.getZoneStrings());
        return result;
    }

    /**
     * Find the ResourceBundle containing the date format information for
     * a specified calendar subclass in a given locale.
     * <p>
     * The resource bundle name is based on the calendar's fully-specified
     * class name, with ".resources" inserted at the end of the package name
     * (just before the class name) and "Symbols" appended to the end.
     * For example, the bundle corresponding to "com.ibm.util.HebrewCalendar"
     * is "com.ibm.util.resources.HebrewCalendarSymbols".
     */
    static protected ResourceBundle getDateFormatBundle(Calendar cal, Locale locale)
                                  throws MissingResourceException
    {
        // Find the calendar's class name, which we're going to use to construct the
        // resource bundle name.
        String fullName = cal.getClass().getName();
        int lastDot = fullName.lastIndexOf('.');
        String className = fullName.substring(lastDot+1);

        // The name of the ResourceBundle itself is the calendar's fully-qualified
        // name, with ".resources" inserted in the package and "Symbols" appended
        String bundleName = fullName.substring(0, lastDot+1) + "resources."
                                + className + "Symbols";
        
        ResourceBundle result = null;
        try {
            result = ResourceBundle.getBundle(bundleName, locale);
        }
        catch (MissingResourceException e) {
            if (!(cal instanceof GregorianCalendar)) {
                // Ok for symbols to be missing for a Gregorian calendar, but
                // not for any other type.
                throw e;
            }
        }
        return result;
    }
    

    //-------------------------------------------------------------------------
    // Protected utility methods for use by subclasses.  These are very handy
    // for implementing add, roll, and computeFields.
    //-------------------------------------------------------------------------
    
    /**
     * Adjust the specified field so that it is within
     * the allowable range for the date to which this calendar is set.
     * For example, in a Gregorian calendar pinning the {@link #DAY_OF_MONTH DAY_OF_MONTH}
     * field for a calendar set to April 31 would cause it to be set
     * to April 30.
     * <p>
     * <b>Subclassing:</b>
     * <br>
     * This utility method is intended for use by subclasses that need to implement
     * their own overrides of {@link #roll roll} and {@link #add add}.
     * <p>
     * <b>Note:</b>
     * <code>pinField</code> is implemented in terms of
     * {@link #getActualMinimum getActualMinimum}
     * and {@link #getActualMaximum getActualMaximum}.  If either of those methods uses
     * a slow, iterative algorithm for a particular field, it would be
     * unwise to attempt to call <code>pinField</code> for that field.  If you
     * really do need to do so, you should override this method to do
     * something more efficient for that field.
     * <p>
     * @param field The calendar field whose value should be pinned.
     *
     * @see #getActualMinimum
     * @see #getActualMaximum
     */
    protected void pinField(int field) {
        int max = getActualMaximum(field);
        int min = getActualMinimum(field);
        
        if (fields[field] > max) {
            set(field, max);
        } else if (fields[field] < min) {
            set(fields[field], min);
        }
    }

    /**
     * Return the week number of a day, within a period. This may be the week number in
     * a year or the week number in a month. Usually this will be a value >= 1, but if
     * some initial days of the period are excluded from week 1, because
     * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is > 1, then 
     * the week number will be zero for those
     * initial days. This method requires the day number and day of week for some
     * known date in the period in order to determine the day of week 
     * on the desired day.
     * <p>
     * <b>Subclassing:</b>
     * <br>
     * This method is intended for use by subclasses in implementing their
     * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods.
     * It is often useful in {@link #getActualMinimum getActualMinimum} and
     * {@link #getActualMaximum getActualMaximum} as well.
     * <p>
     * This variant is handy for computing the week number of some other
     * day of a period (often the first or last day of the period) when its day
     * of the week is not known but the day number and day of week for some other
     * day in the period (e.g. the current date) <em>is</em> known.
     * <p>
     * @param desiredDay    The {@link #DAY_OF_YEAR DAY_OF_YEAR} or
     *              {@link #DAY_OF_MONTH DAY_OF_MONTH} whose week number is desired.
     *              Should be 1 for the first day of the period.
     *
     * @param knownDayOfPeriod   The {@link #DAY_OF_YEAR DAY_OF_YEAR}
     *              or {@link #DAY_OF_MONTH DAY_OF_MONTH} for a day in the period whose
     *              {@link #DAY_OF_WEEK DAY_OF_WEEK} is specified by the
     *              <code>knownDayOfWeek</code> parameter.
     *              Should be 1 for first day of period.
     *
     * @param knownDayOfWeek  The {@link #DAY_OF_WEEK DAY_OF_WEEK} for the day
     *              corresponding to the <code>knownDayOfPeriod</code> parameter.
     *              1-based with 1=Sunday.
     *
     * @return      The week number (one-based), or zero if the day falls before
     *              the first week because
     *              {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
     *              is more than one.
     */
    protected int weekNumber(int desiredDay, int dayOfPeriod, int dayOfWeek)
    {
        int length = getMaximum(DAY_OF_WEEK) - getMinimum(DAY_OF_WEEK) + 1;

        // Determine the day of the week of the first day of the period
        // in question (either a year or a month).  Zero represents the
        // first day of the week on this calendar.
        int periodStartDayOfWeek = (dayOfWeek - getFirstDayOfWeek() - dayOfPeriod + 1) % length;
        if (periodStartDayOfWeek < 0) periodStartDayOfWeek += length;

        // Compute the week number.  Initially, ignore the first week, which
        // may be fractional (or may not be).  We add periodStartDayOfWeek in
        // order to fill out the first week, if it is fractional.
        int weekNo = (desiredDay + periodStartDayOfWeek - 1)/length;

        // If the first week is long enough, then count it.  If
        // the minimal days in the first week is one, or if the period start
        // is zero, we always increment weekNo.
        if ((length - periodStartDayOfWeek) >= getMinimalDaysInFirstWeek()) ++weekNo;

        return weekNo;
    }

    /**
     * Return the week number of a day, within a period. This may be the week number in
     * a year, or the week number in a month. Usually this will be a value >= 1, but if
     * some initial days of the period are excluded from week 1, because
     * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is > 1,
     * then the week number will be zero for those
     * initial days. This method requires the day of week for the given date in order to 
     * determine the result.
     * <p>
     * <b>Subclassing:</b>
     * <br>
     * This method is intended for use by subclasses in implementing their
     * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods.
     * It is often useful in {@link #getActualMinimum getActualMinimum} and
     * {@link #getActualMaximum getActualMaximum} as well.
     * <p>
     * @param dayOfPeriod   The {@link #DAY_OF_YEAR DAY_OF_YEAR} or
     *                      {@link #DAY_OF_MONTH DAY_OF_MONTH} whose week number is desired.
     *                      Should be 1 for the first day of the period.
     *
     * @param dayofWeek     The {@link #DAY_OF_WEEK DAY_OF_WEEK} for the day
     *                      corresponding to the <code>dayOfPeriod</code> parameter.
     *                      1-based with 1=Sunday.
     *
     * @return      The week number (one-based), or zero if the day falls before
     *              the first week because
     *              {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
     *              is more than one.
     */
    protected final int weekNumber(int dayOfPeriod, int dayOfWeek)
    {
        return weekNumber(dayOfPeriod, dayOfPeriod, dayOfWeek);
    }

    //-------------------------------------------------------------------------
    // Constants
    //-------------------------------------------------------------------------
    
    private static final int  SECOND_MS = 1000;
    private static final int  MINUTE_MS = 60*SECOND_MS;
    private static final int  HOUR_MS   = 60*MINUTE_MS;
    private static final long DAY_MS    = 24*HOUR_MS;
    private static final long WEEK_MS   = 7*DAY_MS;
}
