/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation.  All rights 
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer. 
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:  
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must 
*    not be used to endorse or promote products derived from this
*    software without prior written permission. For written 
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache 
*    XMLBeans", nor may "Apache" appear in their name, without prior 
*    written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems 
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/

package org.apache.xmlbeans;

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

/**
 * Represents an XML Schema-compatible Gregorian date.
 * <p>
 * There are many date types in XML Schema, and this type
 * represents the natural union of all those types.  A GDate
 * can hold any subset of date fields (Year, Month, Day, Time,
 * Timezone, or some combination). Wherever the specification
 * provides guidance, the guidelines in the
 * <a target="_blank" href="http://www.w3.org/TR/xmlschema-2/">XML Schema 1.0 specification</a>
 * (plus <a target="_blank" href="http://www.w3.org/2001/05/xmlschema-errata">published errata</a>) are followed.
 * <p>
 * Instances may separately have values or no values for
 * the year, month, day-of-month, and time-of-day. Not all
 * operations are meaningful on all combinations.
 */
public final class GDate implements GDateSpecification, java.io.Serializable
{
    private static final long serialVersionUID = 1L;
    
    // for fast equality comparison, hashing, and serialization
    private transient String _canonicalString;
    private transient String _string;

    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;
    
    
    /* package */ static final BigDecimal _zero = BigDecimal.valueOf(0);
    /* package */ static final BigDecimal _one = BigDecimal.valueOf(1);

    /**
     * Constructs a GDate based on a lexical representation.
     */
    public GDate(CharSequence string)
    {
        // first trim XML whitespace
        int len = string.length();
        int start = 0;
        while (len > 0 && isSpace(string.charAt(len - 1)))
            len -= 1;
        while (start < len && isSpace(string.charAt(start)))
            start += 1;

        // pick optional timezone off the end
        if (len - start >= 1 && string.charAt(len - 1) == 'Z')
        {
            _bits |= HAS_TIMEZONE;
            len -= 1;
        }
        else if (len - start >= 6)
        timezone: {
            int tzsign;
            int tzhour;
            int tzminute;

            if (string.charAt(len - 3) != ':')
                break timezone;

            switch (string.charAt(len - 6))
            {
                case '-':
                    tzsign = -1; break;
                case '+':
                    tzsign = 1; break;
                default:
                    break timezone;
            }

            tzhour = twoDigit(string, len - 5);
            tzminute = twoDigit(string, len - 2);
            if (tzhour > 14)
                throw new IllegalArgumentException("time zone hour must be two digits between -14 and +14");
            if (tzminute > 59)
                throw new IllegalArgumentException("time zone minute must be two digits between 00 and 59");
            _bits |= HAS_TIMEZONE;
            _tzsign = tzsign;
            _tzh = tzhour;
            _tzm = tzminute;
            len -= 6;
        }

        // pick date fields off the beginning if it doesn't look like a time
        if (start < len && (start + 2 >= len || string.charAt(start + 2) != ':'))
        scandate:
        {
            // parse year sign
            boolean negyear = false;
            if (start < len && string.charAt(start) == '-')
            {
                negyear = true;
                start += 1;
            }

            // scan year digits
            int value = 0;
            int digits = -start;
            char ch;
            for (;;)
            {
                ch = start < len ? string.charAt(start) : '\0';
                if (!isDigit(ch))
                    break;
                value = value * 10 + digitVal(ch);
                start += 1;
            }
            digits += start;
            if (digits > 6)
                throw new IllegalArgumentException("year too long (up to 6 digits)");
            else if (digits >= 4)
            {
                _bits |= HAS_YEAR;
                _CY =  negyear ? -value : value;
            }
            else if (digits > 0)
                throw new IllegalArgumentException("year must be four digits (may pad with zeroes, e.g., 0560)");

            // hyphen introduces a month
            if (ch != '-')
            {
                if (negyear && !hasYear())
                    throw new IllegalArgumentException(); // a single minus
                else
                    break scandate;
            }
            start += 1;

            // two-digit month
            if (len - start >= 2)
            {
                value = twoDigit(string, start);
                if (value >= 1 && value <= 12)
                {
                    _bits |= HAS_MONTH;
                    _M = value;
                    start += 2;
                }
            }

            // hyphen introduces a day
            ch = start < len ? string.charAt(start) : '\0';
            if (ch != '-')
            {
                if (!hasMonth())
                    throw new IllegalArgumentException(); // minus after a year
                else
                    break scandate;
            }
            start += 1;

            // two-digit day
            if (len - start >= 2)
            {
                value = twoDigit(string, start);
                if (value >= 1 && value <= 31)
                {
                    _bits |= HAS_DAY;
                    _D = value;
                    start += 2;
                }
            }

            if (!hasDay())
            {
                // error in the original schema spec permits an extra '-' here
                if (hasMonth() && !hasYear())
                {
                    ch = start < len ? string.charAt(start) : '\0';
                    if (ch == '-')
                    {
                        start += 1;
                        break scandate;
                    }
                }
                throw new IllegalArgumentException(); // minus after a month
            }
        }

        // time
        if (start < len)
        {
            if (hasYear() || hasMonth() || hasDay())
            {
                if (string.charAt(start) != 'T')
                   throw new IllegalArgumentException("date and time must be separated by 'T'");
                start += 1;
            }

            if (len < start + 8 || string.charAt(start + 2) != ':' || string.charAt(start + 5) != ':')
                throw new IllegalArgumentException();

            int h = twoDigit(string, start);
            if (h >= 24)
                throw new IllegalArgumentException("hour must be between 00 and 23");
            int m = twoDigit(string, start + 3);
            if (m >= 60)
                throw new IllegalArgumentException("minute must be between 00 and 59");
            int s = twoDigit(string, start + 6);
            if (s >= 60)
                throw new IllegalArgumentException("second must be between 00 and 59");

            start += 8;

            BigDecimal fs = _zero;
            if (start < len)
            {
                if (string.charAt(start) != '.')
                    throw new IllegalArgumentException();
                if (start + 1 < len)
                {
                    for (int i = start + 1; i < len; i++)
                    {
                        if (!isDigit(string.charAt(i)))
                            throw new IllegalArgumentException();
                    }
                    try
                    {
                        fs = new BigDecimal(string.subSequence(start, len).toString());
                    }
                    catch (Throwable e)
                    {
                        throw new IllegalArgumentException();
                    }
                }
            }

            _bits |= HAS_TIME;
            _h = h;
            _m = m;
            _s = s;
            _fs = fs;
        }

        if (!isValid())
            throw new IllegalArgumentException("invalid date");
    }

    /**
     * Constructs a GDate 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 GDate
     * becomes partially unordered with respect to times that
     * do have a specified timezone.
     */
    public GDate(
            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 ? _zero : fraction;

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

    /**
     * Constructs an absolute GDate with the specified year,
     * month, day, hours, minutes, seconds, and optional fractional
     * seconds, and in the timezone specified.
     * <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.
     */
    public GDate(
            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 ? _zero : fraction;
        _tzsign = tzSign;
        _tzh = tzHour;
        _tzm = tzMinute;

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

    /**
     * Constructs a GDate 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.
     */
    public GDate(Date date)
    {
        // requires some date math, so ctor lives on GDateBuilder
        this(new GDateBuilder(date));
    }

    /**
     * Constructs a GDate based on a java.util.Calendar.
     * <p>
     * If the calendar does not have some fields set, the same absence
     * of information is reflected in the GDate.  Note that
     * java.util.GregorianCalendar fills in all fields as soon as any
     * are fetched, so constructing a GDate with the same calendar object
     * twice may result in a different GDate because of a changed calendar.
     * Note that org.apache.xmlbeans.XmlCalendar is stable if you re-get a set field,
     * so it does not have the same problem.
     */
    public GDate(Calendar calendar)
    {
        // we must scrape the "isSet" information out before accessing anything
        boolean isSetYear = calendar.isSet(Calendar.YEAR);
        boolean isSetEra = calendar.isSet(Calendar.ERA);
        boolean isSetMonth = calendar.isSet(Calendar.MONTH);
        boolean isSetDay = calendar.isSet(Calendar.DAY_OF_MONTH);
        boolean isSetHourOfDay = calendar.isSet(Calendar.HOUR_OF_DAY);
        boolean isSetHour = calendar.isSet(Calendar.HOUR);
        boolean isSetAmPm = calendar.isSet(Calendar.AM_PM);
        boolean isSetMinute = calendar.isSet(Calendar.MINUTE);
        boolean isSetSecond = calendar.isSet(Calendar.SECOND);
        boolean isSetMillis = calendar.isSet(Calendar.MILLISECOND);
        boolean isSetZone = calendar.isSet(Calendar.ZONE_OFFSET);
        boolean isSetDst = calendar.isSet(Calendar.DST_OFFSET);

        if (isSetYear)
        {
            int y = calendar.get(Calendar.YEAR);
            if (isSetEra && calendar instanceof GregorianCalendar)
                if (calendar.get(Calendar.ERA) == GregorianCalendar.BC)
                    y = 1 - y;
            _bits |= HAS_YEAR;
            _CY = y;
        }
        if (isSetMonth)
        {
            _bits |= HAS_MONTH;
            _M = calendar.get(Calendar.MONTH) + 1; // !!note
        }
        if (isSetDay)
        {
            _bits |= HAS_DAY;
            _D = calendar.get(Calendar.DAY_OF_MONTH);
        }
        boolean gotTime = false;

        int h = 0;
        int m = 0;
        int s = 0;
        BigDecimal fs = _zero;

        if (isSetHourOfDay)
        {
            h = calendar.get(Calendar.HOUR_OF_DAY);
            gotTime = true;
        }
        else if (isSetHour && isSetAmPm)
        {
            h = calendar.get(Calendar.HOUR) + calendar.get(Calendar.AM_PM) * 12;
            gotTime = true;
        }

        if (isSetMinute)
        {
            m = calendar.get(Calendar.MINUTE);
            gotTime = true;
        }

        if (isSetSecond)
        {
            s = calendar.get(Calendar.SECOND);
            gotTime = true;
        }

        if (isSetMillis)
        {
            fs = BigDecimal.valueOf(calendar.get(Calendar.MILLISECOND), 3);
            gotTime = true;
        }

        if (gotTime)
        {
            _bits |= HAS_TIME;
            _h = h;
            _m = m;
            _s = s;
            _fs = fs;
        }

        if (isSetZone)
        {
            int zoneOffsetInMilliseconds = calendar.get(Calendar.ZONE_OFFSET);
            if (isSetDst)
                zoneOffsetInMilliseconds += calendar.get(Calendar.DST_OFFSET);

            _bits |= HAS_TIMEZONE;
            if (zoneOffsetInMilliseconds == 0)
            {
                _tzsign = 0;
                _tzh = 0;
                _tzm = 0;
                TimeZone zone = calendar.getTimeZone();
                String id = zone.getID();
                if (id != null && id.length() > 3) switch (id.charAt(3))
                {
                    case '+': _tzsign = 1; break;   // GMT+00:00
                    case '-': _tzsign = -1; break;  // GMT-00:00
                }
            }
            else
            {
                _tzsign = (zoneOffsetInMilliseconds < 0 ? -1 : +1);
                zoneOffsetInMilliseconds = zoneOffsetInMilliseconds * _tzsign;
                _tzh = zoneOffsetInMilliseconds / 3600000;
                _tzm = (zoneOffsetInMilliseconds - _tzh * 3600000) / 60000;
            }
        }
    }

    /**
     * Constructs a GDate based on another GDateSpecification.
     */
    public GDate(GDateSpecification gdate)
    {
        if (gdate.hasTimeZone())
        {
            _bits |= HAS_TIMEZONE;
            _tzsign = gdate.getTimeZoneSign();
            _tzh = gdate.getTimeZoneHour();
            _tzm = gdate.getTimeZoneMinute();
        }

        if (gdate.hasTime())
        {
            _bits |= HAS_TIME;
            _h = gdate.getHour();
            _m = gdate.getMinute();
            _s = gdate.getSecond();
            _fs = gdate.getFraction();
        }

        if (gdate.hasDay())
        {
            _bits |= HAS_DAY;
            _D = gdate.getDay();
        }

        if (gdate.hasMonth())
        {
            _bits |= HAS_MONTH;
            _M = gdate.getMonth();
        }

        if (gdate.hasYear())
        {
            _bits |= HAS_YEAR;
            _CY = gdate.getYear();
        }
    }

    /* package */ static final boolean isDigit(char ch)
    {
        return ((char)(ch - '0') <= '9' - '0'); // char is unsigned
    }

    /* package */ static final boolean isSpace(char ch)
    {
        switch (ch)
        {
            case ' ':
            case '\t':
            case '\r':
            case '\n':
                return true;
            default:
                return false;
        }
    }

    /* package */ static final int digitVal(char ch)
    {
        return (ch - '0');
    }

    private static final int twoDigit(CharSequence str, int index)
    {
        char ch1 = str.charAt(index);
        char ch2 = str.charAt(index + 1);
        if (!isDigit(ch1) || !isDigit(ch2))
            return 100; // not two digits
        return digitVal(ch1) * 10 + digitVal(ch2);
    }

    /**
     * Returns true: all GDate instances are immutable.
     */
    public final boolean isImmutable()
    {
        return true;
    }

    /**
     * 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 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; }

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

    /**
     * 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()
    {
        ensureCanonicalString();
        return _canonicalString;
    }

    /**
     * True if this GDate corresponds to a valid gregorian date value
     * in XML schema.
     */
    public boolean isValid()
    {
        return GDateBuilder.isValidGDate(this);
    }

    /**
     * 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 int getJulianDate()
    {
        return GDateBuilder.julianDateForGDate(this);
    }

    /**
     * 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 GDateBuilder.dateForGDate(this);
    }

    /**
     * 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.
     */
    public int compareToGDate(GDateSpecification datespec)
    {
        return GDateBuilder.compareGDate(this, datespec);
    }

    /**
     * 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 int getBuiltinTypeCode()
    {
        return GDateBuilder.btcForFlags(_bits);
    }

    /**
     * Adds a duration to this GDate, and returns a new GDate.
     */
    public GDate add(GDurationSpecification duration)
    {
        GDateBuilder builder = new GDateBuilder(this);
        builder.addGDuration(duration);
        return builder.toGDate();
    }

    /**
     * Adds a duration to this GDate, and returns a new GDate.
     */
    public GDate subtract(GDurationSpecification duration)
    {
        GDateBuilder builder = new GDateBuilder(this);
        builder.subtractGDuration(duration);
        return builder.toGDate();
    }

    /**
     * GDate is an immutable class, and equality is computed based
     * on its canonical value.
     */
    public boolean equals(Object obj)
    {
        if (obj == this)
            return true;
        if (!(obj instanceof GDate))
            return false;

        ensureCanonicalString();
        return _canonicalString.equals(((GDate)obj).canonicalString());
    }

    /**
     * Returns a hash code for this GDate.
     */
    public int hashCode()
    {
        ensureCanonicalString();
        return _canonicalString.hashCode();
    }

    /**
     * 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.
     */
    private void ensureCanonicalString()
    {
        if (_canonicalString != null)
            return;

        boolean needNormalize =
            (hasTimeZone() && getTimeZoneSign() != 0 && hasTime() &&
            ((hasDay() == hasMonth() && hasDay() == hasYear())));

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

        if (!needNormalize)
            _canonicalString = toString();
        else
        {
            GDateBuilder gdb = new GDateBuilder(this);
            gdb.normalize();
            _canonicalString = gdb.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 String toString()
    {
        if (_string == null)
            _string = formatGDate(this);
        return _string;
    }

    private final static char[] _tensDigit =
    {
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
        '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
        '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
        '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
        '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
        '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
        '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
        '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
        '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
    };
    private final static char[] _onesDigit =
    {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    };

    private static final int _padTwoAppend(char[] b, int i, int n)
    {
        assert(n >= 0 && n < 100);
        b[i] = _tensDigit[n];
        b[i + 1] = _onesDigit[n];
        return i + 2;
    }

    private static final int _padFourAppend(char[] b, int i, int n)
    {
        if (n < 0)
        {
            b[i++] = '-';
            n = -n;
        }
        if (n >= 10000)
        {
            String s = Integer.toString(n);
            s.getChars(0, s.length(), b, i);
            return i + s.length();
        }
        int q = n / 100;
        int r = n - q * 100;
        b[i] = _tensDigit[q];
        b[i + 1] = _onesDigit[q];
        b[i + 2] = _tensDigit[r];
        b[i + 3] = _onesDigit[r];
        return i + 4;
    }
    
    private static final TimeZone GMTZONE = TimeZone.getTimeZone("GMT");
    private static final TimeZone[] MINUSZONE =
            {
                TimeZone.getTimeZone("GMT-00:00"),
                TimeZone.getTimeZone("GMT-01:00"),
                TimeZone.getTimeZone("GMT-02:00"),
                TimeZone.getTimeZone("GMT-03:00"),
                TimeZone.getTimeZone("GMT-04:00"),
                TimeZone.getTimeZone("GMT-05:00"),
                TimeZone.getTimeZone("GMT-06:00"),
                TimeZone.getTimeZone("GMT-07:00"),
                TimeZone.getTimeZone("GMT-08:00"),
                TimeZone.getTimeZone("GMT-09:00"),
                TimeZone.getTimeZone("GMT-10:00"),
                TimeZone.getTimeZone("GMT-11:00"),
                TimeZone.getTimeZone("GMT-12:00"),
                TimeZone.getTimeZone("GMT-13:00"),
                TimeZone.getTimeZone("GMT-14:00"),
            };
    private static final TimeZone[] PLUSZONE =
            {
                TimeZone.getTimeZone("GMT+00:00"),
                TimeZone.getTimeZone("GMT+01:00"),
                TimeZone.getTimeZone("GMT+02:00"),
                TimeZone.getTimeZone("GMT+03:00"),
                TimeZone.getTimeZone("GMT+04:00"),
                TimeZone.getTimeZone("GMT+05:00"),
                TimeZone.getTimeZone("GMT+06:00"),
                TimeZone.getTimeZone("GMT+07:00"),
                TimeZone.getTimeZone("GMT+08:00"),
                TimeZone.getTimeZone("GMT+09:00"),
                TimeZone.getTimeZone("GMT+10:00"),
                TimeZone.getTimeZone("GMT+11:00"),
                TimeZone.getTimeZone("GMT+12:00"),
                TimeZone.getTimeZone("GMT+13:00"),
                TimeZone.getTimeZone("GMT+14:00"),
            };

    /* package */ static final TimeZone timeZoneForGDate(GDateSpecification date)
    {
        // use a cached timezone if integral; otherwise make a new one.
        if (!date.hasTimeZone())
            return TimeZone.getDefault();
        if (date.getTimeZoneSign() == 0)
            return GMTZONE;
        if (date.getTimeZoneMinute() == 0 && date.getTimeZoneHour() <= 14 && date.getTimeZoneHour() >= 0)
            return date.getTimeZoneSign() < 0 ? MINUSZONE[date.getTimeZoneHour()] : PLUSZONE[date.getTimeZoneHour()];
        
        char[] zb = new char[9];
        zb[0] = 'G';
        zb[1] = 'M';
        zb[2] = 'T';
        zb[3] = (date.getTimeZoneSign() < 0) ? '-' : '+';
        GDate._padTwoAppend(zb, 4, date.getTimeZoneHour());
        zb[6] = ':';
        GDate._padTwoAppend(zb, 7, date.getTimeZoneMinute());
        return TimeZone.getTimeZone(new String(zb));
    }
    
    /* package */ static String formatGDate(GDateSpecification spec)
    {
        // We've used a char[] rather than a StringBuffer for a 4x speedup
        // -YY(10)YY-MM-DDTHH:MM:SS.FFFFFF+ZH:ZM
        // 1 + 10   + 3+ 3+ 3+ 3+ 3+1 + s + 3+ 3 = 33 + s
        BigDecimal fs = spec.getFraction();
        char[] message = new char[33 + (fs == null ? 0 : fs.scale())];
        int i = 0;

        if (spec.hasYear() || spec.hasMonth() || spec.hasDay())
        {
            dmy: {
                if (spec.hasYear())
                    i = _padFourAppend(message, 0, spec.getYear());
                else
                    message[i++] = '-';

                if (!(spec.hasMonth() || spec.hasDay()))
                    break dmy;

                message[i++] = '-';
                if (spec.hasMonth())
                    i = _padTwoAppend(message, i, spec.getMonth());

                if (!spec.hasDay())
                    break dmy;

                message[i++] = '-';
                i = _padTwoAppend(message, i, spec.getDay());
                break dmy;
            }
            if (spec.hasTime())
                message[i++] = 'T';
        }

        if (spec.hasTime())
        {
            i = _padTwoAppend(message, i, spec.getHour());
            message[i++] = ':';
            i = _padTwoAppend(message, i, spec.getMinute());
            message[i++] = ':';
            i = _padTwoAppend(message, i, spec.getSecond());
            if (fs != _zero) // (optimization ~3%)
            {
                String frac = spec.getFraction().toString();
                int point = frac.indexOf('.');
                if (point >= 0)
                {
                    frac.getChars(point, frac.length(), message, i);
                    i += frac.length() - point;
                }
            }
        }

        if (spec.hasTimeZone())
        {
            if (spec.getTimeZoneSign() == 0)
            {
                message[i++] = 'Z';
            }
            else
            {
                message[i++] = spec.getTimeZoneSign() > 0 ? '+' : '-';
                i = _padTwoAppend(message, i, spec.getTimeZoneHour());
                message[i++] = ':';
                i = _padTwoAppend(message, i, spec.getTimeZoneMinute());
            }
        }

        // it would be nice to use (0, i, message) ctor instead
        return new String(message, 0, i);
    }

}

