/*   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(CharSequence 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())
            {
                assert(_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 = dtz.getOffset(date.getTime());
        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 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 = def.getOffset(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);
    }

}
