/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.xmlbeans;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * Used to build {@link GDate GDates}.
 * <p>
 * Like GDate, a GDateBuilder represents an Gregorian Date, Time,
 * and Timezone, or subset of information (Year, Month, Day,
 * Time, Timezone, or some combination). Wherever it provides
 * guidance, the XML Schema 1.0 specification (plus published
 * errata) is followed.
 * <p>
 * Instances may separately set or clear the year, month,
 * day-of-month, and time-of-day. Not all operations are
 * meaningful on all combinations. In particular, timezone
 * normalization is only possible if there is a time, or
 * a time together with a full date.
 */
public final class GDateBuilder implements GDateSpecification, java.io.Serializable
{
    private static final long serialVersionUID = 1L;
    
    private int _bits;
    private int _CY;
    private int _M;
    private int _D;
    private int _h;
    private int _m;
    private int _s;
    private BigDecimal _fs;
    private int _tzsign;
    private int _tzh;
    private int _tzm;

    /**
     * Constructs a GDateBuilder specifying no date or time
     */
    public GDateBuilder()
    {
    }

    /**
     * Builds another GDateBuilder with the same value
     * as this one.
     */
    public Object clone()
    {
        return new GDateBuilder(this);
    }

    /**
     * Builds a GDate from this GDateBuilder.
     */
    public GDate toGDate()
    {
        return new GDate(this);
    }

    /**
     * Construts a GDateBuilder by copying another GDateSpecificaiton.
     */
    public GDateBuilder(GDateSpecification gdate)
    {
        if (gdate.hasTimeZone())
            setTimeZone(gdate.getTimeZoneSign(), gdate.getTimeZoneHour(), gdate.getTimeZoneMinute());

        if (gdate.hasTime())
            setTime(gdate.getHour(), gdate.getMinute(), gdate.getSecond(), gdate.getFraction());

        if (gdate.hasDay())
            setDay(gdate.getDay());

        if (gdate.hasMonth())
            setMonth(gdate.getMonth());

        if (gdate.hasYear())
            setYear(gdate.getYear());
    }

    // Forms:

    // Date part:
    // Year:       (-?\d{4,})
    // YearMonth:  (-?\d{4,})-(\d{2})
    // Date:       (-?\d{4,})-(\d{2})-(\d{2})
    // Month:      --(\d{2})(--)?              //errata R-48
    // MonthDay:   --(\d{2})-(\d{2})
    // Day:        ---(\d{2})

    // Time part:
    // Time:       (\d{2}):(\d{2}):(\d{2})(.\d*)?

    // Timezone part:
    // TZ:         (Z)|([+-]\d{2}):(\d{2})

    /**
     * Constructs a GDateBuilder from a lexical
     * representation. The lexical space contains the
     * union of the lexical spaces of all the schema
     * date/time types (except for duration).
     */
    public GDateBuilder(String string)
    {
        this(new GDate(string));
    }


    public GDateBuilder(Calendar calendar)
    {
        this(new GDate(calendar));
    }

    /**
     * Constructs a GDateBuilder with the specified year, month, day,
     * hours, minutes, seconds, and optional fractional seconds, in
     * an unspecified timezone.
     * <p>
     * Note that by not specifying the timezone the GDateBuilder
     * becomes partially unordered with respect to timesthat do have a
     * specified timezone.
     * 
     * @param year The year
     * @param month The month, from 1-12
     * @param day The day of month, from 1-31
     * @param hour The hour of day, from 0-23
     * @param minute The minute of hour, from 0-59
     * @param second The second of minute, from 0-59
     * @param fraction The fraction of second, 0.0 to 0.999... (may be null) 
     */
    public GDateBuilder(
            int year,
            int month,
            int day,
            int hour,
            int minute,
            int second,
            BigDecimal fraction)
    {
        _bits = HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME;

        _CY = year;
        _M = month;
        _D = day;
        _h = hour;
        _m = minute;
        _s = second;
        _fs = fraction == null ? GDate._zero : fraction;

        if (!isValid())
            throw new IllegalArgumentException();
    }

    /**
     * Constructs an absolute GDateBuilder with the specified year,
     * month, day, hours, minutes, seconds, and optional fractional
     * seconds, and in the timezone specified.
     * <p>
     * Note that you can reexpress the GDateBuilder in any timezone using
     * normalizeToTimeZone(). The normalize() method normalizes to UTC.
     * <p>
     * If you wish to have a time or date that isn't in a specified timezone,
     * then use the constructor that does not include the timezone arguments.
     *
     * @param year the year
     * @param month the month, from 1-12
     * @param day the day of month, from 1-31
     * @param hour the hour of day, from 0-23
     * @param minute the minute of hour, from 0-59
     * @param second the second of minute, from 0-59
     * @param fraction the fraction of second, 0.0 to 0.999... (may be null)
     * @param tzSign the timezone offset sign, either +1, 0, or -1
     * @param tzHour the timezone offset hour
     * @param tzMinute the timezone offset minute 
     */
    public GDateBuilder(
            int year,
            int month,
            int day,
            int hour,
            int minute,
            int second,
            BigDecimal fraction,
            int tzSign,
            int tzHour,
            int tzMinute)
    {
        _bits = HAS_TIMEZONE | HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME;

        _CY = year;
        _M = month;
        _D = day;
        _h = hour;
        _m = minute;
        _s = second;
        _fs = fraction == null ? GDate._zero : fraction;
        _tzsign = tzSign;
        _tzh = tzHour;
        _tzm = tzMinute;

        if (!isValid())
            throw new IllegalArgumentException();
    }

    /**
     * Constructs a GDateBuilder based on a java.util.Date.
     * <p>
     * The current offset of the default timezone is used as the timezone.
     * <p>
     * For example, if eastern daylight time is in effect at the given
     * date, the timezone on the east coast of the united states
     * translates to GMT-05:00 (EST) + 1:00 (DT offset) == GMT-04:00.
     * 
     * @param date the date object to copy
     */
    public GDateBuilder(Date date)
    {
        setDate(date);
    }

    /**
     * True if the instance is immutable.
     */
    public boolean isImmutable()
    {
        return false;
    }

    /**
     * Returns a combination of flags indicating the information
     * contained by this GDate.  The five flags are
     * HAS_TIMEZONE, HAS_YEAR, HAS_MONTH, HAS_DAY, and HAS_TIME.
     */
    public int getFlags()
    {
        return _bits;
    }

    /**
     * True if this date/time specification specifies a timezone.
     */
    public final boolean hasTimeZone()
        { return ((_bits & HAS_TIMEZONE) != 0); }

    /**
     * True if this date/time specification specifies a year.
     */
    public final boolean hasYear()
        { return ((_bits & HAS_YEAR) != 0); }

    /**
     * True if this date/time specification specifies a month-of-year.
     */
    public final boolean hasMonth()
        { return ((_bits & HAS_MONTH) != 0); }

    /**
     * True if this date/time specification specifies a day-of-month.
     */
    public final boolean hasDay()
        { return ((_bits & HAS_DAY) != 0); }

    /**
     * True if this date/time specification specifies a time-of-day.
     */
    public final boolean hasTime()
        { return ((_bits & HAS_TIME) != 0); }

    /**
     * True if this date/time specification specifies a full date (year, month, day)
     */
    public final boolean hasDate()
        { return ((_bits & (HAS_DAY | HAS_MONTH | HAS_YEAR)) == (HAS_DAY | HAS_MONTH | HAS_YEAR)); }

    /**
     * Gets the year. Should be a four-digit year specification.
     */
    public final int getYear()
        { return _CY;  }

    /**
     * Gets the month-of-year. January is 1.
     */
    public final int getMonth()
        { return _M;  }

    /**
     * Gets the day-of-month. The first day of each month is 1.
     */
    public final int getDay()
        { return _D; }

    /**
     * Gets the hour-of-day. Midnight is 0, and 11PM is 23.
     */
    public final int getHour()
        { return _h; }

    /**
     * Gets the minute-of-hour. Range from 0 to 59.
     */
    public final int getMinute()
        { return _m; }

    /**
     * Gets the second-of-minute. Range from 0 to 59.
     */
    public final int getSecond()
        { return _s; }


    /**
     * Gets the fraction-of-second. Range from 0 (inclusive) to 1 (exclusive).
     */
    public final BigDecimal getFraction()
        { return _fs; }


    /**
     * Gets the rounded millisecond value. Range from 0 to 999
     */
    public final int getMillisecond()
    {
        if (_fs == null || _fs == GDate._zero)
            return 0;
        return _fs.setScale(3, BigDecimal.ROUND_HALF_UP).unscaledValue().intValue();
    }

    /**
     * Gets the time zone sign. For time zones east of GMT,
     * this is positive; for time zones west, this is negative.
     */
    public final int getTimeZoneSign()
        { return _tzsign; }

    /**
     * Gets the time zone hour.
     * This is always positive: for the sign, look at
     * getTimeZoneSign().
     */
    public final int getTimeZoneHour()
        { return _tzh; }

    /**
     * Gets the time zone minutes.
     * This is always positive: for the sign, look at
     * getTimeZoneSign().
     */
    public final int getTimeZoneMinute()
        { return _tzm; }

    /**
     * Sets the year. Should be a four-digit year specification.
     * @param year the year
     */
    public void setYear(int year)
    {
        if (year < -4712 || year > 999999)
            throw new IllegalArgumentException("year out of range");
        _bits |= HAS_YEAR; _CY = year;
    }

    /**
     * Sets the month-of-year. January is 1.
     * @param month the month, from 1-12
     */
    public void setMonth(int month)
    {
        if (month < 1 || month > 12)
            throw new IllegalArgumentException("month out of range");
        _bits |= HAS_MONTH; _M = month;
    }

    /**
     * Sets the day-of-month. The first day of each month is 1.
     * @param day the day of month, from 1-31
     */
    public void setDay(int day)
    {
        if (day < 1 || day > 31)
            throw new IllegalArgumentException("day out of range");
        _bits |= HAS_DAY; _D = day;
    }

    /**
     * Sets the time. Hours in the day range from 0 to 23;
     * minutes and seconds range from 0 to 59; and fractional
     * seconds range from 0 (inclusive) to 1 (exclusive).
     * The fraction can be null and is assumed to be zero.
     * @param hour the hour of day, from 0-23
     * @param minute the minute of hour, from 0-59
     * @param second the second of minute, from 0-59
     * @param fraction the fraction of second, 0.0 to 0.999... (may be null)
     */
    public void setTime(int hour, int minute, int second, BigDecimal fraction)
    {
        if (hour < 0 || hour > 23)
            throw new IllegalArgumentException("hour out of range");
        if (minute < 0 || minute > 59)
            throw new IllegalArgumentException("minute out of range");
        if (second < 0 || second > 59)
            throw new IllegalArgumentException("second out of range");
        if (fraction != null && (fraction.signum() < 0 || fraction.compareTo(GDate._one) > 1))
            throw new IllegalArgumentException("fraction out of range");
        _bits |= HAS_TIME;
        _h = hour;
        _m = minute;
        _s = second;
        _fs = fraction == null ? GDate._zero : fraction;
    }

    /**
     * Sets the time zone without changing the other time
     * fields. If you with to adjust other time fields to express
     * the same actual moment in time in a different time zone,
     * use normalizeToTimeZone.
     * <p>
     * Timezones must be between -14:00 and +14:00. Sign
     * must be -1 or 1 (or 0 for UTC only), and the offset hours
     * and minute arguments must be nonnegative.
     * 
     * @param tzSign the timezone offset sign, either +1, 0, or -1
     * @param tzHour the timezone offset hour
     * @param tzMinute the timezone offset minute 
     */
    public void setTimeZone(int tzSign, int tzHour, int tzMinute)
    {
        if (!((tzSign == 0 && tzHour == 0 && tzMinute == 0) ||
              ((tzSign == -1 || tzSign == 1) &&
               (tzHour >= 0 && tzMinute >= 0) &&
               (tzHour == 14 && tzMinute == 0 || tzHour < 14 && tzMinute < 60))))
            throw new IllegalArgumentException("time zone out of range (-14:00 to +14:00). (" +
                (tzSign<0 ? "-" : "+") + tzHour + ":" + tzMinute + ")");

        _bits |= HAS_TIMEZONE;
        _tzsign = tzSign;
        _tzh = tzHour;
        _tzm = tzMinute;
    }
    
    /**
     * Sets the time zone based on a number of offset minutes rather
     * than sign/hour/minute; for example, setTimeZone(-60) is the
     * same as setTimeZone(-1, 1, 0).
     */
    public void setTimeZone(int tzTotalMinutes)
    {
        if (tzTotalMinutes < -14 * 60 || tzTotalMinutes > 14 * 60)
            throw new IllegalArgumentException("time zone out of range (-840 to 840 minutes). (" + tzTotalMinutes + ")");
        
        int tzSign = tzTotalMinutes < 0 ? -1 : tzTotalMinutes > 0 ? 1 : 0;
        tzTotalMinutes *= tzSign;
        int tzH = tzTotalMinutes / 60;
        int tzM = tzTotalMinutes - tzH * 60;
        
        setTimeZone(tzSign, tzH, tzM);
    }

    /**
     * Clears the year. After clearing, hasYear returns false and the
     * value of getYear is undefined.
     */
    public void clearYear()
        { _bits &= ~HAS_YEAR; _CY = 0;  }

    /**
     * Clears the month-of-year. After clearing. hasMonth returns false and
     * the value of getMonth is undefined.
     */
    public void clearMonth()
        { _bits &= ~HAS_MONTH; _M = 0;  }

    /**
     * Clears the day-of-month. After clearing. hasDay returns false and
     * the value of getDay is undefined.
     */
    public void clearDay()
        { _bits &= ~HAS_DAY; _D = 0;  }

    /**
     * Clears the time-of-day.
     * After clearing. hasTime returns false and
     * the value of getTime is undefined.
     */
    public void clearTime()
    {
        _bits &= ~HAS_TIME;
        _h = 0;
        _m = 0;
        _s = 0;
        _fs = null;
    }

    /**
     * Clears the timezone. After clearing. hasTimeZone returns false and
     * the value of getTimeZoneHour and getTimeZoneMinute are undefined.
     * Does not change the other time fields.
     */
    public void clearTimeZone()
    {
        _bits &= ~HAS_TIMEZONE;
        _tzsign = 0;
        _tzh = 0;
        _tzm = 0;
    }

    /**
     * True if all date fields lie within their legal ranges.  A GDateBuilder
     * can be invalid, for example, if you change the month to February
     * and the day-of-month is 31.
     */
    public boolean isValid()
    {
        return isValidGDate(this);
    }

    /* package */ static final boolean isValidGDate(GDateSpecification date)
    {
        if (date.hasMonth() && (date.getMonth() < 1 || date.getMonth() > 12))
            return false;

        if (date.hasDay() && (date.getDay() < 1 || date.getDay() > 31 ||
            date.getDay() > 28 && date.hasMonth() &&
                (date.hasYear() ? date.getDay() > _maxDayInMonthFor(date.getYear(), date.getMonth()) :
                                  date.getDay() > _maxDayInMonth(date.getMonth()))))
            return false;

        if (date.hasTime() && (date.getHour() < 0 || date.getHour() > 23 ||
            date.getMinute() < 0 || date.getMinute() > 59 ||
            date.getSecond() < 0 || date.getSecond() > 59 ||
            date.getFraction().signum() < 0 || date.getFraction().compareTo(GDate._one) >= 0))
            return false;

        if (date.hasTimeZone() &&
            (!((date.getTimeZoneSign() == 0 && date.getTimeZoneHour() == 0 && date.getTimeZoneMinute() == 0) ||
              ((date.getTimeZoneSign() == -1 || date.getTimeZoneSign() == +1) &&
                // NB: allow +00:00 and -00:00
                // (date.getTimeZoneHour() == 0 && date.getTimeZoneMinute() > 0 || date.getTimeZoneHour() > 0 && date.getTimeZoneMinute() >= 0) &&
               (date.getTimeZoneHour() >= 0 && date.getTimeZoneMinute() >= 0) &&
               (date.getTimeZoneHour() == 14 && date.getTimeZoneMinute() == 0 || date.getTimeZoneHour() < 14 && date.getTimeZoneMinute() < 60)))))
            return false;

        // everyting looks kosher
        return true;
    }


    /**
     * Normalizes the instance, ensuring date and time fields are within
     * their normal ranges.
     * <p>
     * If no timezone or no time is specified, or if a partial date is specified, this
     * method does nothing, and leaves the timezone information as-is.
     * <p>
     * If a time or time and date is specified, this method normalizes the timezone
     * to UTC.
     */
    public void normalize()
    {
        // DateTime or Time, with TimeZone: normalize to UTC.
        // In the process all the fields will be normalized.
        if (hasDay() == hasMonth() && hasDay() == hasYear() &&
            hasTimeZone() && hasTime())
        {
            normalizeToTimeZone(0, 0, 0);
        }
        else
        {
            // No timezone, or incomplete date.
            long carry = 0;

            if (hasTime())
                carry = _normalizeTime();

            if (hasDay())
                _D += carry;

            if (hasDate())
            {
                _normalizeDate();
            }
            else if (hasMonth())
            {
                // with incomplete dates, just months can be normalized:
                // days stay denormalized.
                if (_M < 1 || _M > 12)
                {
                    int temp = _M;
                    _M = _modulo(temp, 1, 13);
                    if (hasYear())
                        _CY = _CY + (int)_fQuotient(temp, 1, 13);
                }
            }
        }

        // remove trailing zeros from fractional seconds
        if (hasTime() && _fs != null && _fs.scale() > 0)
        {
            if (_fs.signum() == 0)
                _fs = GDate._zero;
            else
            {
                BigInteger bi = _fs.unscaledValue();
                String str = bi.toString();
                int lastzero;
                for (lastzero = str.length(); lastzero > 0; lastzero -= 1)
                    if (str.charAt(lastzero - 1) != '0')
                        break;
                if (lastzero < str.length())
                    _fs = _fs.setScale(_fs.scale() - str.length() + lastzero);
            }
        }
    }

    /**
     * If the time and timezone are known, this method changes the timezone to the
     * specified UTC offset, altering minutes, hours, day, month, and year as
     * necessary to ensure that the actual described moment in time is the same.
     * <p>
     * It is an error to operate on instances without a time or timezone, or
     * with a partially specified date.
     * 
     * @param tzSign the timezone offset sign, either +1, 0, or -1
     * @param tzHour the timezone offset hour
     * @param tzMinute the timezone offset minute 
     */
    public void normalizeToTimeZone(int tzSign, int tzHour, int tzMinute)
    {
        if (!((tzSign == 0 && tzHour == 0 && tzMinute == 0) ||
              ((tzSign == -1 || tzSign == 1) &&
               (tzHour >= 0 && tzMinute >= 0) &&
               (tzHour == 14 && tzMinute == 0 || tzHour < 14 && tzMinute < 60))))
            throw new IllegalArgumentException("time zone must be between -14:00 and +14:00");

        if (!hasTimeZone() || !hasTime())
            throw new IllegalStateException("cannot normalize time zone without both time and timezone");

        if (!(hasDay() == hasMonth() && hasDay() == hasYear()))
            throw new IllegalStateException("cannot do date math without a complete date");

        int hshift = tzSign * tzHour - _tzsign * _tzh;
        int mshift = tzSign * tzMinute - _tzsign * _tzm;

        _tzsign = tzSign;
        _tzh = tzHour;
        _tzm = tzMinute;
        addDuration(1, 0, 0, 0, hshift, mshift, 0, null);
    }

    /**
     * Normalizes to a time zone specified by a number of offset minutes rather
     * than sign/hour/minute; for example, normalizeToTimeZone(-60) is the
     * same as normalizeToTimeZone(-1, 1, 0).
     */
    public void normalizeToTimeZone(int tzTotalMinutes)
    {
        if (tzTotalMinutes < -14 * 60 || tzTotalMinutes > 14 * 60)
            throw new IllegalArgumentException("time zone out of range (-840 to 840 minutes). (" + tzTotalMinutes + ")");
        
        int tzSign = tzTotalMinutes < 0 ? -1 : tzTotalMinutes > 0 ? 1 : 0;
        tzTotalMinutes *= tzSign;
        int tzH = tzTotalMinutes / 60;
        int tzM = tzTotalMinutes - tzH * 60;
        
        normalizeToTimeZone(tzSign, tzH, tzM);
    }


    /**
     * Adds a given duration to the date/time.
     * 
     * @param duration the duration to add
     */
    public void addGDuration(GDurationSpecification duration)
    {
        addDuration(duration.getSign(), duration.getYear(), duration.getMonth(), duration.getDay(),
                    duration.getHour(), duration.getMinute(), duration.getSecond(), duration.getFraction());
    }

    /**
     * Subtracts a given duration from the date/time.
     * 
     * @param duration the duration to subtract
     */
    public void subtractGDuration(GDurationSpecification duration)
    {
        addDuration(-duration.getSign(), duration.getYear(), duration.getMonth(), duration.getDay(),
                    duration.getHour(), duration.getMinute(), duration.getSecond(), duration.getFraction());
    }


    /**
     * Normalizes the date by carrying over to the year any months outside 1..12
     * and carrying over to the month any days outside 1..(days-in-month).
     */
    private void _normalizeDate()
    {
        if (_M < 1 || _M > 12 || _D < 1 || _D > _maxDayInMonthFor(_CY, _M))
        {
            // fix months first
            int temp = _M;
            _M = _modulo(temp, 1, 13);
            _CY = _CY + (int)_fQuotient(temp, 1, 13);

            // then pull days out
            int extradays = _D - 1;
            _D = 1;

            // then use the julian date function to fix
            setJulianDate(getJulianDate() + extradays);
        }
    }

    /**
     * Normalizes time so that fractions are 0..1(exc), seconds/minutes 0..59,
     * and hours 0..24. Returns the number of days to carry over from normalizing
     * away more than 24 hours.
     */
    private long _normalizeTime()
    {
        long carry = 0;
        long temp;

        // fractions
        if (_fs != null && (_fs.signum() < 0 || _fs.compareTo(GDate._one) >= 0))
        {
            BigDecimal bdcarry = _fs.setScale(0, BigDecimal.ROUND_FLOOR);
            _fs = _fs.subtract(bdcarry);
            carry = bdcarry.longValue();
        }

        if (carry != 0 || _s < 0 || _s > 59 || _m < 0 || _m > 50 || _h < 0 || _h > 23)
        {
            // seconds
            temp = _s + carry;
            carry = _fQuotient(temp, 60);
            _s = _mod(temp, 60, carry);

            // minutes
            temp = _m + carry;
            carry = _fQuotient(temp, 60);
            _m = _mod(temp, 60, carry);

            // hours
            temp = _h + carry;
            carry = _fQuotient(temp, 24);
            _h = _mod(temp, 24, carry);
        }

        return carry;
    }

    /**
     * Adds a given duration to the date/time.
     * 
     * @param sign +1 to add, -1 to subtract
     * @param year the number of years to add
     * @param month the number of months to add
     * @param day the number of days to add
     * @param hour the number of hours to add
     * @param minute the number of minutes to add
     * @param second the number of seconds to add
     * @param fraction the number of fractional seconds to add (may be null)
     */
    public void addDuration(int sign, int year, int month, int day,
                            int hour, int minute, int second, BigDecimal fraction)
    {
        boolean timemath = hour != 0 || minute != 0 || second != 0 || fraction != null && fraction.signum() != 0;
        if (timemath && !hasTime())
            throw new IllegalStateException("cannot do time math without a complete time");
        boolean datemath = hasDay() && (day != 0 || timemath);
        if (datemath && !hasDate())
            throw new IllegalStateException("cannot do date math without a complete date");

        int temp;

        // months + years are easy
        if (month != 0 || year != 0)
        {
            // Prepare the _D to be pegged before changing month
            if (hasDay())
                _normalizeDate();

            // Add months and years
            temp = _M + sign * month;
            _M = _modulo(temp, 1, 13);
            _CY = _CY + sign * year + (int)_fQuotient(temp, 1, 13);

            // In new month, day may need to be pegged before proceeding
            if (hasDay())
            {
                if (XmlBeans.ASSERTS)
                    XmlBeans.assertTrue(_D >= 1);
                temp = _maxDayInMonthFor(_CY, _M);
                if (_D > temp)
                    _D = temp;
            }
        }

        long carry = 0;

        if (timemath)
        {
            // fractions
            if (fraction != null && fraction.signum() != 0)
            {
                if (_fs.signum() == 0 && sign == 1)
                    _fs = fraction;
                else
                    _fs = (sign == 1) ? _fs.add(fraction) : _fs.subtract(fraction);
            }

            // seconds, minutes, hours
            _s += sign * second;
            _m += sign * minute;
            _h += sign * hour;

            // normalize time
            carry = _normalizeTime();
        }

        if (datemath)
        {
            // days: may require renormalization
            _D += sign * day + carry;
            _normalizeDate();
        }
    }

    /**
     * Given {year,month} computes maximum
     * number of days for given month
     */
    private static int _maxDayInMonthFor(int year, int month)
    {
        if (month == 4 || month == 6 || month == 9 || month == 11)
            return 30;

        if (month == 2)
            return (_isLeapYear(year) ? 29 : 28);

        return 31;
    }

    /**
     * Given {year,month} computes maximum
     * number of days for given month
     */
    private static int _maxDayInMonth(int month)
    {
        if (month == 4 || month == 6 || month == 9 || month == 11)
            return 30;

        if (month == 2)
            return 29;

        return 31;
    }

    /**
     * Returns the Julian date corresponding to this Gregorian date.
     * The Julian date (JD) is a continuous count of days from
     * 1 January 4713 BC (= -4712 January 1).
     */
    public final int getJulianDate()
    {
        return julianDateForGDate(this);
    }


    /**
     * Sets the Gregorian date based on the given Julian date.
     * The Julian date (JD) is a continuous count of days from
     * 1 January 4713 BC (= -4712 January 1).
     * 
     * @param julianday the julian day number
     */
    public void setJulianDate(int julianday)
    {
        if (julianday < 0)
            throw new IllegalArgumentException("date before year -4712");

        int temp;
        int qepoc;

        // from http://aa.usno.navy.mil/faq/docs/JD_Formula.html
        temp = julianday + 68569;
        qepoc = 4 * temp / 146097;
        temp = temp - (146097 * qepoc + 3) / 4;
        _CY = 4000 * (temp + 1) / 1461001;
        temp = temp - 1461 * _CY / 4 + 31;
        _M = 80 * temp / 2447;
        _D = temp - 2447 * _M / 80;
        temp = _M / 11;
        _M = _M + 2 - 12 * temp;
        _CY = 100 * (qepoc - 49) + _CY + temp;

        _bits |= HAS_DAY | HAS_MONTH | HAS_YEAR;
    }


    /**
     * Sets the current time and date based on a java.util.Date instance.
     * <p>
     * The timezone offset used is based on the default TimeZone. (The
     * default TimeZone is consulted to incorporate daylight savings offsets
     * if applicable for the current date as well as the base timezone offset.)
     * <p>
     * If you wish to normalize the timezone, e.g., to UTC, follow this with
     * a call to normalizeToTimeZone.
     * 
     * @param date the Date object to copy
     */
    public void setDate(Date date)
    {
        // Default timezone
        TimeZone dtz = TimeZone.getDefault();
        int offset = getOffset(dtz, date);
        int offsetsign = 1;
        if (offset < 0)
        {
            offsetsign = -1;
            offset = -offset;
        }
        int offsetmin = offset / (1000 * 60);
        int offsethr = offsetmin / 60;
        offsetmin = offsetmin - offsethr * 60;

        setTimeZone(offsetsign, offsethr, offsetmin);
        
        // paranoia: tz.getOffset can return fractions of minutes, but we must round
        int roundedoffset = offsetsign * (offsethr * 60 + offsetmin) * 60 * 1000;

        // midnight
        setTime(0, 0, 0, GDate._zero);

        // Set to January 1, 1970.
        // setJulianDate(2440588);
        _bits |= HAS_DAY | HAS_MONTH | HAS_YEAR;
        _CY = 1970;
        _M = 1;
        _D = 1;

        // Add a duration representing the number of milliseconds
        addGDuration(new GDuration(1, 0, 0, 0, 0, 0, 0,
                BigDecimal.valueOf(date.getTime() + roundedoffset, 3)));

        // special case: ss.000 -> ss
        if (_fs.signum() == 0)
            _fs = GDate._zero;
    }
    
    /**
     * Copies a GDateSpecification, completely replacing the current
     * information in this GDateBuilder.
     * 
     * @param gdate the GDateSpecification to copy
     */ 
    public void setGDate(GDateSpecification gdate)
    {
        _bits = gdate.getFlags() & (HAS_TIMEZONE | HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME);
        _CY = gdate.getYear();
        _M = gdate.getMonth();
        _D = gdate.getDay();
        _h = gdate.getHour();
        _m = gdate.getMinute();
        _s = gdate.getSecond();
        _fs = gdate.getFraction();
        _tzsign = gdate.getTimeZoneSign();
        _tzh = gdate.getTimeZoneHour();
        _tzm = gdate.getTimeZoneMinute();
    }


    /**
     * Retrieves the value of the current time as an {@link XmlCalendar}.
     * <p>
     * {@link XmlCalendar} is a subclass of {@link java.util.GregorianCalendar}
     * which is slightly customized to match XML schema date rules.
     * <p>
     * The returned {@link XmlCalendar} has only those time and date fields
     * set that are reflected in the GDate object.  Because of the way the
     * {@link java.util.Calendar} contract works, any information in the isSet() vanishes
     * as soon as you view any unset field using get() methods.
     * This means that if it is important to understand which date fields
     * are set, you must call isSet() first before get().
     */
    public XmlCalendar getCalendar()
    {
        return new XmlCalendar(this);
    }

    /**
     * Retrieves the value of the current time as a java.util.Date
     * instance.
     */
    public Date getDate()
    {
        return dateForGDate(this);
    }


    /* package */ static int getOffset(TimeZone tz, long time)
    {
        return getOffset(tz, new Date(time));
    }

    /* package */ static int getOffset(TimeZone tz, Date date)
    {
        if (tz.inDaylightTime(date))
            return tz.getRawOffset() + (tz.useDaylightTime() ? 3600000 : 0);
        
        return tz.getRawOffset();
    }

    /* package */ static int julianDateForGDate(GDateSpecification date)
    {
        if (!date.hasDate())
            throw new IllegalStateException("cannot do date math without a complete date");

        // from http://aa.usno.navy.mil/faq/docs/JD_Formula.html
        int result = date.getDay()-32075+1461*(date.getYear()+4800+(date.getMonth()-14)/12)/4+
            367*(date.getMonth()-2-(date.getMonth()-14)/12*12)/12-3*((date.getYear()+4900+(date.getMonth()-14)/12)/100)/4;

        if (result < 0)
            throw new IllegalStateException("date too far in the past (year allowed to -4712)");

        return result;
    }

    /* package */ static Date dateForGDate(GDateSpecification date)
    {
        long jDate = julianDateForGDate(date);
        long to1970Date = jDate - 2440588;
        long to1970Ms = 1000 * 60 * 60 * 24 * to1970Date;

        to1970Ms += date.getMillisecond();
        to1970Ms += date.getSecond() * 1000;
        to1970Ms += date.getMinute() * 60 * 1000;
        to1970Ms += date.getHour() * 60 * 60 * 1000;
        if (date.hasTimeZone())
        {
            to1970Ms -= (date.getTimeZoneMinute() * date.getTimeZoneSign()) * 60 * 1000;
            to1970Ms -= (date.getTimeZoneHour() * date.getTimeZoneSign()) * 60 * 60 * 1000;
        }
        else
        {
            TimeZone def = TimeZone.getDefault();
            int offset = getOffset(def, to1970Ms);
            to1970Ms -= offset;
        }

        return new Date(to1970Ms);
    }

    /**
     * True for leap years.
     */
    private static boolean _isLeapYear(int year)
    {
        // BUGBUG: Julian calendar?
        return ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)));
    }

    /**
     * fQuotient(a, b) = the greatest integer less than or equal to a/b
     */
    private static final long _fQuotient(long a, int b)
    {
        if ((a < 0) == (b < 0))
            return a / b;

        return -((b - a - 1) / b);
    }

    /**
     * modulo(a, b) = a - fQuotient(a,b)*b
     */
    private static int _mod(long a, int b, long quotient)
    {
        return (int)(a - quotient*b) ;
    }

    /**
     * modulo(a - low, high - low) + low
     */
    private static final int _modulo(long temp, int low, int high)
    {
        long a = temp - low;
        int b = high - low;
        return (_mod(a, b, _fQuotient(a, b)) + low) ;
    }

    /**
     * Quotient(a - low, high - low)
     */
    private static final long _fQuotient(long temp, int low, int high)
    {
        return _fQuotient(temp - low, high - low);
    }

    /**
     * Sets to the first possible moment that matches the given
     * specification.
     */
    private void _setToFirstMoment()
    {
        // 1584 was the first leap year during which the Gregorian
        // calendar was in use: seems like the most reasonable "first"
        // year to use in absence of a year.

        if (!hasYear())
            setYear(1584);

        if (!hasMonth())
            setMonth(1);

        if (!hasDay())
            setDay(1);

        if (!hasTime())
            setTime(0, 0, 0, GDate._zero);
    }

    /**
     * Comparison to another GDate.
     * <ul>
     * <li>Returns -1 if this < date. (less-than)
     * <li>Returns 0 if this == date. (equal)
     * <li>Returns 1 if this > date. (greater-than)
     * <li>Returns 2 if this <> date. (incomparable)
     * </ul>
     * Two instances are incomparable if they have different amounts
     * of information.
     * 
     * @param datespec the date to compare against
     */
    public final int compareToGDate(GDateSpecification datespec)
    {
        return compareGDate(this, datespec);
    }


    /* package */ static final int compareGDate(GDateSpecification tdate, GDateSpecification datespec)
    {
        // same amount of information: looks good
        int bitdiff = tdate.getFlags() ^ datespec.getFlags();

        easy: if ((bitdiff & (HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME | HAS_TIMEZONE)) == 0)
        {
            // If the other date needs to be normalized to
            // our timezone, make a clone and do so if possible
            if (tdate.hasTimeZone() &&
                (datespec.getTimeZoneHour() != tdate.getTimeZoneHour() ||
                 datespec.getTimeZoneMinute() != tdate.getTimeZoneMinute() ||
                 datespec.getTimeZoneSign() != tdate.getTimeZoneSign()))
            {
                datespec = new GDateBuilder(datespec);

                int flags = tdate.getFlags() & (HAS_YEAR | HAS_MONTH | HAS_DAY);
                if (flags != 0 && flags != (HAS_YEAR | HAS_MONTH | HAS_DAY) || !tdate.hasTime())
                {
                    // in these cases we'll need to fill in fields
                    ((GDateBuilder)datespec)._setToFirstMoment();
                    tdate = new GDateBuilder(tdate);
                    ((GDateBuilder)tdate)._setToFirstMoment();
                }

                ((GDateBuilder)datespec).normalizeToTimeZone(tdate.getTimeZoneSign(), tdate.getTimeZoneHour(), tdate.getTimeZoneMinute());
            }

            // compare by field
            return fieldwiseCompare(tdate, datespec);
        }

        // different amounts of information (except timezone): not comparable
        if ((bitdiff & (HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME)) != 0)
            return 2;

        // The schema spec says we should try to compare with-timezone and
        // without-timezone specifications... Well, OK, sure, if they say so.

        // We don't have a timezone but the other does: reverse the call
        if (!tdate.hasTimeZone())
        {
            int result = compareGDate(datespec, tdate);
            return result == 2 ? 2 : -result;
        }

        // Now tdate is guaranteed to have a timezone and datespec not.

        // To muck with the times, make clones
        GDateBuilder pdate = new GDateBuilder(tdate);

        // To cover the one uncovered case: if one date is 02/28 and the
        // other date is 03/01, shift days closer by one to simulate being
        // the last day of the month within a leap year
        if ((tdate.getFlags() & (HAS_YEAR | HAS_MONTH | HAS_DAY)) == (HAS_MONTH | HAS_DAY))
        {
            if (tdate.getDay() == 28 && tdate.getMonth() == 2)
            {
                if (datespec.getDay() == 01 && datespec.getMonth() == 3)
                {
                    pdate.setDay(29);
                }
            }
            else if (datespec.getDay() == 28 && datespec.getMonth() == 2)
            {
                if (tdate.getDay() == 01 && tdate.getMonth() == 3)
                {
                    pdate.setMonth(02);
                    pdate.setDay(29);
                }
            }
        }

        // For timespans, compare by first instant of time
        // possible. Therefore, fill in Midnight, January 1, 1584 (a leap year)
        // in absence of other information.
        pdate._setToFirstMoment();

        // P < Q if P < (Q with time zone +14:00)
        GDateBuilder qplusdate = new GDateBuilder(datespec);
        qplusdate._setToFirstMoment();
        qplusdate.setTimeZone(1, 14, 0);
        qplusdate.normalizeToTimeZone(tdate.getTimeZoneSign(), tdate.getTimeZoneHour(), tdate.getTimeZoneMinute());
        if (fieldwiseCompare(pdate, qplusdate) == -1)
            return -1;

        // P > Q if P > (Q with time zone -14:00)
        GDateBuilder qminusdate = qplusdate;
        qminusdate.setGDate(datespec);
        qminusdate._setToFirstMoment();
        qminusdate.setTimeZone(-1, 14, 0);
        qminusdate.normalizeToTimeZone(tdate.getTimeZoneSign(), tdate.getTimeZoneHour(), tdate.getTimeZoneMinute());
        if (fieldwiseCompare(pdate, qminusdate) == 1)
            return 1;

        // P <> Q otherwise
        return 2;
    }

    /**
     * Does a simple most-significant-digit-first comparison,
     * ignoring any timezone or has/doesn't have issues.
     * The data must have been digested first.
     */
    private static int fieldwiseCompare(GDateSpecification tdate, GDateSpecification date)
    {
        if (tdate.hasYear())
        {
            int CY = date.getYear();
            int TCY = tdate.getYear();
            if (TCY < CY) return -1;
            if (TCY > CY) return 1;
        }
        if (tdate.hasMonth())
        {
            int M = date.getMonth();
            int TM = tdate.getMonth();
            if (TM < M) return -1;
            if (TM > M) return 1;
        }
        if (tdate.hasDay())
        {
            int D = date.getDay();
            int TD = tdate.getDay();
            if (TD < D) return -1;
            if (TD > D) return 1;
        }
        if (tdate.hasTime())
        {
            int h = date.getHour();
            int th = tdate.getHour();
            if (th < h) return -1;
            if (th > h) return 1;
            int m = date.getMinute();
            int tm = tdate.getMinute();
            if (tm < m) return -1;
            if (tm > m) return 1;
            int s = date.getSecond();
            int ts = tdate.getSecond();
            if (ts < s) return -1;
            if (ts > s) return 1;
            BigDecimal fs = date.getFraction();
            BigDecimal tfs = tdate.getFraction();
            if (tfs == null && fs == null) return 0;
            return (tfs == null ? GDate._zero : tfs).compareTo(fs == null ? GDate._zero : fs);
        }

        return 0;
    }

    /**
     * Returns the builtin type code for the shape of the information
     * contained in this instance, or 0 if the
     * instance doesn't contain information corresponding to a
     * Schema type.
     * <p> 
     * Value will be equal to
     * {@link SchemaType#BTC_NOT_BUILTIN},
     * {@link SchemaType#BTC_G_YEAR},
     * {@link SchemaType#BTC_G_YEAR_MONTH},
     * {@link SchemaType#BTC_G_MONTH},
     * {@link SchemaType#BTC_G_MONTH_DAY},
     * {@link SchemaType#BTC_G_DAY},
     * {@link SchemaType#BTC_DATE},
     * {@link SchemaType#BTC_DATE_TIME}, or
     * {@link SchemaType#BTC_TIME}.
     */
    public final int getBuiltinTypeCode()
    {
        return btcForFlags(_bits);
    }

    /* package */ static int btcForFlags(int flags)
    {
        switch (flags & (HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME))
        {
            case HAS_YEAR:
                return SchemaType.BTC_G_YEAR;
            case HAS_YEAR | HAS_MONTH:
                return SchemaType.BTC_G_YEAR_MONTH;
            case HAS_MONTH:
                return SchemaType.BTC_G_MONTH;
            case HAS_MONTH | HAS_DAY:
                return SchemaType.BTC_G_MONTH_DAY;
            case HAS_DAY:
                return SchemaType.BTC_G_DAY;
            case HAS_YEAR | HAS_MONTH | HAS_DAY:
                return SchemaType.BTC_DATE;
            case HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME:
                return SchemaType.BTC_DATE_TIME;
            case HAS_TIME:
                return SchemaType.BTC_TIME;
            default:
                return SchemaType.BTC_NOT_BUILTIN;
        }
    }

    /**
     * Clears the fields in this GDateBuilder that are not applicable
     * for the given SchemaType date code.  The code should be
     * {@link SchemaType#BTC_G_YEAR},
     * {@link SchemaType#BTC_G_YEAR_MONTH},
     * {@link SchemaType#BTC_G_MONTH},
     * {@link SchemaType#BTC_G_MONTH_DAY},
     * {@link SchemaType#BTC_G_DAY},
     * {@link SchemaType#BTC_DATE},
     * {@link SchemaType#BTC_DATE_TIME}, or
     * {@link SchemaType#BTC_TIME}.
     * 
     * @param typeCode the type code to apply
     */
    public void setBuiltinTypeCode(int typeCode)
    {
        switch (typeCode)
        {
            case SchemaType.BTC_G_YEAR:
                //HAS_YEAR
                clearMonth();
                clearDay();
                clearTime();
                return;
            case SchemaType.BTC_G_YEAR_MONTH:
                //HAS_YEAR | HAS_MONTH
                clearDay();
                clearTime();
                return;
            case SchemaType.BTC_G_MONTH:
                //HAS_MONTH
                clearYear();
                clearDay();
                clearTime();
                return;
            case SchemaType.BTC_G_MONTH_DAY:
                //HAS_MONTH | HAS_DAY
                clearYear();
                clearTime();
                return;
            case SchemaType.BTC_G_DAY:
                //HAS_DAY
                clearYear();
                clearMonth();
                clearTime();
                return;
            case SchemaType.BTC_DATE:
                //HAS_YEAR | HAS_MONTH | HAS_DAY
                clearTime();
                return;
            case SchemaType.BTC_DATE_TIME:
                //HAS_YEAR | HAS_MONTH | HAS_DAY | HAS_TIME
                return;
            case SchemaType.BTC_TIME:
                //HAS_TIME
                clearYear();
                clearMonth();
                clearDay();
                return;
            default:
                throw new IllegalArgumentException("codeType must be one of SchemaType BTC_  DATE TIME related types.");
        }
    }


    /* package */ static final BigInteger TEN = BigInteger.valueOf(10);

    /**
     * The canonical string representation. Specific moments or
     * times-of-day in a specified timezone are normalized to
     * UTC time to produce a canonical string form for them.
     * Other recurring time specifications keep their timezone
     * information.
     */
    public String canonicalString()
    {
        boolean needNormalize =
            (hasTimeZone() && getTimeZoneSign() != 0 && hasTime() &&
            ((hasDay() == hasMonth() && hasDay() == hasYear())));

        if (!needNormalize && getFraction().scale() > 0)
        {
            BigInteger bi = getFraction().unscaledValue();
            needNormalize = (bi.mod(TEN).signum() == 0);
        }

        if (!needNormalize)
            return toString();

        GDateBuilder cdate = new GDateBuilder(this);
        cdate.normalize();
        return cdate.toString();
    }

    /**
     * The natural string representation. This represents the information
     * that is available, including timezone. For types that correspond
     * to defined schema types (schemaBuiltinTypeCode() > 0),
     * this provides the natural lexical representation.
     * <p>
     * When both time and timezone are specified, this string is not
     * the canonical representation unless the timezone is UTC (Z)
     * (since the same moment in time can be expressed in different
     * timezones). To get a canonical string, use the canonicalString()
     * method.
     */
    public final String toString()
    {
        return GDate.formatGDate(this);
    }

}
