/*
 * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.org.apache.xerces.internal.jaxp.datatype;

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

import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import com.sun.org.apache.xerces.internal.util.DatatypeMessageFormatter;
import com.sun.org.apache.xerces.internal.utils.SecuritySupport;

/**
 * <p>Representation for W3C XML Schema 1.0 date/time datatypes.
 * Specifically, these date/time datatypes are
 * {@link DatatypeConstants#DATETIME dateTime},
 * {@link DatatypeConstants#TIME time},
 * {@link DatatypeConstants#DATE date},
 * {@link DatatypeConstants#GYEARMONTH gYearMonth},
 * {@link DatatypeConstants#GMONTHDAY gMonthDay},
 * {@link DatatypeConstants#GYEAR gYear},
 * {@link DatatypeConstants#GMONTH gMonth} and
 * {@link DatatypeConstants#GDAY gDay}
 * defined in the XML Namespace
 * <code>"http://www.w3.org/2001/XMLSchema"</code>.
 * These datatypes are normatively defined in
 * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">W3C XML Schema 1.0 Part 2, Section 3.2.7-14</a>.</p>
 *
 * <p>The table below defines the mapping between XML Schema 1.0
 * date/time datatype fields and this class' fields. It also summarizes
 * the value constraints for the date and time fields defined in
 * <a href="http://www.w3.org/TR/xmlschema-2/#isoformats">W3C XML Schema 1.0 Part 2, Appendix D,
 * <i>ISO 8601 Date and Time Formats</i></a>.</p>
 *
 * <a name="datetimefieldsmapping"/>
 * <table border="2" rules="all" cellpadding="2">
 *   <thead>
 *     <tr>
 *       <th align="center" colspan="3">
 *         Date/time datatype field mapping between XML Schema 1.0 and Java representation
 *       </th>
 *     </tr>
 *   </thead>
 *   <tbody>
 *     <tr>
 *       <th>XML Schema 1.0<br/>
 *           datatype<br/>
 *            field</th>
 *       <th>Related<br/>XMLGregorianCalendar<br/>Accessor(s)</th>
 *       <th>Value Range</th>
 *     </tr>
 *     <a name="datetimefield-year"/>
 *     <tr>
 *       <td> year </td>
 *       <td> {@link #getYear()} + {@link #getEon()} or<br/>
 *            {@link #getEonAndYear}
 *       </td>
 *       <td> <code>getYear()</code> is a value between -(10^9-1) to (10^9)-1
 *            or {@link DatatypeConstants#FIELD_UNDEFINED}.<br/>
 *            {@link #getEon()} is high order year value in billion of years.<br/>
 *            <code>getEon()</code> has values greater than or equal to (10^9) or less than or equal to -(10^9).
 *            A value of null indicates field is undefined.</br>
 *            Given that <a href="http://www.w3.org/2001/05/xmlschema-errata#e2-63">XML Schema 1.0 errata</a> states that the year zero
 *            will be a valid lexical value in a future version of XML Schema,
 *            this class allows the year field to be set to zero. Otherwise,
 *            the year field value is handled exactly as described
 *            in the errata and [ISO-8601-1988]. Note that W3C XML Schema 1.0
 *            validation does not allow for the year field to have a value of zero.
 *            </td>
 *     </tr>
 *     <a name="datetimefield-month"/>
 *     <tr>
 *       <td> month </td>
 *       <td> {@link #getMonth()} </td>
 *       <td> 1 to 12 or {@link DatatypeConstants#FIELD_UNDEFINED} </td>
 *     </tr>
 *     <a name="datetimefield-day"/>
 *     <tr>
 *       <td> day </td>
 *       <td> {@link #getDay()} </td>
 *       <td> Independent of month, max range is 1 to 31 or {@link DatatypeConstants#FIELD_UNDEFINED}.<br/>
 *            The normative value constraint stated relative to month
 *            field's value is in <a href="http://www.w3.org/TR/xmlschema-2/#isoformats">W3C XML Schema 1.0 Part 2, Appendix D</a>.
 *       </td>
 *     </tr>
 *     <a name="datetimefield-hour"/>
 *     <tr>
 *       <td> hour </td>
 *       <td> {@link #getHour()} </td>
 *       <td>
 *         0 to 23 or {@link DatatypeConstants#FIELD_UNDEFINED}.
 *         An hour value of 24 is allowed to be set in the lexical space provided the minute and second
 *         field values are zero. However, an hour value of 24 is not allowed in value space and will be
 *         transformed to represent the value of the first instance of the following day as per
 *         <a href="http://www.w3.org/TR/xmlschema-2/#built-in-primitive-datatypes">
 *         XML Schema Part 2: Datatypes Second Edition, 3.2 Primitive datatypes</a>.
 *       </td>
 *     </tr>
 *     <a name="datetimefield-minute"/>
 *     <tr>
 *       <td> minute </td>
 *       <td> {@link #getMinute()} </td>
 *       <td> 0 to 59 or {@link DatatypeConstants#FIELD_UNDEFINED} </td>
 *     </tr>
 *     <a name="datetimefield-second"/>
 *     <tr>
 *       <td>second</td>
 *       <td>
 *         {@link #getSecond()} + {@link #getMillisecond()}/1000 or<br/>
 *         {@link #getSecond()} + {@link #getFractionalSecond()}
 *       </td>
 *       <td>
 *         {@link #getSecond()} from 0 to 60 or {@link DatatypeConstants#FIELD_UNDEFINED}.<br/>
 *         <i>(Note: 60 only allowable for leap second.)</i><br/>
 *         {@link #getFractionalSecond()} allows for infinite precision over the range from 0.0 to 1.0 when
 *         the {@link #getSecond()} is defined.<br/>
 *         <code>FractionalSecond</code> is optional and has a value of <code>null</code> when it is undefined.<br />
 *            {@link #getMillisecond()} is the convenience
 *            millisecond precision of value of {@link #getFractionalSecond()}.
 *       </td>
 *     </tr>
 *     <tr id="datetimefield-timezone">
 *       <td> timezone </td>
 *       <td> {@link #getTimezone()} </td>
 *       <td> Number of minutes or {@link DatatypeConstants#FIELD_UNDEFINED}.
 *         Value range from -14 hours (-14 * 60 minutes) to 14 hours (14 * 60 minutes).
 *       </td>
 *     </tr>
 *   </tbody>
 *  </table>
 *
 * <p>All maximum value space constraints listed for the fields in the table
 * above are checked by factory methods, setter methods and parse methods of
 * this class. <code>IllegalArgumentException</code> is thrown when
 * parameter's value is outside the maximum value constraint for the field.
 * Validation checks, for example, whether days in month should be
 * limited to 29, 30 or 31 days, that are dependent on the values of other
 * fields are not checked by these methods.
 * </p>
 *
 * <p>The following operations are defined for this class:
 * <ul>
 *   <li>factory methods to create instances</li>
 *   <li>accessors/mutators for independent date/time fields</li>
 *   <li>conversion between this class and W3C XML Schema 1.0 lexical representation</li>
 *   <li>conversion between this class and <code>java.util.GregorianCalendar</code></li>
 *   <li>partial order relation comparator method, {@link #compare(XMLGregorianCalendar)}</li>
 *   <li>{@link #equals(Object)} defined relative to {@link #compare(XMLGregorianCalendar)}.</li>
 *   <li> addition operation with {@link javax.xml.datatype.Duration}.
 * instance as defined in <a href="http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes">
 * W3C XML Schema 1.0 Part 2, Appendix E, <i>Adding durations to dateTimes</i></a>.</li>
 * </ul>
 * </p>
 *
 * @author <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a>
 * @author <a href="mailto:Joseph.Fialli@Sun.com">Joseph Fialli</a>
 * @author <a href="mailto:Sunitha.Reddy@Sun.com">Sunitha Reddy</a>
 * @version $Revision: 1.14 $, $Date: 2010-11-10 07:41:41 $
 * @see javax.xml.datatype.Duration
 * @since 1.5
 */

public class XMLGregorianCalendarImpl
        extends XMLGregorianCalendar
        implements Serializable, Cloneable {

    /**
     * <p>Eon of this <code>XMLGregorianCalendar</code>.</p>
     */
    private BigInteger eon = null;

    /**
     * <p>Year of this <code>XMLGregorianCalendar</code>.</p>
     */
    private int year = DatatypeConstants.FIELD_UNDEFINED;

    /**
     * <p>Month of this <code>XMLGregorianCalendar</code>.</p>
     */
    private int month = DatatypeConstants.FIELD_UNDEFINED;

    /**
     * <p>Day of this <code>XMLGregorianCalendar</code>.</p>
     */
    private int day = DatatypeConstants.FIELD_UNDEFINED;

    /**
     * <p>Timezone of this <code>XMLGregorianCalendar</code> in minutes.</p>
     */
    private int timezone = DatatypeConstants.FIELD_UNDEFINED;

    /**
     * <p>Hour of this <code>XMLGregorianCalendar</code>.</p>
     */
    private int hour = DatatypeConstants.FIELD_UNDEFINED;

    /**
     * <p>Minute of this <code>XMLGregorianCalendar</code>.</p>
     */
    private int minute = DatatypeConstants.FIELD_UNDEFINED;

    /**
     * <p>Second of this <code>XMLGregorianCalendar</code>.</p>
     */
    private int second = DatatypeConstants.FIELD_UNDEFINED ;

    /**
     * <p>Fractional second of this <code>XMLGregorianCalendar</code>.</p>
     */
    private BigDecimal fractionalSecond = null;

    /**
     * <p>Constant to represent a billion.</p>
     */
    private static final BigInteger BILLION = new BigInteger("1000000000");

    /**
     *   <p>Obtain a pure Gregorian Calendar by calling
     *   GregorianCalendar.setChange(PURE_GREGORIAN_CHANGE). </p>
     */
    private static final Date PURE_GREGORIAN_CHANGE =
        new Date(Long.MIN_VALUE);

    /**
     * Year index for MIN_ and MAX_FIELD_VALUES.
     */
    private static final int YEAR   = 0;

    /**
     * Month index for MIN_ and MAX_FIELD_VALUES.
     */
    private static final int MONTH  = 1;

    /**
     * Day index for MIN_ and MAX_FIELD_VALUES.
     */
    private static final int DAY    = 2;

    /**
     * Hour index for MIN_ and MAX_FIELD_VALUES.
     */
    private static final int HOUR   = 3;

    /**
     * Minute index for MIN_ and MAX_FIELD_VALUES.
     */
    private static final int MINUTE = 4;

    /**
     * Second index for MIN_ and MAX_FIELD_VALUES.
     */
    private static final int SECOND = 5;

    /**
     * Second index for MIN_ and MAX_FIELD_VALUES.
     */
    private static final int MILLISECOND = 6;

    /**
     * Timezone index for MIN_ and MAX_FIELD_VALUES
     */
    private static final int TIMEZONE = 7;


    /**
     * field names indexed by YEAR..TIMEZONE.
     */
    private static final String FIELD_NAME[] = {
        "Year",
        "Month",
        "Day",
        "Hour",
        "Minute",
        "Second",
        "Millisecond",
        "Timezone"
    };

    /**
     * <p>Stream Unique Identifier.</p>
     *
     * <p>TODO: Serialization should use the XML string representation as
     * the serialization format to ensure future compatibility.</p>
     */
    private static final long serialVersionUID = 1L;

    /**
     * <p>Use as a template for default field values when
     * converting to a {@link GregorianCalendar}, set to a leap
     * year date of January 1, 0400 at midnight.</p>
     *
     * <p>Fields that are optional for an <code>xsd:dateTime</code> instances are defaulted to not being set to any value.
     * <code>XMLGregorianCalendar</code> fields millisecond, fractional second and timezone return the value indicating
     * that the field is not set, {@link DatatypeConstants#FIELD_UNDEFINED} for millisecond and timezone
     * and <code>null</code> for fractional second.</p>
     *
     * @see #toGregorianCalendar(TimeZone, Locale, XMLGregorianCalendar)
     */
    public static final XMLGregorianCalendar LEAP_YEAR_DEFAULT =
                createDateTime(
                        400,  //year
                DatatypeConstants.JANUARY,  //month
                        1,  // day
                    0,  // hour
                    0,  // minute
                    0,  // second
                    DatatypeConstants.FIELD_UNDEFINED,  // milliseconds
                    DatatypeConstants.FIELD_UNDEFINED // timezone
                );

    // Constructors

    /**
     * Constructs a new XMLGregorianCalendar object.
     *
     * String parsing documented by {@link #parse(String)}.
     *
     * Returns a non-null valid XMLGregorianCalendar object that holds the
     * value indicated by the lexicalRepresentation parameter.
     *
     * @param lexicalRepresentation
     *      Lexical representation of one the eight
     *      XML Schema date/time datatypes.
     * @throws IllegalArgumentException
     *      If the given string does not conform as documented in
     *      {@link #parse(String)}.
     * @throws NullPointerException
     *      If the given string is null.
     */
    protected XMLGregorianCalendarImpl(String lexicalRepresentation)
            throws IllegalArgumentException {

        // compute format string for this lexical representation.
        String format = null;
        String lexRep = lexicalRepresentation;
        final int NOT_FOUND = -1;
        int lexRepLength = lexRep.length();

        // current parser needs a format string,
        // use following heuristics to figure out what xml schema date/time
        // datatype this lexical string could represent.
        // Fix 4971612: invalid SCCS macro substitution in data string,
        //   no %{alpha}% to avoid SCCS maco substitution
        if (lexRep.indexOf('T') != NOT_FOUND) {
            // found Date Time separater, must be xsd:DateTime
            format = "%Y-%M-%DT%h:%m:%s" + "%z";
        } else if (lexRepLength >= 3 && lexRep.charAt(2) == ':') {
            // found ":", must be xsd:Time
            format = "%h:%m:%s" + "%z";
        } else if (lexRep.startsWith("--")) {
            // check for gDay || gMonth || gMonthDay
            if (lexRepLength >= 3 && lexRep.charAt(2) == '-') {
                // gDay, ---DD(z?)
                format = "---%D" + "%z";
            } else if (lexRepLength == 4     // --MM
                    || lexRepLength == 5     // --MMZ
                    || lexRepLength == 10) { // --MMSHH:MM
                // gMonth, --MM(z?),
                // per XML Schema Errata, used to be --MM--(z?)
                format = "--%M" + "%z";
            } else {
                // gMonthDay, --MM-DD(z?), (or invalid lexicalRepresentation)
                // length should be:
                //  7: --MM-DD
                //  8: --MM-DDZ
                // 13: --MM-DDSHH:MM
                format = "--%M-%D" + "%z";
            }
        } else {
            // check for Date || GYear | GYearMonth
            int countSeparator = 0;

            // start at index 1 to skip potential negative sign for year.


            int timezoneOffset = lexRep.indexOf(':');
            if (timezoneOffset != NOT_FOUND) {

                // found timezone, strip it off for distinguishing
                // between Date, GYear and GYearMonth so possible
                // negative sign in timezone is not mistaken as
                // a separator.
                lexRepLength -= 6;
            }

            for (int i = 1; i < lexRepLength; i++) {
                if (lexRep.charAt(i) == '-') {
                    countSeparator++;
                }
            }
            if (countSeparator == 0) {
                // GYear
                format = "%Y" + "%z";
            } else if (countSeparator == 1) {
                // GYearMonth
                format = "%Y-%M" + "%z";
            } else {
                // Date or invalid lexicalRepresentation
                // Fix 4971612: invalid SCCS macro substitution in data string
                format = "%Y-%M-%D" + "%z";
            }
        }
        Parser p = new Parser(format, lexRep);
        p.parse();

        // check for validity
        if (!isValid()) {
            throw new IllegalArgumentException(
                    DatatypeMessageFormatter.formatMessage(null, "InvalidXGCRepresentation", new Object[]{lexicalRepresentation})
                    //"\"" + lexicalRepresentation + "\" is not a valid representation of an XML Gregorian Calendar value."
            );
        }
    }

    /**
     * <p>Create an instance with all date/time datatype fields set to
     * {@link DatatypeConstants#FIELD_UNDEFINED} or null respectively.</p>
     */
    public XMLGregorianCalendarImpl() {

        // field initializers already do the correct initialization.
    }

    /**
     * <p>Private constructor allowing for complete value spaces allowed by
     * W3C XML Schema 1.0 recommendation for xsd:dateTime and related
     * builtin datatypes. Note that <code>year</code> parameter supports
     * arbitrarily large numbers and fractionalSecond has infinite
     * precision.</p>
     *
     * @param year of <code>XMLGregorianCalendar</code> to be created.
     * @param month of <code>XMLGregorianCalendar</code> to be created.
     * @param day of <code>XMLGregorianCalendar</code> to be created.
     * @param hour of <code>XMLGregorianCalendar</code> to be created.
     * @param minute of <code>XMLGregorianCalendar</code> to be created.
     * @param second of <code>XMLGregorianCalendar</code> to be created.
     * @param fractionalSecond of <code>XMLGregorianCalendar</code> to be created.
     * @param timezone of <code>XMLGregorianCalendar</code> to be created.
     *
     */
    protected XMLGregorianCalendarImpl(
        BigInteger year,
        int month,
        int day,
        int hour,
        int minute,
        int second,
        BigDecimal fractionalSecond,
        int timezone) {

                setYear(year);
        setMonth(month);
        setDay(day);
        setTime(hour, minute, second, fractionalSecond);
                setTimezone(timezone);

                // check for validity
                if (!isValid()) {

            throw new IllegalArgumentException(
                DatatypeMessageFormatter.formatMessage(null,
                    "InvalidXGCValue-fractional",
                    new Object[] { year, new Integer(month), new Integer(day),
                    new Integer(hour), new Integer(minute), new Integer(second),
                    fractionalSecond, new Integer(timezone)})
                        );

                        /**
                String yearString = "null";
                if (year != null) {
                    yearString = year.toString();
                }
                String fractionalSecondString = "null";
                if (fractionalSecond != null) {
                    fractionalSecondString = fractionalSecond.toString();
                }

                throw new IllegalArgumentException(
                    "year = " + yearString
                    + ", month = " + month
                    + ", day = " + day
                    + ", hour = " + hour
                    + ", minute = " + minute
                    + ", second = " + second
                    + ", fractionalSecond = " + fractionalSecondString
                    + ", timezone = " + timezone
                    + ", is not a valid representation of an XML Gregorian Calendar value."
                );
                */

                }

    }

    /**
     * <p>Private constructor of value spaces that a
     * <code>java.util.GregorianCalendar</code> instance would need to convert to an
     * <code>XMLGregorianCalendar</code> instance.</p>
     *
     * <p><code>XMLGregorianCalendar eon</code> and
     * <code>fractionalSecond</code> are set to <code>null</code></p>
     *
     * @param year of <code>XMLGregorianCalendar</code> to be created.
     * @param month of <code>XMLGregorianCalendar</code> to be created.
     * @param day of <code>XMLGregorianCalendar</code> to be created.
     * @param hour of <code>XMLGregorianCalendar</code> to be created.
     * @param minute of <code>XMLGregorianCalendar</code> to be created.
     * @param second of <code>XMLGregorianCalendar</code> to be created.
     * @param millisecond of <code>XMLGregorianCalendar</code> to be created.
     * @param timezone of <code>XMLGregorianCalendar</code> to be created.
     */
    private XMLGregorianCalendarImpl(
        int year,
        int month,
        int day,
        int hour,
        int minute,
        int second,
                int millisecond,
        int timezone) {

                setYear(year);
        setMonth(month);
        setDay(day);
        setTime(hour, minute, second);
                setTimezone(timezone);
                setMillisecond(millisecond);

                if (!isValid()) {

            throw new IllegalArgumentException(
                DatatypeMessageFormatter.formatMessage(null,
                "InvalidXGCValue-milli",
                new Object[] { new Integer(year), new Integer(month), new Integer(day),
                new Integer(hour), new Integer(minute), new Integer(second),
                new Integer(millisecond), new Integer(timezone)})
                        );
                /*
                throw new IllegalArgumentException(
                    "year = " + year
                    + ", month = " + month
                    + ", day = " + day
                    + ", hour = " + hour
                    + ", minute = " + minute
                    + ", second = " + second
                    + ", millisecond = " + millisecond
                    + ", timezone = " + timezone
                    + ", is not a valid representation of an XML Gregorian Calendar value."
                    );
                 */

                }
    }

        /**
         * <p>Convert a <code>java.util.GregorianCalendar</code> to XML Schema 1.0
         * representation.</p>
         *
         * <table border="2" rules="all" cellpadding="2">
         *   <thead>
         *     <tr>
         *       <th align="center" colspan="2">
         *          Field by Field Conversion from
         *          <code>java.util.GregorianCalendar</code> to this class
         *       </th>
         *     </tr>
         *   </thead>
         *   <tbody>
         *     <tr>
         *        <th><code>javax.xml.datatype.XMLGregorianCalendar</code> field</th>
         *        <th><code>java.util.GregorianCalendar</code> field</th>
         *     </tr>
         *     <tr>
         *       <th>{@link #setYear(int)}</th>
         *       <th><code>ERA == GregorianCalendar.BC ? -YEAR : YEAR</code></th>
         *     </tr>
         *     <tr>
         *       <th>{@link #setMonth(int)}</th>
         *       <th><code>MONTH + 1</code></th>
         *     </tr>
         *     <tr>
         *       <th>{@link #setDay(int)}</th>
         *       <th><code>DAY_OF_MONTH</code></th>
         *     </tr>
         *     <tr>
         *       <th>{@link #setTime(int,int,int, BigDecimal)}</th>
         *       <th><code>HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND</code></th>
         *     </tr>
         *     <tr>
         *       <th>{@link #setTimezone(int)}<i>*</i></th>
         *       <th><code>(ZONE_OFFSET + DST_OFFSET) / (60*1000)</code><br/>
         *       <i>(in minutes)</i>
         *       </th>
         *     </tr>
         *   </tbody>
         * </table>
         * <p><i>*</i>conversion loss of information. It is not possible to represent
         * a <code>java.util.GregorianCalendar</code> daylight savings timezone id in the
         * XML Schema 1.0 date/time datatype representation.</p>
         *
         * <p>To compute the return value's <code>TimeZone</code> field,
         * <ul>
         * <li>when <code>this.getTimezone() != DatatypeConstants.FIELD_UNDEFINED</code>,
         * create a <code>java.util.TimeZone</code> with a custom timezone id
         * using the <code>this.getTimezone()</code>.</li>
         * <li>else use the <code>GregorianCalendar</code> default timezone value
         * for the host is defined as specified by
         * <code>java.util.TimeZone.getDefault()</code>.</li></p>
         *
         * @param cal <code>java.util.GregorianCalendar</code> used to create <code>XMLGregorianCalendar</code>
         */
    public XMLGregorianCalendarImpl(GregorianCalendar cal) {

        int year = cal.get(Calendar.YEAR);
        if (cal.get(Calendar.ERA) == GregorianCalendar.BC) {
            year = -year;
        }
        this.setYear(year);

        // Calendar.MONTH is zero based, XSD Date datatype's month field starts
        // with JANUARY as 1.
        this.setMonth(cal.get(Calendar.MONTH) + 1);
        this.setDay(cal.get(Calendar.DAY_OF_MONTH));
        this.setTime(
                cal.get(Calendar.HOUR_OF_DAY),
                cal.get(Calendar.MINUTE),
                cal.get(Calendar.SECOND),
                cal.get(Calendar.MILLISECOND));

        // Calendar ZONE_OFFSET and DST_OFFSET fields are in milliseconds.
        int offsetInMinutes = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / (60 * 1000);
        this.setTimezone(offsetInMinutes);
    }

    // Factories

    /**
     * <p>Create a Java representation of XML Schema builtin datatype <code>dateTime</code>.
     * All possible fields are specified for this factory method.</p>
     *
     * @param year represents both high-order eons and low-order year.
     * @param month of <code>dateTime</code>
     * @param day of <code>dateTime</code>
     * @param hours of <code>dateTime</code>
     * @param minutes of <code>dateTime</code>
     * @param seconds of <code>dateTime</code>
     * @param fractionalSecond value of null indicates optional field is absent.
     * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
     *
     * @return <code>XMLGregorianCalendar</code> created from parameter values.
     *
     * @see DatatypeConstants#FIELD_UNDEFINED
     *
     * @throws IllegalArgumentException if any parameter is outside value
     * constraints for the field as specified in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
     */
    public static XMLGregorianCalendar createDateTime(
        BigInteger year,
        int month,
        int day,
        int hours,
        int minutes,
        int seconds,
        BigDecimal fractionalSecond,
        int timezone) {

        return new XMLGregorianCalendarImpl(
            year,
            month,
            day,
            hours,
            minutes,
            seconds,
            fractionalSecond,
            timezone);
    }

    /**
     * <p>Create a Java instance of XML Schema builtin datatype dateTime.</p>
     *
     * @param year represents both high-order eons and low-order year.
     * @param month of <code>dateTime</code>
     * @param day of <code>dateTime</code>
     * @param hour of <code>dateTime</code>
     * @param minute of <code>dateTime</code>
     * @param second of <code>dateTime</code>
     *
     * @return <code>XMLGregorianCalendar</code> created from parameter values.
     *
     * @throws IllegalArgumentException if any parameter is outside value constraints for the field as specified in
     *   <a href="#datetimefieldmapping">date/time field mapping table</a>.
     *
     * @see DatatypeConstants#FIELD_UNDEFINED
     */
    public static XMLGregorianCalendar createDateTime(
        int year,
        int month,
        int day,
        int hour,
        int minute,
        int second) {

        return new XMLGregorianCalendarImpl(
            year,
            month,
            day,
            hour,
            minute,
            second,
            DatatypeConstants.FIELD_UNDEFINED,  //millisecond
                DatatypeConstants.FIELD_UNDEFINED //timezone
        );
    }

    /**
     * <p>Create a Java representation of XML Schema builtin datatype <code>dateTime</code>.
     * All possible fields are specified for this factory method.</p>
     *
     * @param year represents low-order year.
     * @param month of <code>dateTime</code>
     * @param day of <code>dateTime</code>
     * @param hours of <code>dateTime</code>
     * @param minutes of <code>dateTime</code>
     * @param seconds of <code>dateTime</code>
     * @param milliseconds of <code>dateTime</code>. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
     * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
     *
     * @return <code>XMLGregorianCalendar</code> created from parameter values.
     *
     * @throws IllegalArgumentException if any parameter is outside value constraints for the field as specified in
     *   <a href="#datetimefieldmapping">date/time field mapping table</a>.
     *
     * @see DatatypeConstants#FIELD_UNDEFINED
     */
    public static XMLGregorianCalendar createDateTime(
        int year,
        int month,
        int day,
        int hours,
        int minutes,
        int seconds,
        int milliseconds,
        int timezone) {

        return new XMLGregorianCalendarImpl(
            year,
            month,
            day,
            hours,
            minutes,
            seconds,
            milliseconds,
            timezone);
    }

    /**
     * <p>Create a Java representation of XML Schema builtin datatype <code>date</code> or <code>g*</code>.</p>
     *
     * <p>For example, an instance of <code>gYear</code> can be created invoking this factory
     * with <code>month</code> and <code>day</code> parameters set to
     * {@link DatatypeConstants#FIELD_UNDEFINED}.</p>
     *
     * @param year of <code>XMLGregorianCalendar</code> to be created.
     * @param month of <code>XMLGregorianCalendar</code> to be created.
     * @param day of <code>XMLGregorianCalendar</code> to be created.
     * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
     *
     * @return <code>XMLGregorianCalendar</code> created from parameter values.
     *
     * @see DatatypeConstants#FIELD_UNDEFINED
     *
     * @throws IllegalArgumentException if any parameter is outside value
     * constraints for the field as specified in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
     */
    public static XMLGregorianCalendar createDate(
        int year,
        int month,
        int day,
        int timezone) {

        return new XMLGregorianCalendarImpl(
            year,
            month,
            day,
            DatatypeConstants.FIELD_UNDEFINED, // hour
            DatatypeConstants.FIELD_UNDEFINED, // minute
            DatatypeConstants.FIELD_UNDEFINED, // second
                DatatypeConstants.FIELD_UNDEFINED, // millisecond
            timezone);
    }

    /**
     * Create a Java instance of XML Schema builtin datatype <code>time</code>.
     * @param hours number of hours
     * @param minutes number of minutes
     * @param seconds number of seconds
     * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
     *
     * @return <code>XMLGregorianCalendar</code> created from parameter values.
     *
     * @see DatatypeConstants#FIELD_UNDEFINED
     *
     * @throws IllegalArgumentException if any parameter is outside value
     * constraints for the field as specified in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
     */
    public static XMLGregorianCalendar createTime(
        int hours,
        int minutes,
        int seconds,
                int timezone) {

                return new XMLGregorianCalendarImpl(
                        DatatypeConstants.FIELD_UNDEFINED, // Year
                        DatatypeConstants.FIELD_UNDEFINED, // Month
                        DatatypeConstants.FIELD_UNDEFINED, // Day
                        hours,
                        minutes,
                        seconds,
                        DatatypeConstants.FIELD_UNDEFINED, //Millisecond
                        timezone);
    }

    /**
     * <p>Create a Java instance of XML Schema builtin datatype time.</p>
     *
     * @param hours number of hours
     * @param minutes number of minutes
     * @param seconds number of seconds
     * @param fractionalSecond value of <code>null</code> indicates that this optional field is not set.
     * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
     *
     * @return <code>XMLGregorianCalendar</code> created from parameter values.
     *
     * @see DatatypeConstants#FIELD_UNDEFINED
     *
     * @throws IllegalArgumentException if any parameter is outside value
     * constraints for the field as specified in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
     */
    public static XMLGregorianCalendar createTime(
        int hours,
        int minutes,
        int seconds,
        BigDecimal fractionalSecond,
        int timezone) {

        return new XMLGregorianCalendarImpl(
            null,            // Year
            DatatypeConstants.FIELD_UNDEFINED, // month
            DatatypeConstants.FIELD_UNDEFINED, // day
            hours,
            minutes,
            seconds,
            fractionalSecond,
            timezone);
    }

    /**
     * <p>Create a Java instance of XML Schema builtin datatype time.</p>
     *
     * @param hours number of hours
     * @param minutes number of minutes
     * @param seconds number of seconds
     * @param milliseconds number of milliseconds
     * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
     *
     * @return <code>XMLGregorianCalendar</code> created from parameter values.
     *
     * @see DatatypeConstants#FIELD_UNDEFINED
     *
     * @throws IllegalArgumentException if any parameter is outside value
     * constraints for the field as specified in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
     */
    public static XMLGregorianCalendar createTime(
        int hours,
        int minutes,
        int seconds,
        int milliseconds,
        int timezone) {

        return new XMLGregorianCalendarImpl(
                DatatypeConstants.FIELD_UNDEFINED, // year
                DatatypeConstants.FIELD_UNDEFINED, // month
                DatatypeConstants.FIELD_UNDEFINED, // day
                hours,
                minutes,
                seconds,
                milliseconds,
                timezone);
    }

    // Accessors

    /**
     * <p>Return high order component for XML Schema 1.0 dateTime datatype field for
     * <code>year</code>.
     * <code>null</code> if this optional part of the year field is not defined.</p>
     *
     * <p>Value constraints for this value are summarized in
     * <a href="#datetimefield-year">year field of date/time field mapping table</a>.</p>
     * @return eon of this <code>XMLGregorianCalendar</code>. The value
     * returned is an integer multiple of 10^9.
     *
     * @see #getYear()
     * @see #getEonAndYear()
     */
    public BigInteger getEon() {
           return eon;
    }

    /**
     * <p>Return low order component for XML Schema 1.0 dateTime datatype field for
     * <code>year</code> or {@link DatatypeConstants#FIELD_UNDEFINED}.</p>
     *
     * <p>Value constraints for this value are summarized in
     * <a href="#datetimefield-year">year field of date/time field mapping table</a>.</p>
     *
     * @return year  of this <code>XMLGregorianCalendar</code>.
     *
     * @see #getEon()
     * @see #getEonAndYear()
     */
    public int getYear() {
           return year;
    }

    /**
     * <p>Return XML Schema 1.0 dateTime datatype field for
     * <code>year</code>.</p>
     *
     * <p>Value constraints for this value are summarized in
     * <a href="#datetimefield-year">year field of date/time field mapping table</a>.</p>
     *
     * @return sum of <code>eon</code> and <code>BigInteger.valueOf(year)</code>
     * when both fields are defined. When only <code>year</code> is defined,
     * return it. When both <code>eon</code> and <code>year</code> are not
     * defined, return <code>null</code>.
     *
     * @see #getEon()
     * @see #getYear()
     */
    public BigInteger getEonAndYear() {

                // both are defined
                if (year != DatatypeConstants.FIELD_UNDEFINED
                        && eon != null) {

                        return eon.add(BigInteger.valueOf((long) year));
                }

                // only year is defined
                if (year != DatatypeConstants.FIELD_UNDEFINED
                        && eon == null) {

                        return BigInteger.valueOf((long) year);
                }

        // neither are defined
        // or only eon is defined which is not valid without a year
                return null;
    }

    /**
     * <p>Return number of month or {@link DatatypeConstants#FIELD_UNDEFINED}.</p>
     *
     * <p>Value constraints for this value are summarized in
     * <a href="#datetimefield-month">month field of date/time field mapping table</a>.</p>
     *
     * @return year  of this <code>XMLGregorianCalendar</code>.
     *
     */
    public int getMonth() {
        return month;
    }

    /**
     * Return day in month or {@link DatatypeConstants#FIELD_UNDEFINED}.</p>
     *
     * <p>Value constraints for this value are summarized in
     * <a href="#datetimefield-day">day field of date/time field mapping table</a>.</p>
     *
     * @see #setDay(int)
     */
    public int getDay() {
        return day;
    }

    /**
     * Return timezone offset in minutes or
     * {@link DatatypeConstants#FIELD_UNDEFINED} if this optional field is not defined.
     *
     * <p>Value constraints for this value are summarized in
     * <a href="#datetimefield-timezone">timezone field of date/time field mapping table</a>.</p>
     *
     * @see #setTimezone(int)
     */
    public int getTimezone() {
        return timezone;
    }

    /**
     * Return hours or {@link DatatypeConstants#FIELD_UNDEFINED}.
     * Returns {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined.
     *
     * <p>Value constraints for this value are summarized in
     * <a href="#datetimefield-hour">hour field of date/time field mapping table</a>.</p>
     * @see #setTime(int, int, int)
     */
    public int getHour() {
        return hour;
    }

    /**
     * Return minutes or {@link DatatypeConstants#FIELD_UNDEFINED}.<\p>
     * Returns {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined.
     *
     * <p>Value constraints for this value are summarized in
     * <a href="#datetimefield-minute">minute field of date/time field mapping table</a>.</p>
     * @see #setTime(int, int, int)
     */
    public int getMinute() {
        return minute;
    }

    /**
     * <p>Return seconds or {@link DatatypeConstants#FIELD_UNDEFINED}.<\p>
     *
     * <p>Returns {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined.
     * When this field is not defined, the optional xs:dateTime
     * fractional seconds field, represented by
     * {@link #getFractionalSecond()} and {@link #getMillisecond()},
     * must not be defined.</p>
     *
     * <p>Value constraints for this value are summarized in
     * <a href="#datetimefield-second">second field of date/time field mapping table</a>.</p>
     *
     * @return Second  of this <code>XMLGregorianCalendar</code>.
     *
     * @see #getFractionalSecond()
     * @see #getMillisecond()
     * @see #setTime(int, int, int)
     */
    public int getSecond() {
           return second;
    }

    /**
     * @return result of adding second and fractional second field
     */
    private BigDecimal getSeconds() {
        if (second == DatatypeConstants.FIELD_UNDEFINED) {
            return DECIMAL_ZERO;
        }
        BigDecimal result = BigDecimal.valueOf((long) second);
        if (fractionalSecond != null) {
            return result.add(fractionalSecond);
        } else {
            return result;
        }
    }


    /**
     * <p>Return millisecond precision of {@link #getFractionalSecond()}.<\p>
     *
     * <p>This method represents a convenience accessor to infinite
     * precision fractional second value returned by
     * {@link #getFractionalSecond()}. The returned value is the rounded
     * down to milliseconds value of
     * {@link #getFractionalSecond()}. When {@link #getFractionalSecond()}
     * returns <code>null</code>, this method must return
     * {@link DatatypeConstants#FIELD_UNDEFINED}.</p>
     *
     * <p>Value constraints for this value are summarized in
     * <a href="#datetimefield-second">second field of date/time field mapping table</a>.</p>
     *
     * @return Millisecond  of this <code>XMLGregorianCalendar</code>.
     *
     * @see #getFractionalSecond()
     * @see #setTime(int, int, int)
     */
    public int getMillisecond() {
        if (fractionalSecond == null) {
            return DatatypeConstants.FIELD_UNDEFINED;
        } else {
            // TODO: Non-optimal solution for now.
            // Efficient implementation would only store as BigDecimal
            // when needed and millisecond otherwise.
            return fractionalSecond.movePointRight(3).intValue();
        }
    }

    /**
     * <p>Return fractional seconds.</p>
     *
     * <p><code>null</code> is returned when this optional field is not defined.</p>
     *
     * <p>Value constraints are detailed in
     * <a href="#datetimefield-second">second field of date/time field mapping table</a>.</p>
     *
     * <p>This optional field can only have a defined value when the
     * xs:dateTime second field, represented by ({@link #getSecond()},
     * does not return {@link DatatypeConstants#FIELD_UNDEFINED}).</p>
     *
     * @return fractional seconds  of this <code>XMLGregorianCalendar</code>.
     *
     * @see #getSecond()
     * @see #setTime(int, int, int, BigDecimal)
     */
    public BigDecimal getFractionalSecond() {
           return fractionalSecond;
    }

    // setters

    /**
     * <p>Set low and high order component of XSD <code>dateTime</code> year field.</p>
     *
     * <p>Unset this field by invoking the setter with a parameter value of <code>null</code>.</p>
     *
     * @param year value constraints summarized in <a href="#datetimefield-year">year field of date/time field mapping table</a>.
     *
     * @throws IllegalArgumentException if <code>year</code> parameter is
     * outside value constraints for the field as specified in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
     */
    public void setYear(BigInteger year) {
        if (year == null) {
            this.eon = null;
            this.year = DatatypeConstants.FIELD_UNDEFINED;
        } else {
            BigInteger temp = year.remainder(BILLION);
            this.year = temp.intValue();
            setEon(year.subtract(temp));
        }
    }

    /**
     * <p>Set year of XSD <code>dateTime</code> year field.</p>
     *
     * <p>Unset this field by invoking the setter with a parameter value of
     * {@link DatatypeConstants#FIELD_UNDEFINED}.</p>
     *
     * <p>Note: if the absolute value of the <code>year</code> parameter
     * is less than 10^9, the eon component of the XSD year field is set to
     * <code>null</code> by this method.</p>
     *
     * @param year value constraints are summarized in <a href="#datetimefield-year">year field of date/time field mapping table</a>.
     *   If year is {@link DatatypeConstants#FIELD_UNDEFINED}, then eon is set to <code>null</code>.
     */
    public void setYear(int year) {
        if (year == DatatypeConstants.FIELD_UNDEFINED) {
            this.year = DatatypeConstants.FIELD_UNDEFINED;
            this.eon = null;
        } else if (Math.abs(year) < BILLION.intValue()) {
            this.year = year;
            this.eon = null;
        } else {
            BigInteger theYear = BigInteger.valueOf((long) year);
            BigInteger remainder = theYear.remainder(BILLION);
            this.year = remainder.intValue();
            setEon(theYear.subtract(remainder));
        }
    }

    /**
     * <p>Set high order part of XSD <code>dateTime</code> year field.</p>
     *
     * <p>Unset this field by invoking the setter with a parameter value of
     * <code>null</code>.</p>
     *
     * @param eon value constraints summarized in <a href="#datetimefield-year">year field of date/time field mapping table</a>.
     */
    private void setEon(BigInteger eon) {
        if (eon != null && eon.compareTo(BigInteger.ZERO) == 0) {
            // Treat ZERO as field being undefined.
            this.eon = null;
        } else {
            this.eon = eon;
        }
    }

    /**
     * <p>Set month.</p>
     *
     * <p>Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.</p>
     *
     * @param month value constraints summarized in <a href="#datetimefield-month">month field of date/time field mapping table</a>.
     *
     * @throws IllegalArgumentException if <code>month</code> parameter is
     * outside value constraints for the field as specified in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
     */
    public void setMonth(int month) {
        if(month<DatatypeConstants.JANUARY || DatatypeConstants.DECEMBER<month)
            if(month!=DatatypeConstants.FIELD_UNDEFINED)
                invalidFieldValue(MONTH, month);
        this.month = month;
    }

    /**
     * <p>Set days in month.</p>
     *
     * <p>Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.</p>
     *
     * @param day value constraints summarized in <a href="#datetimefield-day">day field of date/time field mapping table</a>.
     *
     * @throws IllegalArgumentException if <code>day</code> parameter is
     * outside value constraints for the field as specified in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
     */
    public void setDay(int day) {
        if(day<1 || 31<day)
            if(day!=DatatypeConstants.FIELD_UNDEFINED)
                invalidFieldValue(DAY,day);
        this.day = day;
    }

    /**
     * <p>Set the number of minutes in the timezone offset.</p>
     *
     * <p>Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.</p>
     *
     * @param offset value constraints summarized in <a href="#datetimefield-timezone">
     *   timezone field of date/time field mapping table</a>.
     *
     * @throws IllegalArgumentException if <code>offset</code> parameter is
     * outside value constraints for the field as specified in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
     */
    public void setTimezone(int offset) {
            if(offset<-14*60 || 14*60<offset)
            if(offset!=DatatypeConstants.FIELD_UNDEFINED)
                invalidFieldValue(TIMEZONE,offset);
        this.timezone = offset;
    }

    /**
     * <p>Set time as one unit.</p>
     *
     * @param hour value constraints are summarized in
     * <a href="#datetimefield-hour">hour field of date/time field mapping table</a>.
     * @param minute value constraints are summarized in
     * <a href="#datetimefield-minute">minute field of date/time field mapping table</a>.
     * @param second value constraints are summarized in
     * <a href="#datetimefield-second">second field of date/time field mapping table</a>.
     *
     * @see #setTime(int, int, int, BigDecimal)
     *
     * @throws IllegalArgumentException if any parameter is
     * outside value constraints for the field as specified in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
     */
    public void setTime(int hour, int minute, int second) {
        setTime(hour, minute, second, null);
    }

    private void invalidFieldValue(int field, int value) {
        throw new IllegalArgumentException(
            DatatypeMessageFormatter.formatMessage(null, "InvalidFieldValue",
                new Object[]{ new Integer(value), FIELD_NAME[field]})
        );
    }

    private void testHour() {

        // http://www.w3.org/2001/05/xmlschema-errata#e2-45
        if (getHour() == 24) {
            if (getMinute() != 0
                    || getSecond() != 0) {
                invalidFieldValue(HOUR, getHour());
            }
            // while 0-24 is acceptable in the lexical space, 24 is not valid in value space
            // W3C XML Schema Part 2, Section 3.2.7.1
            setHour(0, false);
            add(new DurationImpl(true, 0, 0, 1, 0, 0, 0));
        }
    }

    public void setHour(int hour) {

        setHour(hour, true);
    }

    private void setHour(int hour, boolean validate) {

        if (hour < 0 || hour > 24) {
            if (hour != DatatypeConstants.FIELD_UNDEFINED) {
                invalidFieldValue(HOUR, hour);
            }
        }

        this.hour = hour;

        if (validate) {
            testHour();
        }
    }

    public void setMinute(int minute) {
        if(minute<0 || 59<minute)
            if(minute!=DatatypeConstants.FIELD_UNDEFINED)
                invalidFieldValue(MINUTE, minute);
        this.minute = minute;
    }

    public void setSecond(int second) {
        if(second<0 || 60<second)   // leap second allows for 60
            if(second!=DatatypeConstants.FIELD_UNDEFINED)
                invalidFieldValue(SECOND, second);
        this.second  = second;
    }

    /**
     * <p>Set time as one unit, including the optional infinite precison
     * fractional seconds.</p>
     *
     * @param hour value constraints are summarized in
     * <a href="#datetimefield-hour">hour field of date/time field mapping table</a>.
     * @param minute value constraints are summarized in
     * <a href="#datetimefield-minute">minute field of date/time field mapping table</a>.
     * @param second value constraints are summarized in
     * <a href="#datetimefield-second">second field of date/time field mapping table</a>.
     * @param fractional value of <code>null</code> indicates this optional
     *                   field is not set.
     *
     * @throws IllegalArgumentException if any parameter is
     * outside value constraints for the field as specified in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
     */
    public void setTime(
            int hour,
            int minute,
            int second,
            BigDecimal fractional) {

        setHour(hour, false);

        setMinute(minute);
        if (second != 60) {
            setSecond(second);
        } else if ((hour == 23 && minute == 59) || (hour == 0 && minute == 0)) {
            setSecond(second);
        } else {
            invalidFieldValue(SECOND, second);
        }

        setFractionalSecond(fractional);

        // must test hour after setting seconds
        testHour();
    }


    /**
     * <p>Set time as one unit, including optional milliseconds.</p>
     *
     * @param hour value constraints are summarized in
     * <a href="#datetimefield-hour">hour field of date/time field mapping table</a>.
     * @param minute value constraints are summarized in
     * <a href="#datetimefield-minute">minute field of date/time field mapping table</a>.
     * @param second value constraints are summarized in
     * <a href="#datetimefield-second">second field of date/time field mapping table</a>.
     * @param millisecond value of {@link DatatypeConstants#FIELD_UNDEFINED} indicates this
     *                    optional field is not set.
     *
     * @throws IllegalArgumentException if any parameter is
     * outside value constraints for the field as specified in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
     */
    public void setTime(int hour, int minute, int second, int millisecond) {

        setHour(hour, false);

        setMinute(minute);
        if (second != 60) {
            setSecond(second);
        } else if ((hour == 23 && minute == 59) || (hour == 0 && minute == 0)) {
            setSecond(second);
        } else {
            invalidFieldValue(SECOND, second);
        }
        setMillisecond(millisecond);

        // must test hour after setting seconds
        testHour();
    }

    // comparisons
    /**
     * <p>Compare two instances of W3C XML Schema 1.0 date/time datatypes
     * according to partial order relation defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime-order">W3C XML Schema 1.0 Part 2, Section 3.2.7.3,
     * <i>Order relation on dateTime</i></a>.</p>
     *
     * <p><code>xsd:dateTime</code> datatype field mapping to accessors of
     * this class are defined in
     * <a href="#datetimefieldmapping">date/time field mapping table</a>.</p>
     *
     * @param rhs instance of <code>XMLGregorianCalendar</code> to compare
     *
     * @return the relationship between <code>lhs</code> and <code>rhs</code> as
     *   {@link DatatypeConstants#LESSER},
     *   {@link DatatypeConstants#EQUAL},
     *   {@link DatatypeConstants#GREATER} or
     *   {@link DatatypeConstants#INDETERMINATE}.
     *
     * @throws NullPointerException if <code>lhs</code> or <code>rhs</code>
     * parameters are null.
     */
    public int compare(XMLGregorianCalendar rhs) {

        XMLGregorianCalendar lhs = this;

        int result = DatatypeConstants.INDETERMINATE;
        XMLGregorianCalendarImpl P = (XMLGregorianCalendarImpl) lhs;
        XMLGregorianCalendarImpl Q = (XMLGregorianCalendarImpl) rhs;

        if (P.getTimezone() == Q.getTimezone()) {
            // Optimization:
            // both instances are in same timezone or
            // both are FIELD_UNDEFINED.
            // Avoid costly normalization of timezone to 'Z' time.
            return internalCompare(P, Q);

        } else if (P.getTimezone() != DatatypeConstants.FIELD_UNDEFINED &&
                Q.getTimezone() != DatatypeConstants.FIELD_UNDEFINED) {

            // Both instances have different timezones.
            // Normalize to UTC time and compare.
            P = (XMLGregorianCalendarImpl) P.normalize();
            Q = (XMLGregorianCalendarImpl) Q.normalize();
            return internalCompare(P, Q);
        } else if (P.getTimezone() != DatatypeConstants.FIELD_UNDEFINED) {

            if (P.getTimezone() != 0) {
                P = (XMLGregorianCalendarImpl) P.normalize();
            }

            // C. step 1
            XMLGregorianCalendar MinQ = Q.normalizeToTimezone(DatatypeConstants.MIN_TIMEZONE_OFFSET);
            result = internalCompare(P, MinQ);
            if (result == DatatypeConstants.LESSER) {
                return result;
            }

            // C. step 2
            XMLGregorianCalendar MaxQ = Q.normalizeToTimezone(DatatypeConstants.MAX_TIMEZONE_OFFSET);
            result = internalCompare(P, MaxQ);
            if (result == DatatypeConstants.GREATER) {
                return result;
            } else {
                // C. step 3
                return DatatypeConstants.INDETERMINATE;
            }
        } else { // Q.getTimezone() != DatatypeConstants.FIELD_UNDEFINED
            // P has no timezone and Q does.
            if (Q.getTimezone() != 0) {
                Q = (XMLGregorianCalendarImpl) Q.normalizeToTimezone(Q.getTimezone());
            }

            // D. step 1
            XMLGregorianCalendar MaxP = P.normalizeToTimezone(DatatypeConstants.MAX_TIMEZONE_OFFSET);
            result = internalCompare(MaxP, Q);
            if (result == DatatypeConstants.LESSER) {
                return result;
            }

            // D. step 2
            XMLGregorianCalendar MinP = P.normalizeToTimezone(DatatypeConstants.MIN_TIMEZONE_OFFSET);
            result = internalCompare(MinP, Q);
            if (result == DatatypeConstants.GREATER) {
                return result;
            } else {
                // D. step 3
                return DatatypeConstants.INDETERMINATE;
            }
        }
    }

    /**
     * <p>Normalize this instance to UTC.</p>
     *
     * <p>2000-03-04T23:00:00+03:00 normalizes to 2000-03-04T20:00:00Z</p>
     * <p>Implements W3C XML Schema Part 2, Section 3.2.7.3 (A).</p>
     */
    public XMLGregorianCalendar normalize() {

        XMLGregorianCalendar normalized = normalizeToTimezone(timezone);

        // if timezone was undefined, leave it undefined
        if (getTimezone() == DatatypeConstants.FIELD_UNDEFINED) {
            normalized.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
        }

        // if milliseconds was undefined, leave it undefined
        if (getMillisecond() == DatatypeConstants.FIELD_UNDEFINED) {
            normalized.setMillisecond(DatatypeConstants.FIELD_UNDEFINED);
        }

        return normalized;
    }

        /**
         * <p>Normalize this instance to UTC.</p>
         *
         * <p>2000-03-04T23:00:00+03:00 normalizes to 2000-03-04T20:00:00Z</p>
         * <p>Implements W3C XML Schema Part 2, Section 3.2.7.3 (A).</p>
         */
    private XMLGregorianCalendar normalizeToTimezone(int timezone) {

        int minutes = timezone;
        XMLGregorianCalendar result = (XMLGregorianCalendar) this.clone();

        // normalizing to UTC time negates the timezone offset before
        // addition.
        minutes = -minutes;
        Duration d = new DurationImpl(minutes >= 0, // isPositive
                0, //years
                0, //months
                0, //days
                0, //hours
                minutes < 0 ? -minutes : minutes, // absolute
                0  //seconds
        );
        result.add(d);

        // set to zulu UTC time.
        result.setTimezone(0);
        return result;
    }

    /**
     *
     *  <p>Implements Step B from http://www.w3.org/TR/xmlschema-2/#dateTime-order </p>
     * @param P calendar instance with normalized timezone offset or
     *          having same timezone as Q
     * @param Q calendar instance with normalized timezone offset or
     *          having same timezone as P
     *
     * @return result of comparing P and Q, value of
     *   {@link DatatypeConstants#EQUAL},
     *   {@link DatatypeConstants#LESSER},
     *   {@link DatatypeConstants#GREATER} or
     *   {@link DatatypeConstants#INDETERMINATE}.
     */
    private static int internalCompare(XMLGregorianCalendar P,
                                       XMLGregorianCalendar Q) {

        int result;

        // compare Year.
        if (P.getEon() == Q.getEon()) {

            // Eon field is only equal when null.
            // optimized case for comparing year not requiring eon field.
            result = compareField(P.getYear(), Q.getYear());
            if (result != DatatypeConstants.EQUAL) {
                return result;
            }
        } else {
            result = compareField(P.getEonAndYear(), Q.getEonAndYear());
            if (result != DatatypeConstants.EQUAL) {
                return result;
            }
        }

        result = compareField(P.getMonth(), Q.getMonth());
        if (result != DatatypeConstants.EQUAL) {
            return result;
        }

        result = compareField(P.getDay(), Q.getDay());
        if (result != DatatypeConstants.EQUAL) {
            return result;
        }

        result = compareField(P.getHour(), Q.getHour());
        if (result != DatatypeConstants.EQUAL) {
            return result;
        }

        result = compareField(P.getMinute(), Q.getMinute());
        if (result != DatatypeConstants.EQUAL) {
            return result;
        }
        result = compareField(P.getSecond(), Q.getSecond());
        if (result != DatatypeConstants.EQUAL) {
            return result;
        }

        result = compareField(P.getFractionalSecond(), Q.getFractionalSecond());
        return result;
    }

    /**
     * <p>Implement Step B from
     * http://www.w3.org/TR/xmlschema-2/#dateTime-order.</p>
     */
    private static int compareField(int Pfield, int Qfield) {
        if (Pfield == Qfield) {

            //fields are either equal in value or both undefined.
            // Step B. 1.1 AND optimized result of performing 1.1-1.4.
            return DatatypeConstants.EQUAL;
        } else {
            if (Pfield == DatatypeConstants.FIELD_UNDEFINED || Qfield == DatatypeConstants.FIELD_UNDEFINED) {
                // Step B. 1.2
                return DatatypeConstants.INDETERMINATE;
            } else {
                // Step B. 1.3-4.
                return (Pfield < Qfield ? DatatypeConstants.LESSER : DatatypeConstants.GREATER);
            }
        }
    }

    private static int compareField(BigInteger Pfield, BigInteger Qfield) {
        if (Pfield == null) {
            return (Qfield == null ? DatatypeConstants.EQUAL : DatatypeConstants.INDETERMINATE);
        }
        if (Qfield == null) {
            return DatatypeConstants.INDETERMINATE;
        }
        return Pfield.compareTo(Qfield);
    }

    private static int compareField(BigDecimal Pfield, BigDecimal Qfield) {
        // optimization. especially when both arguments are null.
        if (Pfield == Qfield) {
            return DatatypeConstants.EQUAL;
        }

        if (Pfield == null) {
            Pfield = DECIMAL_ZERO;
        }

        if (Qfield == null) {
            Qfield = DECIMAL_ZERO;
        }

        return Pfield.compareTo(Qfield);
    }

    /**
     * <p>Indicates whether parameter <code>obj</code> is "equal to" this one.</p>
     *
     * @param obj to compare.
     *
     * @return <code>true</code> when <code>compare(this,(XMLGregorianCalendar)obj) == EQUAL.</code>.
     */
    public boolean equals(Object obj) {

        if (obj == null || !(obj instanceof XMLGregorianCalendar)) {
            return false;
        }
        return compare((XMLGregorianCalendar) obj) == DatatypeConstants.EQUAL;
    }

    /**
     * <p>Returns a hash code consistent with the definition of the equals method.</p>
     *
     * @return hash code of this object.
     */
    public int hashCode() {

        // Following two dates compare to EQUALS since in different timezones.
        // 2000-01-15T12:00:00-05:00 == 2000-01-15T13:00:00-04:00
        //
        // Must ensure both instances generate same hashcode by normalizing
        // this to UTC timezone.
        int timezone = getTimezone();
        if (timezone == DatatypeConstants.FIELD_UNDEFINED) {
            timezone = 0;
        }
        XMLGregorianCalendar gc = this;
        if (timezone != 0) {
            gc = this.normalizeToTimezone(getTimezone());
        }
        return gc.getYear() + gc.getMonth() + gc.getDay() +
                gc.getHour() + gc.getMinute() + gc.getSecond();
    }


    /**
     * <p>Constructs a new XMLGregorianCalendar object by
     * parsing its lexical string representation as defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime-order">XML Schema 1.0 Part 2, Section 3.2.[7-14].1,
     * <i>Lexical Representation</i>.</a></p>
     *
     * <p>The string representation may not have any leading and trailing whitespaces.</p>
     *
     * <p>The parsing is done field by field so that
     * the following holds for any lexically correct string x:</p>
     * <pre>
     * new XMLGregorianCalendar(x).toXMLFormat().equals(x)
     * </pre>
     * Except for the noted lexical/canonical representation mismatches
     * listed in <a href="http://www.w3.org/2001/05/xmlschema-errata#e2-45">
     * XML Schema 1.0 errata, Section 3.2.7.2</a>.
     *
     * <p>Returns a non-null valid XMLGregorianCalendar object that holds the value
     * indicated by the lexicalRepresentation parameter.</p>
     *
     * @param lexicalRepresentation Lexical representation of one the 8 XML Schema calendar datatypes.
     *
     * @return <code>XMLGregorianCalendar</code> created from parsing <code>lexicalRepresentation</code> parameter.
     *
     * @throws IllegalArgumentException
     *      If the given string does not conform to the aforementioned
     *      specification.
     * @throws NullPointerException
     *      If the given string is null.
     */
    public static XMLGregorianCalendar parse(String lexicalRepresentation) {

                return new XMLGregorianCalendarImpl(lexicalRepresentation);
    }

    /**
     * <p>Return the lexical representation of <code>this</code> instance.
     * The format is specified in
     * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime-order">XML Schema 1.0 Part 2, Section 3.2.[7-14].1,
     * <i>Lexical Representation</i>".</a></p>
     *
     * <p>Specific target lexical representation format is determined by
     * {@link #getXMLSchemaType()}.</p>
     *
     * @return XML, as <code>String</code>, representation of this <code>XMLGregorianCalendar</code>
     *
     * @throws java.lang.IllegalStateException if the combination of set fields
     *    does not match one of the eight defined XML Schema builtin date/time datatypes.
     */
    public String toXMLFormat() {

        QName typekind = getXMLSchemaType();

        String formatString = null;
        // Fix 4971612: invalid SCCS macro substitution in data string
        //   no %{alpha}% to avoid SCCS macro substitution
        if (typekind == DatatypeConstants.DATETIME) {
            formatString = "%Y-%M-%DT%h:%m:%s" + "%z";
        } else if (typekind == DatatypeConstants.DATE) {
            formatString = "%Y-%M-%D" + "%z";
        } else if (typekind == DatatypeConstants.TIME) {
            formatString = "%h:%m:%s" + "%z";
        } else if (typekind == DatatypeConstants.GMONTH) {
            formatString = "--%M" + "%z";
        } else if (typekind == DatatypeConstants.GDAY) {
            formatString = "---%D" + "%z";
        } else if (typekind == DatatypeConstants.GYEAR) {
            formatString = "%Y" + "%z";
        } else if (typekind == DatatypeConstants.GYEARMONTH) {
            formatString = "%Y-%M" + "%z";
        } else if (typekind == DatatypeConstants.GMONTHDAY) {
            formatString = "--%M-%D" + "%z";
        }
        return format(formatString);
    }

    /**
     * <p>Return the name of the XML Schema date/time type that this instance
     * maps to. Type is computed based on fields that are set.</p>
     *
     * <table border="2" rules="all" cellpadding="2">
     *   <thead>
     *     <tr>
     *       <th align="center" colspan="7">
     *         Required fields for XML Schema 1.0 Date/Time Datatypes.<br/>
     *         <i>(timezone is optional for all date/time datatypes)</i>
     *       </th>
     *     </tr>
     *   </thead>
     *   <tbody>
     *     <tr>
     *       <td>Datatype</td>
     *       <td>year</td>
     *       <td>month</td>
     *       <td>day</td>
     *       <td>hour</td>
     *       <td>minute</td>
     *       <td>second</td>
     *     </tr>
     *     <tr>
     *       <td>{@link DatatypeConstants#DATETIME}</td>
     *       <td>X</td>
     *       <td>X</td>
     *       <td>X</td>
     *       <td>X</td>
     *       <td>X</td>
     *       <td>X</td>
     *     </tr>
     *     <tr>
     *       <td>{@link DatatypeConstants#DATE}</td>
     *       <td>X</td>
     *       <td>X</td>
     *       <td>X</td>
     *       <td></td>
     *       <td></td>
     *       <td></td>
     *     </tr>
     *     <tr>
     *       <td>{@link DatatypeConstants#TIME}</td>
     *       <td></td>
     *       <td></td>
     *       <td></td>
     *       <td>X</td>
     *       <td>X</td>
     *       <td>X</td>
     *     </tr>
     *     <tr>
     *       <td>{@link DatatypeConstants#GYEARMONTH}</td>
     *       <td>X</td>
     *       <td>X</td>
     *       <td></td>
     *       <td></td>
     *       <td></td>
     *       <td></td>
     *     </tr>
     *     <tr>
     *       <td>{@link DatatypeConstants#GMONTHDAY}</td>
     *       <td></td>
     *       <td>X</td>
     *       <td>X</td>
     *       <td></td>
     *       <td></td>
     *       <td></td>
     *     </tr>
     *     <tr>
     *       <td>{@link DatatypeConstants#GYEAR}</td>
     *       <td>X</td>
     *       <td></td>
     *       <td></td>
     *       <td></td>
     *       <td></td>
     *       <td></td>
     *     </tr>
     *     <tr>
     *       <td>{@link DatatypeConstants#GMONTH}</td>
     *       <td></td>
     *       <td>X</td>
     *       <td></td>
     *       <td></td>
     *       <td></td>
     *       <td></td>
     *     </tr>
     *     <tr>
     *       <td>{@link DatatypeConstants#GDAY}</td>
     *       <td></td>
     *       <td></td>
     *       <td>X</td>
     *       <td></td>
     *       <td></td>
     *       <td></td>
     *     </tr>
     *   </tbody>
     * </table>
     *
     * @throws java.lang.IllegalStateException if the combination of set fields
     *    does not match one of the eight defined XML Schema builtin
     *    date/time datatypes.
     * @return One of the following class constants:
     *   {@link DatatypeConstants#DATETIME},
     *   {@link DatatypeConstants#TIME},
     *   {@link DatatypeConstants#DATE},
     *   {@link DatatypeConstants#GYEARMONTH},
     *   {@link DatatypeConstants#GMONTHDAY},
     *   {@link DatatypeConstants#GYEAR},
     *   {@link DatatypeConstants#GMONTH} or
     *   {@link DatatypeConstants#GDAY}.
     */
    public QName getXMLSchemaType() {

        int mask =
            (year != DatatypeConstants.FIELD_UNDEFINED ?   0x20 : 0 )|
            (month != DatatypeConstants.FIELD_UNDEFINED ?  0x10 : 0 )|
            (day != DatatypeConstants.FIELD_UNDEFINED ?    0x08 : 0 )|
            (hour != DatatypeConstants.FIELD_UNDEFINED ?   0x04 : 0 )|
            (minute != DatatypeConstants.FIELD_UNDEFINED ? 0x02 : 0 )|
            (second != DatatypeConstants.FIELD_UNDEFINED ? 0x01 : 0 );

        switch(mask) {
        case 0x3F:
                return DatatypeConstants.DATETIME;
        case 0x38:
                return DatatypeConstants.DATE;
        case 0x07:
                return DatatypeConstants.TIME;
        case 0x30:
                return DatatypeConstants.GYEARMONTH;
        case 0x18:
                return DatatypeConstants.GMONTHDAY;
        case 0x20:
                return DatatypeConstants.GYEAR;
        case 0x10:
                return DatatypeConstants.GMONTH;
        case 0x08:
                return DatatypeConstants.GDAY;
        default:
            throw new IllegalStateException(
                this.getClass().getName()
                + "#getXMLSchemaType() :"
                + DatatypeMessageFormatter.formatMessage(null, "InvalidXGCFields", null)
            );
        }
    }


    /**
     * Validate instance by <code>getXMLSchemaType()</code> constraints.
     * @return true if data values are valid.
     */
    public boolean isValid() {
        // since setters do not allow for invalid values,
        // (except for exceptional case of year field of zero),
        // no need to check for anything except for constraints
        // between fields.

        //check if days in month is valid. Can be dependent on leap year.
        if (getMonth() == DatatypeConstants.FEBRUARY) {
            // years could not be set
            int maxDays = 29;

            if (eon == null) {
                if(year!=DatatypeConstants.FIELD_UNDEFINED)
                    maxDays = maximumDayInMonthFor(year,getMonth());
            } else {
                BigInteger years = getEonAndYear();
                if (years != null) {
                    maxDays = maximumDayInMonthFor(getEonAndYear(), DatatypeConstants.FEBRUARY);
                }
            }
            if (getDay() > maxDays) {
                return false;
            }
        }

        // http://www.w3.org/2001/05/xmlschema-errata#e2-45
        if (getHour() == 24) {
            if(getMinute() != 0) {
                return false;
            } else if (getSecond() != 0) {
                return false;
            }
        }

        // XML Schema 1.0 specification defines year value of zero as
        // invalid. Allow this class to set year field to zero
        // since XML Schema 1.0 errata states that lexical zero will
        // be allowed in next version and treated as 1 B.C.E.
        if (eon == null) {
            // optimize check.
            if (year == 0) {
                return false;
            }
        } else {
            BigInteger yearField = getEonAndYear();
            if (yearField != null) {
                int result = compareField(yearField, BigInteger.ZERO);
                if (result == DatatypeConstants.EQUAL) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * <p>Add <code>duration</code> to this instance.<\p>
     *
     * <p>The computation is specified in
     * <a href="http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes">XML Schema 1.0 Part 2, Appendix E,
     * <i>Adding durations to dateTimes</i>></a>.
     * <a href="#datetimefieldsmapping">date/time field mapping table</a>
     * defines the mapping from XML Schema 1.0 <code>dateTime</code> fields
     * to this class' representation of those fields.</p>
     *
     * @param duration Duration to add to this <code>XMLGregorianCalendar</code>.
     *
     * @throws NullPointerException  when <code>duration</code> parameter is <code>null</code>.
     */
    public void add(Duration duration) {

        /*
           * Extracted from
           * http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes
           * to ensure implemented properly. See spec for definitions of methods
           * used in algorithm.
           *
           * Given a dateTime S and a duration D, specifies how to compute a
           * dateTime E where E is the end of the time period with start S and
           * duration D i.e. E = S + D.
           *
           * The following is the precise specification.
           * These steps must be followed in the same order.
           * If a field in D is not specified, it is treated as if it were zero.
           * If a field in S is not specified, it is treated in the calculation
           * as if it were the minimum allowed value in that field, however,
           * after the calculation is concluded, the corresponding field in
           * E is removed (set to unspecified).
           *
           * Months (may be modified additionally below)
               *  temp := S[month] + D[month]
               *  E[month] := modulo(temp, 1, 13)
               *  carry := fQuotient(temp, 1, 13)
           */

        boolean fieldUndefined[] = {
                false,
                false,
                false,
                false,
                false,
                false
        };

        int signum = duration.getSign();

        int startMonth = getMonth();
        if (startMonth == DatatypeConstants.FIELD_UNDEFINED) {
            startMonth = DatatypeConstants.JANUARY;
            fieldUndefined[MONTH] = true;
        }

        BigInteger dMonths = sanitize(duration.getField(DatatypeConstants.MONTHS), signum);
        BigInteger temp = BigInteger.valueOf((long) startMonth).add(dMonths);
        setMonth(temp.subtract(BigInteger.ONE).mod(TWELVE).intValue() + 1);
        BigInteger carry =
                new BigDecimal(temp.subtract(BigInteger.ONE)).divide(new BigDecimal(TWELVE), BigDecimal.ROUND_FLOOR).toBigInteger();

        /* Years (may be modified additionally below)
            *  E[year] := S[year] + D[year] + carry
            */
        BigInteger startYear = getEonAndYear();
        if (startYear == null) {
            fieldUndefined[YEAR] = true;
            startYear = BigInteger.ZERO;
        }
        BigInteger dYears = sanitize(duration.getField(DatatypeConstants.YEARS), signum);
        BigInteger endYear = startYear.add(dYears).add(carry);
        setYear(endYear);

        /* Zone
               *  E[zone] := S[zone]
           *
           * no-op since adding to this, not to a new end point.
           */

        /* Seconds
            *  temp := S[second] + D[second]
            *  E[second] := modulo(temp, 60)
            *  carry := fQuotient(temp, 60)
            */
        BigDecimal startSeconds;
        if (getSecond() == DatatypeConstants.FIELD_UNDEFINED) {
            fieldUndefined[SECOND] = true;
            startSeconds = DECIMAL_ZERO;
        } else {
            // seconds + fractionalSeconds
            startSeconds = getSeconds();
        }

        // Duration seconds is SECONDS + FRACTIONALSECONDS.
        BigDecimal dSeconds = DurationImpl.sanitize((BigDecimal) duration.getField(DatatypeConstants.SECONDS), signum);
        BigDecimal tempBD = startSeconds.add(dSeconds);
        BigDecimal fQuotient =
                new BigDecimal(new BigDecimal(tempBD.toBigInteger()).divide(DECIMAL_SIXTY, BigDecimal.ROUND_FLOOR).toBigInteger());
        BigDecimal endSeconds = tempBD.subtract(fQuotient.multiply(DECIMAL_SIXTY));

        carry = fQuotient.toBigInteger();
        setSecond(endSeconds.intValue());
        BigDecimal tempFracSeconds = endSeconds.subtract(new BigDecimal(BigInteger.valueOf((long) getSecond())));
        if (tempFracSeconds.compareTo(DECIMAL_ZERO) < 0) {
            setFractionalSecond(DECIMAL_ONE.add(tempFracSeconds));
            if (getSecond() == 0) {
                setSecond(59);
                carry = carry.subtract(BigInteger.ONE);
            } else {
                setSecond(getSecond() - 1);
            }
        } else {
            setFractionalSecond(tempFracSeconds);
        }

        /* Minutes
               *  temp := S[minute] + D[minute] + carry
               *  E[minute] := modulo(temp, 60)
               *  carry := fQuotient(temp, 60)
           */
        int startMinutes = getMinute();
        if (startMinutes == DatatypeConstants.FIELD_UNDEFINED) {
            fieldUndefined[MINUTE] = true;
            startMinutes = 0;
        }
        BigInteger dMinutes = sanitize(duration.getField(DatatypeConstants.MINUTES), signum);

        temp = BigInteger.valueOf(startMinutes).add(dMinutes).add(carry);
        setMinute(temp.mod(SIXTY).intValue());
        carry = new BigDecimal(temp).divide(DECIMAL_SIXTY, BigDecimal.ROUND_FLOOR).toBigInteger();

        /* Hours
               *  temp := S[hour] + D[hour] + carry
               *  E[hour] := modulo(temp, 24)
               *  carry := fQuotient(temp, 24)
           */
        int startHours = getHour();
        if (startHours == DatatypeConstants.FIELD_UNDEFINED) {
            fieldUndefined[HOUR] = true;
            startHours = 0;
        }
        BigInteger dHours = sanitize(duration.getField(DatatypeConstants.HOURS), signum);

        temp = BigInteger.valueOf(startHours).add(dHours).add(carry);
        setHour(temp.mod(TWENTY_FOUR).intValue(), false);
        carry = new BigDecimal(temp).divide(new BigDecimal(TWENTY_FOUR), BigDecimal.ROUND_FLOOR).toBigInteger();

        /* Days
           *  if S[day] > maximumDayInMonthFor(E[year], E[month])
           *       + tempDays := maximumDayInMonthFor(E[year], E[month])
           *  else if S[day] < 1
           *       + tempDays := 1
           *  else
           *       + tempDays := S[day]
           *  E[day] := tempDays + D[day] + carry
           *  START LOOP
           *       + IF E[day] < 1
           *             # E[day] := E[day] +
            *                 maximumDayInMonthFor(E[year], E[month] - 1)
           *             # carry := -1
           *       + ELSE IF E[day] > maximumDayInMonthFor(E[year], E[month])
           *             # E[day] :=
            *                    E[day] - maximumDayInMonthFor(E[year], E[month])
           *             # carry := 1
           *       + ELSE EXIT LOOP
           *       + temp := E[month] + carry
           *       + E[month] := modulo(temp, 1, 13)
           *       + E[year] := E[year] + fQuotient(temp, 1, 13)
           *       + GOTO START LOOP
           */
        BigInteger tempDays;
        int startDay = getDay();
        if (startDay == DatatypeConstants.FIELD_UNDEFINED) {
            fieldUndefined[DAY] = true;
            startDay = 1;
        }
        BigInteger dDays = sanitize(duration.getField(DatatypeConstants.DAYS), signum);
        int maxDayInMonth = maximumDayInMonthFor(getEonAndYear(), getMonth());
        if (startDay > maxDayInMonth) {
            tempDays = BigInteger.valueOf(maxDayInMonth);
        } else if (startDay < 1) {
            tempDays = BigInteger.ONE;
        } else {
            tempDays = BigInteger.valueOf(startDay);
        }
        BigInteger endDays = tempDays.add(dDays).add(carry);
        int monthCarry;
        int intTemp;
        while (true) {
            if (endDays.compareTo(BigInteger.ONE) < 0) {
                // calculate days in previous month, watch for month roll over
                BigInteger mdimf = null;
                if (month >= 2) {
                    mdimf = BigInteger.valueOf(maximumDayInMonthFor(getEonAndYear(), getMonth() - 1));
                } else {
                    // roll over to December of previous year
                    mdimf = BigInteger.valueOf(maximumDayInMonthFor(getEonAndYear().subtract(BigInteger.valueOf((long) 1)), 12));
                }
                endDays = endDays.add(mdimf);
                monthCarry = -1;
            } else if (endDays.compareTo(BigInteger.valueOf(maximumDayInMonthFor(getEonAndYear(), getMonth()))) > 0) {
                endDays = endDays.add(BigInteger.valueOf(-maximumDayInMonthFor(getEonAndYear(), getMonth())));
                monthCarry = 1;
            } else {
                break;
            }

            intTemp = getMonth() + monthCarry;
            int endMonth = (intTemp - 1) % (13 - 1);
            int quotient;
            if (endMonth < 0) {
                endMonth = (13 - 1) + endMonth + 1;
                quotient = new BigDecimal(intTemp - 1).divide(new BigDecimal(TWELVE), BigDecimal.ROUND_UP).intValue();
            } else {
                quotient = (intTemp - 1) / (13 - 1);
                endMonth += 1;
            }
            setMonth(endMonth);
            if (quotient != 0) {
                setYear(getEonAndYear().add(BigInteger.valueOf(quotient)));
            }
        }
        setDay(endDays.intValue());

        // set fields that where undefined before this addition, back to undefined.
        for (int i = YEAR; i <= SECOND; i++) {
            if (fieldUndefined[i]) {
                switch (i) {
                case YEAR:
                    setYear(DatatypeConstants.FIELD_UNDEFINED);
                    break;
                case MONTH:
                    setMonth(DatatypeConstants.FIELD_UNDEFINED);
                    break;
                case DAY:
                    setDay(DatatypeConstants.FIELD_UNDEFINED);
                    break;
                case HOUR:
                    setHour(DatatypeConstants.FIELD_UNDEFINED, false);
                    break;
                case MINUTE:
                    setMinute(DatatypeConstants.FIELD_UNDEFINED);
                    break;
                case SECOND:
                    setSecond(DatatypeConstants.FIELD_UNDEFINED);
                    setFractionalSecond(null);
                    break;
                }
            }
        }
    }

    private static final BigInteger FOUR = BigInteger.valueOf(4);
    private static final BigInteger HUNDRED = BigInteger.valueOf(100);
    private static final BigInteger FOUR_HUNDRED = BigInteger.valueOf(400);
    private static final BigInteger SIXTY = BigInteger.valueOf(60);
    private static final BigInteger TWENTY_FOUR = BigInteger.valueOf(24);
    private static final BigInteger TWELVE = BigInteger.valueOf(12);
    private static final BigDecimal DECIMAL_ZERO = new BigDecimal("0");
    private static final BigDecimal DECIMAL_ONE = new BigDecimal("1");
    private static final BigDecimal DECIMAL_SIXTY = new BigDecimal("60");


    private static int daysInMonth[] = { 0,  // XML Schema months start at 1.
                                       31, 28, 31, 30, 31, 30,
                                       31, 31, 30, 31, 30, 31};

    private static int maximumDayInMonthFor(BigInteger year, int month) {
        if (month != DatatypeConstants.FEBRUARY) {
            return daysInMonth[month];
        } else {
            if (year.mod(FOUR_HUNDRED).equals(BigInteger.ZERO) ||
                    (!year.mod(HUNDRED).equals(BigInteger.ZERO) &&
                            year.mod(FOUR).equals(BigInteger.ZERO))) {
                // is a leap year.
                return 29;
            } else {
                return daysInMonth[month];
            }
        }
    }

    private static int maximumDayInMonthFor(int year, int month) {
        if (month != DatatypeConstants.FEBRUARY) {
            return daysInMonth[month];
        } else {
            if (((year % 400) == 0) ||
                    (((year % 100) != 0) && ((year % 4) == 0))) {
                // is a leap year.
                return 29;
            } else {
                return daysInMonth[DatatypeConstants.FEBRUARY];
            }
        }
    }

    /**
     * <p>Convert <code>this</code> to <code>java.util.GregorianCalendar</code>.</p>
     *
     * <p>When <code>this</code> instance has an undefined field, this
     * conversion relies on the <code>java.util.GregorianCalendar</code> default
     * for its corresponding field. A notable difference between
     * XML Schema 1.0 date/time datatypes and <code>java.util.GregorianCalendar</code>
     * is that Timezone value is optional for date/time datatypes and it is
     * a required field for <code>java.util.GregorianCalendar</code>. See javadoc
     * for <code>java.util.TimeZone.getDefault()</code> on how the default
     * is determined. To explicitly specify the <code>TimeZone</code>
     * instance, see
     * {@link #toGregorianCalendar(TimeZone, Locale, XMLGregorianCalendar)}.</p>
     *
     * <table border="2" rules="all" cellpadding="2">
     *   <thead>
     *     <tr>
     *       <th align="center" colspan="2">
     *          Field by Field Conversion from this class to
     *          <code>java.util.GregorianCalendar</code>
     *       </th>
     *     </tr>
     *   </thead>
     *   <tbody>
     *     <tr>
     *        <th><code>java.util.GregorianCalendar</code> field</th>
     *        <th><code>javax.xml.datatype.XMLGregorianCalendar</code> field</th>
     *     </tr>
     *     <tr>
     *       <th><code>ERA</code></th>
     *       <th>{@link #getEonAndYear()}<code>.signum() < 0 ? GregorianCalendar.BC : GregorianCalendar.AD</code></th>
     *     </tr>
     *     <tr>
     *       <th><code>YEAR</code></th>
     *       <th>{@link #getEonAndYear()}<code>.abs().intValue()</code><i>*</i></th>
     *     </tr>
     *     <tr>
     *       <th><code>MONTH</code></th>
     *       <th>{@link #getMonth()}<code> - 1</code></th>
     *     </tr>
     *     <tr>
     *       <th><code>DAY_OF_MONTH</code></th>
     *       <th>{@link #getDay()}</th>
     *     </tr>
     *     <tr>
     *       <th><code>AM_PM</code></th>
     *       <th>{@link #getHour()} < 12 : Calendar.AM : Calendar.PM</th>
     *     </tr>
     *     <tr>
     *       <th><code>HOUR_OF_DAY</code></th>
     *       <th>{@link #getHour()}</th>
     *     </tr>
     *     <tr>
     *       <th><code>MINUTE</code></th>
     *       <th>{@link #getMinute()}</th>
     *     </tr>
     *     <tr>
     *       <th><code>SECOND</code></th>
     *       <th>{@link #getSecond()}</th>
     *     </tr>
     *     <tr>
     *       <th><code>MILLISECOND</code></th>
     *       <th>get millisecond order from {@link #getFractionalSecond()}<i>*</i> </th>
     *     </tr>
     *     <tr>
     *       <th><code>GregorianCalendar.setTimeZone(TimeZone)</code></th>
     *       <th>{@link #getTimezone()} formatted into Custom timezone id</th>
     *     </tr>
     *   </tbody>
     * </table>
     * <i>*</i> designates possible loss of precision during the conversion due
     * to source datatype having higer precison than target datatype.
     *
     * <p>To ensure consistency in conversion implementations, the new
     * <code>GregorianCalendar</code> should be instantiated in following
     * manner.
     * <ul>
     *   <li>Using <code>timeZone</code> value as defined above, create a new
     * <code>java.util.GregorianCalendar(timeZone,Locale.getDefault())</code>.
     *   </li>
     *   <li>Initialize all GregorianCalendar fields by calling {(@link GegorianCalendar#clear()}.</li>
     *   <li>Obtain a pure Gregorian Calendar by invoking
     *   <code>GregorianCalendar.setGregorianChange(
     *   new Date(Long.MIN_VALUE))</code>.</li>
     *   <li>Its fields ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY,
     *       MINUTE, SECOND and MILLISECOND are set using the method
     *       <code>Calendar.set(int,int)</code></li>
     * </ul>
     * </p>
     *
     * @see #toGregorianCalendar(java.util.TimeZone, java.util.Locale, XMLGregorianCalendar)
     */
    public java.util.GregorianCalendar toGregorianCalendar() {

        GregorianCalendar result = null;
        final int DEFAULT_TIMEZONE_OFFSET = DatatypeConstants.FIELD_UNDEFINED;
        TimeZone tz = getTimeZone(DEFAULT_TIMEZONE_OFFSET);
        /** Use the following instead for JDK7 only:
         * Locale locale = Locale.getDefault(Locale.Category.FORMAT);
         */
        Locale locale = getDefaultLocale();

        result = new GregorianCalendar(tz, locale);
        result.clear();
        result.setGregorianChange(PURE_GREGORIAN_CHANGE);

        // if year( and eon) are undefined, leave default Calendar values
        BigInteger year = getEonAndYear();
        if (year != null) {
            result.set(Calendar.ERA, year.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD);
            result.set(Calendar.YEAR, year.abs().intValue());
        }

        // only set month if it is set
        if (month != DatatypeConstants.FIELD_UNDEFINED) {
            // Calendar.MONTH is zero based while XMLGregorianCalendar month field is not.
            result.set(Calendar.MONTH, month - 1);
        }

        // only set day if it is set
        if (day != DatatypeConstants.FIELD_UNDEFINED) {
            result.set(Calendar.DAY_OF_MONTH, day);
        }

        // only set hour if it is set
        if (hour != DatatypeConstants.FIELD_UNDEFINED) {
            result.set(Calendar.HOUR_OF_DAY, hour);
        }

        // only set minute if it is set
        if (minute != DatatypeConstants.FIELD_UNDEFINED) {
            result.set(Calendar.MINUTE, minute);
        }

        // only set second if it is set
        if (second != DatatypeConstants.FIELD_UNDEFINED) {
            result.set(Calendar.SECOND, second);
        }

        // only set millisend if it is set
        if (fractionalSecond != null) {
            result.set(Calendar.MILLISECOND, getMillisecond());
        }

        return result;
    }

    /**
     *
     * @return default locale
     */
    private Locale getDefaultLocale() {

        String lang = SecuritySupport.getSystemProperty("user.language.format");
        String country = SecuritySupport.getSystemProperty("user.country.format");
        String variant = SecuritySupport.getSystemProperty("user.variant.format");
        Locale locale = null;
        if (lang != null) {
            if (country != null) {
                if (variant != null) {
                    locale = new Locale(lang, country, variant);
                } else {
                    locale = new Locale(lang, country);
                }
            } else {
                locale = new Locale(lang);
            }
        }
        if (locale == null) {
            locale = Locale.getDefault();
        }
        return locale;
    }

    /**
     * <p>Convert <code>this</code> along with provided parameters
     * to <code>java.util.GregorianCalendar</code> instance.</p>
     *
     * <p> Since XML Schema 1.0 date/time datetypes has no concept of
     * timezone ids or daylight savings timezone ids, this conversion operation
     * allows the user to explicitly specify one with
     * <code>timezone</code> parameter.</p>
     *
     * <p>To compute the return value's <code>TimeZone</code> field,
     * <ul>
     * <li>when parameter <code>timeZone</code> is non-null,
     * it is the timezone field.</li>
     * <li>else when <code>this.getTimezone() != DatatypeConstants.FIELD_UNDEFINED</code>,
     * create a <code>java.util.TimeZone</code> with a custom timezone id
     * using the <code>this.getTimezone()</code>.</li>
     * <li>else when <code>defaults.getTimezone() != DatatypeConstants.FIELD_UNDEFINED</code>,
     * create a <code>java.util.TimeZone</code> with a custom timezone id
     * using <code>defaults.getTimezone()</code>.</li>
     * <li>else use the <code>GregorianCalendar</code> default timezone value
     * for the host is definedas specified by
     * <code>java.util.TimeZone.getDefault()</code>.</li></p>
     *
     * <p>To ensure consistency in conversion implementations, the new
     * <code>GregorianCalendar</code> should be instantiated in following
     * manner.
     * <ul>
     *   <li>Create a new <code>java.util.GregorianCalendar(TimeZone,
     *       Locale)</code> with TimeZone set as specified above and the
     *       <code>Locale</code> parameter.
     *   </li>
     *   <li>Initialize all GregorianCalendar fields by calling {(@link GegorianCalendar#clear()}.</li>
     *   <li>Obtain a pure Gregorian Calendar by invoking
     *   <code>GregorianCalendar.setGregorianChange(
     *   new Date(Long.MIN_VALUE))</code>.</li>
     *   <li>Its fields ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY,
     *       MINUTE, SECOND and MILLISECOND are set using the method
     *       <code>Calendar.set(int,int)</code></li>
     * </ul>
     *
     * @param timezone provide Timezone. <code>null</code> is a legal value.
     * @param aLocale  provide explicit Locale. Use default GregorianCalendar locale if
     *                 value is <code>null</code>.
     * @param defaults provide default field values to use when corresponding
     *                 field for this instance is DatatypeConstants.FIELD_UNDEFINED or null.
     *                 If <code>defaults</code>is <code>null</code> or a field
     *                 within the specified <code>defaults</code> is undefined,
     *                 just use <code>java.util.GregorianCalendar</code> defaults.
     * @return a java.util.GregorianCalendar conversion of this instance.
     *
     * @see #LEAP_YEAR_DEFAULT
     */
    public GregorianCalendar toGregorianCalendar(TimeZone timezone,
                                                 Locale aLocale,
                                                 XMLGregorianCalendar defaults) {
        GregorianCalendar result = null;
        TimeZone tz = timezone;
        if (tz == null) {
            int defaultZoneoffset = DatatypeConstants.FIELD_UNDEFINED;
            if (defaults != null) {
                defaultZoneoffset = defaults.getTimezone();
            }
            tz = getTimeZone(defaultZoneoffset);
        }
        if (aLocale == null) {
            aLocale = Locale.getDefault();
        }
        result = new GregorianCalendar(tz, aLocale);
        result.clear();
        result.setGregorianChange(PURE_GREGORIAN_CHANGE);

        // if year( and eon) are undefined, leave default Calendar values
        BigInteger year = getEonAndYear();
        if (year != null) {
            result.set(Calendar.ERA, year.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD);
            result.set(Calendar.YEAR, year.abs().intValue());
        } else {
            // use default if set
            BigInteger defaultYear = (defaults != null) ? defaults.getEonAndYear() : null;
            if (defaultYear != null) {
                result.set(Calendar.ERA, defaultYear.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD);
                result.set(Calendar.YEAR, defaultYear.abs().intValue());
            }
        }

        // only set month if it is set
        if (month != DatatypeConstants.FIELD_UNDEFINED) {
            // Calendar.MONTH is zero based while XMLGregorianCalendar month field is not.
            result.set(Calendar.MONTH, month - 1);
        } else {
            // use default if set
            int defaultMonth = (defaults != null) ? defaults.getMonth() : DatatypeConstants.FIELD_UNDEFINED;
            if (defaultMonth != DatatypeConstants.FIELD_UNDEFINED) {
                // Calendar.MONTH is zero based while XMLGregorianCalendar month field is not.
                result.set(Calendar.MONTH, defaultMonth - 1);
            }
        }

        // only set day if it is set
        if (day != DatatypeConstants.FIELD_UNDEFINED) {
            result.set(Calendar.DAY_OF_MONTH, day);
        } else {
            // use default if set
            int defaultDay = (defaults != null) ? defaults.getDay() : DatatypeConstants.FIELD_UNDEFINED;
            if (defaultDay != DatatypeConstants.FIELD_UNDEFINED) {
                result.set(Calendar.DAY_OF_MONTH, defaultDay);
            }
        }

        // only set hour if it is set
        if (hour != DatatypeConstants.FIELD_UNDEFINED) {
            result.set(Calendar.HOUR_OF_DAY, hour);
        } else {
            // use default if set
            int defaultHour = (defaults != null) ? defaults.getHour() : DatatypeConstants.FIELD_UNDEFINED;
            if (defaultHour != DatatypeConstants.FIELD_UNDEFINED) {
                result.set(Calendar.HOUR_OF_DAY, defaultHour);
            }
        }

        // only set minute if it is set
        if (minute != DatatypeConstants.FIELD_UNDEFINED) {
            result.set(Calendar.MINUTE, minute);
        } else {
            // use default if set
            int defaultMinute = (defaults != null) ? defaults.getMinute() : DatatypeConstants.FIELD_UNDEFINED;
            if (defaultMinute != DatatypeConstants.FIELD_UNDEFINED) {
                result.set(Calendar.MINUTE, defaultMinute);
            }
        }

        // only set second if it is set
        if (second != DatatypeConstants.FIELD_UNDEFINED) {
            result.set(Calendar.SECOND, second);
        } else {
            // use default if set
            int defaultSecond = (defaults != null) ? defaults.getSecond() : DatatypeConstants.FIELD_UNDEFINED;
            if (defaultSecond != DatatypeConstants.FIELD_UNDEFINED) {
                result.set(Calendar.SECOND, defaultSecond);
            }
        }

        // only set millisend if it is set
        if (fractionalSecond != null) {
            result.set(Calendar.MILLISECOND, getMillisecond());
        } else {
            // use default if set
            BigDecimal defaultFractionalSecond = (defaults != null) ? defaults.getFractionalSecond() : null;
            if (defaultFractionalSecond != null) {
                result.set(Calendar.MILLISECOND, defaults.getMillisecond());
            }
        }

        return result;
    }

    /**
     * <p>Returns a <code>java.util.TimeZone</code> for this class.</p>
     *
     * <p>If timezone field is defined for this instance,
     * returns TimeZone initialized with custom timezone id
     * of zoneoffset. If timezone field is undefined,
     * try the defaultZoneoffset that was passed in.
     * If defaultZoneoffset is DatatypeConstants.FIELD_UNDEFINED, return
     * default timezone for this host.
     * (Same default as java.util.GregorianCalendar).</p>
     *
     * @param defaultZoneoffset default zoneoffset if this zoneoffset is
     * {@link DatatypeConstants#FIELD_UNDEFINED}.
     *
     * @return TimeZone for this.
     */
    public TimeZone getTimeZone(int defaultZoneoffset) {
        TimeZone result = null;
        int zoneoffset = getTimezone();

        if (zoneoffset == DatatypeConstants.FIELD_UNDEFINED) {
            zoneoffset = defaultZoneoffset;
        }
        if (zoneoffset == DatatypeConstants.FIELD_UNDEFINED) {
            result = TimeZone.getDefault();
        } else {
            // zoneoffset is in minutes. Convert to custom timezone id format.
            char sign = zoneoffset < 0 ? '-' : '+';
            if (sign == '-') {
                zoneoffset = -zoneoffset;
            }
            int hour = zoneoffset / 60;
            int minutes = zoneoffset - (hour * 60);

            // Javadoc for java.util.TimeZone documents max length
            // for customTimezoneId is 8 when optional ':' is not used.
            // Format is
            // "GMT" ('-'|''+') (digit digit?) (digit digit)?
            //                   hour          minutes
            StringBuffer customTimezoneId = new StringBuffer(8);
            customTimezoneId.append("GMT");
            customTimezoneId.append(sign);
            customTimezoneId.append(hour);
            if (minutes != 0) {
                customTimezoneId.append(minutes);
            }
            result = TimeZone.getTimeZone(customTimezoneId.toString());
        }
        return result;
    }

    /**
     * <p>Creates and returns a copy of this object.</p>
     *
     * @return copy of this <code>Object</code>
     */
   public Object clone() {
        // Both this.eon and this.fractionalSecond are instances
        // of immutable classes, so they do not need to be cloned.
       return new XMLGregorianCalendarImpl(getEonAndYear(),
                        this.month, this.day,
                        this.hour, this.minute, this.second,
                        this.fractionalSecond,
                        this.timezone);
    }

    /**
     * <p>Unset all fields to undefined.</p>
     *
     * <p>Set all int fields to {@link DatatypeConstants#FIELD_UNDEFINED} and reference fields
     * to null.</p>
     */
    public void clear() {
        eon = null;
        year = DatatypeConstants.FIELD_UNDEFINED;
        month = DatatypeConstants.FIELD_UNDEFINED;
        day = DatatypeConstants.FIELD_UNDEFINED;
        timezone = DatatypeConstants.FIELD_UNDEFINED;  // in minutes
        hour = DatatypeConstants.FIELD_UNDEFINED;
        minute = DatatypeConstants.FIELD_UNDEFINED;
        second = DatatypeConstants.FIELD_UNDEFINED;
        fractionalSecond = null;
    }

    public void setMillisecond(int millisecond) {
        if (millisecond == DatatypeConstants.FIELD_UNDEFINED) {
            fractionalSecond = null;
        } else {
            if(millisecond<0 || 999<millisecond)
                if(millisecond!=DatatypeConstants.FIELD_UNDEFINED)
                    invalidFieldValue(MILLISECOND, millisecond);
            fractionalSecond = new BigDecimal((long) millisecond).movePointLeft(3);
        }
    }

    public void setFractionalSecond(BigDecimal fractional) {
        if (fractional != null) {
            if ((fractional.compareTo(DECIMAL_ZERO) < 0) ||
                    (fractional.compareTo(DECIMAL_ONE) > 0)) {
                throw new IllegalArgumentException(DatatypeMessageFormatter.formatMessage(null,
                        "InvalidFractional", new Object[]{fractional}));
            }
        }
        this.fractionalSecond = fractional;
    }

    private final class Parser {
        private final String format;
        private final String value;

        private final int flen;
        private final int vlen;

        private int fidx;
        private int vidx;

        private Parser(String format, String value) {
            this.format = format;
            this.value = value;
            this.flen = format.length();
            this.vlen = value.length();
        }

        /**
         * <p>Parse a formated <code>String</code> into an <code>XMLGregorianCalendar</code>.</p>
         *
         * <p>If <code>String</code> is not formated as a legal <code>XMLGregorianCalendar</code> value,
         * an <code>IllegalArgumentException</code> is thrown.</p>
         *
         * @throws IllegalArgumentException If <code>String</code> is not formated as a legal <code>XMLGregorianCalendar</code> value.
         */
        public void parse() throws IllegalArgumentException {
            while (fidx < flen) {
                char fch = format.charAt(fidx++);

                if (fch != '%') { // not a meta character
                    skip(fch);
                    continue;
                }

                // seen meta character. we don't do error check against the format
                switch (format.charAt(fidx++)) {
                    case 'Y' : // year
                        parseAndSetYear(4);
                        break;

                    case 'M' : // month
                        setMonth(parseInt(2, 2));
                        break;

                    case 'D' : // days
                        setDay(parseInt(2, 2));
                        break;

                    case 'h' : // hours
                        setHour(parseInt(2, 2), false);
                        break;

                    case 'm' : // minutes
                        setMinute(parseInt(2, 2));
                        break;

                    case 's' : // parse seconds.
                        setSecond(parseInt(2, 2));

                        if (peek() == '.') {
                            setFractionalSecond(parseBigDecimal());
                        }
                        break;

                    case 'z' : // time zone. missing, 'Z', or [+-]nn:nn
                        char vch = peek();
                        if (vch == 'Z') {
                            vidx++;
                            setTimezone(0);
                        } else if (vch == '+' || vch == '-') {
                            vidx++;
                            int h = parseInt(2, 2);
                            skip(':');
                            int m = parseInt(2, 2);
                            setTimezone((h * 60 + m) * (vch == '+' ? 1 : -1));
                        }

                        break;

                    default :
                        // illegal meta character. impossible.
                        throw new InternalError();
                }
            }

            if (vidx != vlen) {
                // some tokens are left in the input
                throw new IllegalArgumentException(value); //,vidx);
            }
            testHour();
        }

        private char peek() throws IllegalArgumentException {
            if (vidx == vlen) {
                return (char) -1;
            }
            return value.charAt(vidx);
        }

        private char read() throws IllegalArgumentException {
            if (vidx == vlen) {
                throw new IllegalArgumentException(value); //,vidx);
            }
            return value.charAt(vidx++);
        }

        private void skip(char ch) throws IllegalArgumentException {
            if (read() != ch) {
                throw new IllegalArgumentException(value); //,vidx-1);
            }
        }

        private int parseInt(int minDigits, int maxDigits)
            throws IllegalArgumentException {

            int n = 0;
            char ch;
            int vstart = vidx;
            while (isDigit(ch=peek()) && (vidx - vstart) <= maxDigits) {
                vidx++;
                n = n*10 + ch-'0';
            }
            if ((vidx - vstart) < minDigits) {
                // we are expecting more digits
                throw new IllegalArgumentException(value); //,vidx);
            }

            return n;
        }

        private void parseAndSetYear(int minDigits)
                throws IllegalArgumentException {
            int vstart = vidx;
            int n = 0;
            boolean neg = false;

            // skip leading negative, if it exists
            if (peek() == '-') {
                vidx++;
                neg = true;
            }
            while(true) {
                char ch = peek();
                if(!isDigit(ch))
                    break;
                vidx++;
                n = n*10 + ch-'0';
            }

            if ((vidx - vstart) < minDigits) {
                // we are expecting more digits
                throw new IllegalArgumentException(value); //,vidx);
            }

            if(vidx-vstart<7) {
                // definitely int only. I don't know the exact # of digits that can be in int,
                // but as long as we can catch (0-9999) range, that should be enough.
                if(neg)     n = -n;
                year = n;
                eon = null;
            } else {
                setYear(new BigInteger(value.substring(vstart, vidx)));
            }
        }

        private BigDecimal parseBigDecimal()
                throws IllegalArgumentException {
            int vstart = vidx;

            if (peek() == '.') {
                vidx++;
            } else {
                throw new IllegalArgumentException(value);
            }
            while (isDigit(peek())) {
                vidx++;
            }
            return new BigDecimal(value.substring(vstart, vidx));
        }
    }

    private static boolean isDigit(char ch) {
        return '0' <= ch && ch <= '9';
    }

    /**
     * Prints this object according to the format specification.
     *
     * <p>
     * I wrote a custom format method for a particular format string to
     * see if it improves the performance, but it didn't. So this interpreting
     * approach isn't too bad.
     *
     * <p>
     * StringBuffer -> StringBuilder change had a very visible impact.
     * It almost cut the execution time to half, but unfortunately we can't use it
     * because we need to run on JDK 1.3
     */
    private String format( String format ) {
        char[] buf = new char[32];
        int bufPtr = 0;

        int fidx=0,flen=format.length();

        while(fidx<flen) {
            char fch = format.charAt(fidx++);
            if(fch!='%') {// not a meta char
                buf[bufPtr++] = fch;
                continue;
            }

            switch(format.charAt(fidx++)) {
            case 'Y':
                if(eon==null) {
                    // optimized path
                    int y = getYear();
                    if(y<0) {
                        buf[bufPtr++] = '-';
                        y = -y;
                    }
                    bufPtr = print4Number(buf,bufPtr,y);
                } else {
                    String s = getEonAndYear().toString();
                    // reallocate the buffer now so that it has enough space
                    char[] n = new char[buf.length+s.length()];
                    System.arraycopy(buf,0,n,0,bufPtr);
                    buf = n;
                    for(int i=s.length();i<4;i++)
                        buf[bufPtr++] = '0';
                    s.getChars(0,s.length(),buf,bufPtr);
                    bufPtr += s.length();
                }
                break;
            case 'M':
                bufPtr = print2Number(buf,bufPtr,getMonth());
                break;
            case 'D':
                bufPtr = print2Number(buf,bufPtr,getDay());
                break;
            case 'h':
                bufPtr = print2Number(buf,bufPtr,getHour());
                break;
            case 'm':
                bufPtr = print2Number(buf,bufPtr,getMinute());
                break;
            case 's':
                bufPtr = print2Number(buf,bufPtr,getSecond());
                if (getFractionalSecond() != null) {
                    // Note: toPlainString() isn't available before Java 1.5
                    String frac = getFractionalSecond().toString();

                    int pos = frac.indexOf("E-");
                    if (pos >= 0) {
                        String zeros = frac.substring(pos+2);
                        frac = frac.substring(0,pos);
                        pos = frac.indexOf(".");
                        if (pos >= 0) {
                            frac = frac.substring(0,pos) + frac.substring(pos+1);
                        }
                        int count = Integer.parseInt(zeros);
                        if (count < 40) {
                            frac = "00000000000000000000000000000000000000000".substring(0,count-1) + frac;
                        } else {
                            // do it the hard way
                            while (count > 1) {
                                frac = "0" + frac;
                                count--;
                            }
                        }
                        frac = "0." + frac;
                    }

                    // reallocate the buffer now so that it has enough space
                    char[] n = new char[buf.length+frac.length()];
                    System.arraycopy(buf,0,n,0,bufPtr);
                    buf = n;
                    //skip leading zero.
                    frac.getChars(1, frac.length(), buf, bufPtr);
                    bufPtr += frac.length()-1;
                }
                break;
            case 'z':
                int offset = getTimezone();
                if (offset == 0) {
                    buf[bufPtr++] = 'Z';
                } else
                if (offset != DatatypeConstants.FIELD_UNDEFINED) {
                    if (offset < 0) {
                        buf[bufPtr++] = '-';
                        offset *= -1;
                    } else {
                        buf[bufPtr++] = '+';
                    }
                    bufPtr = print2Number(buf, bufPtr, offset / 60);
                    buf[bufPtr++] = ':';
                    bufPtr = print2Number(buf, bufPtr, offset % 60);
                }
                break;
            default:
                throw new InternalError();  // impossible
            }
        }

        return new String(buf,0,bufPtr);
    }

    /**
     * Prints an int as two digits into the buffer.
     *
     * @param number
     *      Number to be printed. Must be positive.
     */
    private int print2Number( char[] out, int bufptr, int number ) {
        out[bufptr++] = (char) ('0'+(number/10));
        out[bufptr++] = (char) ('0'+(number%10));
        return bufptr;
    }

    /**
     * Prints an int as four digits into the buffer.
     *
     * @param number
     *      Number to be printed. Must be positive.
     */
    private int print4Number( char[] out, int bufptr, int number ) {
        out[bufptr+3] = (char) ('0'+(number%10));
        number /= 10;
        out[bufptr+2] = (char) ('0'+(number%10));
        number /= 10;
        out[bufptr+1] = (char) ('0'+(number%10));
        number /= 10;
        out[bufptr  ] = (char) ('0'+(number%10));
        return bufptr+4;
    }

    /**
     * Compute <code>value*signum</code> where value==null is treated as
     * value==0.
     * @return non-null {@link BigInteger}.
     */
    static BigInteger sanitize(Number value, int signum) {
        if (signum == 0 || value == null) {
            return BigInteger.ZERO;
        }
        return (signum <  0)? ((BigInteger)value).negate() : (BigInteger)value;
    }

    /** <p><code>reset()</code> is designed to allow the reuse of existing
     * <code>XMLGregorianCalendar</code>s thus saving resources associated
     *  with the creation of new <code>XMLGregorianCalendar</code>s.</p>
     */
    public void reset() {
        //PENDING : Implementation of reset method
    }
}
