FileDocCategorySizeDatePackage
XMLGregorianCalendarImpl.javaAPI DocApache Xerces 3.0.1122238Fri Sep 14 20:33:52 BST 2007org.apache.xerces.jaxp.datatype

XMLGregorianCalendarImpl

public class XMLGregorianCalendarImpl extends XMLGregorianCalendar implements Serializable, Cloneable

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 "http://www.w3.org/2001/XMLSchema". These datatypes are normatively defined in W3C XML Schema 1.0 Part 2, Section 3.2.7-14.

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 W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats.

Date/time datatype field mapping between XML Schema 1.0 and Java representation
XML Schema 1.0
datatype
field
Related
XMLGregorianCalendar
Accessor(s)
Value Range
year {@link #getYear()} + {@link #getEon()} or
{@link #getEonAndYear}
getYear() is a value between -(10^9-1) to (10^9)-1 or {@link DatatypeConstants#FIELD_UNDEFINED}.
{@link #getEon()} is high order year value in billion of years.
getEon() 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.
Given that XML Schema 1.0 errata 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.
month {@link #getMonth()} 1 to 12 or {@link DatatypeConstants#FIELD_UNDEFINED}
day {@link #getDay()} Independent of month, max range is 1 to 31 or {@link DatatypeConstants#FIELD_UNDEFINED}.
The normative value constraint stated relative to month field's value is in W3C XML Schema 1.0 Part 2, Appendix D.
hour {@link #getHour()} 0 to 24 or {@link DatatypeConstants#FIELD_UNDEFINED} For a value of 24, the minute and second field must be zero.
minute {@link #getMinute()} 0 to 59 or {@link DatatypeConstants#FIELD_UNDEFINED}
second {@link #getSecond()} + {@link #getMillisecond()}/1000 or
{@link #getSecond()} + {@link #getFractionalSecond()}
{@link #getSecond()} from 0 to 60 or {@link DatatypeConstants#FIELD_UNDEFINED}.
(Note: 60 only allowable for leap second.)
{@link #getFractionalSecond()} allows for infinite precision over the range from 0.0 to 1.0 when the {@link #getSecond()} is defined.
FractionalSecond is optional and has a value of null when it is undefined.
{@link #getMillisecond()} is the convenience millisecond precision of value of {@link #getFractionalSecond()}.
timezone {@link #getTimezone()} Number of minutes or {@link DatatypeConstants#FIELD_UNDEFINED}. Value range from -14 hours (-14 * 60 minutes) to 14 hours (14 * 60 minutes).

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. IllegalArgumentException 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.

The following operations are defined for this class:

author
Kohsuke Kawaguchi
author
Joseph Fialli
version
$Id: XMLGregorianCalendarImpl.java 565110 2007-08-12 18:40:57Z mrglavas $
see
javax.xml.datatype.Duration

Fields Summary
private BigInteger
orig_eon
Backup values
private int
orig_year
private int
orig_month
private int
orig_day
private int
orig_hour
private int
orig_minute
private int
orig_second
private BigDecimal
orig_fracSeconds
private int
orig_timezone
private BigInteger
eon

Eon of this XMLGregorianCalendar.

private int
year

Year of this XMLGregorianCalendar.

private int
month

Month of this XMLGregorianCalendar.

private int
day

Day of this XMLGregorianCalendar.

private int
timezone

Timezone of this XMLGregorianCalendar in minutes.

private int
hour

Hour of this XMLGregorianCalendar.

private int
minute

Minute of this XMLGregorianCalendar.

private int
second

Second of this XMLGregorianCalendar.

private BigDecimal
fractionalSecond

Fractional second of this XMLGregorianCalendar.

private static final BigInteger
BILLION_B

BigInteger constant; representing a billion.

private static final int
BILLION_I

int constant; representing a billion.

private static final Date
PURE_GREGORIAN_CHANGE

Obtain a pure Gregorian Calendar by calling GregorianCalendar.setChange(PURE_GREGORIAN_CHANGE).

private static final int
YEAR
Year index for MIN_ and MAX_FIELD_VALUES.
private static final int
MONTH
Month index for MIN_ and MAX_FIELD_VALUES.
private static final int
DAY
Day index for MIN_ and MAX_FIELD_VALUES.
private static final int
HOUR
Hour index for MIN_ and MAX_FIELD_VALUES.
private static final int
MINUTE
Minute index for MIN_ and MAX_FIELD_VALUES.
private static final int
SECOND
Second index for MIN_ and MAX_FIELD_VALUES.
private static final int
MILLISECOND
Second index for MIN_ and MAX_FIELD_VALUES.
private static final int
TIMEZONE
Timezone index for MIN_ and MAX_FIELD_VALUES
private static final int[]
MIN_FIELD_VALUE
Minimum field values indexed by YEAR..TIMEZONE.
private static final int[]
MAX_FIELD_VALUE
Maximum field values indexed by YEAR..TIMEZONE.
private static final String[]
FIELD_NAME
field names indexed by YEAR..TIMEZONE.
private static final long
serialVersionUID

Stream Unique Identifier.

TODO: Serialization should use the XML string representation as the serialization format to ensure future compatibility.

public static final XMLGregorianCalendar
LEAP_YEAR_DEFAULT

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.

Fields that are optional for an xsd:dateTime instances are defaulted to not being set to any value. XMLGregorianCalendar 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 null for fractional second.

private static final BigInteger
FOUR
private static final BigInteger
HUNDRED
private static final BigInteger
FOUR_HUNDRED
private static final BigInteger
SIXTY
private static final BigInteger
TWENTY_FOUR
private static final BigInteger
TWELVE
private static final BigDecimal
DECIMAL_ZERO
private static final BigDecimal
DECIMAL_ONE
private static final BigDecimal
DECIMAL_SIXTY
Constructors Summary
protected XMLGregorianCalendarImpl(String lexicalRepresentation)
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.


    // Constructors

                                                                                                  
      
          

        // 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.
        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
                // Fix 4971612: invalid SCCS macro substitution in data string
                format = "---%D" + "%z";
            } 
            else if (lexRepLength == 4 || (lexRepLength >= 6 && (lexRep.charAt(4) == '+" || (lexRep.charAt(4) == '-" && (lexRep.charAt(5) == '-" || lexRepLength == 10))))) {
                // GMonth
                // Fix 4971612: invalid SCCS macro substitution in data string
                format = "--%M--%z";
                Parser p = new Parser(format, lexRep);
                try {
                    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."
                        );
                    }
                    save();
                    return;
                }
                catch(IllegalArgumentException e) {
                    format = "--%M%z";
                }
            } 
            else {
                // GMonthDay or invalid lexicalRepresentation
                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."
            );
        }
        save();
    
public XMLGregorianCalendarImpl()

Create an instance with all date/time datatype fields set to {@link DatatypeConstants#FIELD_UNDEFINED} or null respectively.

    	
        // field initializers already do the correct initialization.
    
protected XMLGregorianCalendarImpl(BigInteger year, int month, int day, int hour, int minute, int second, BigDecimal fractionalSecond, int timezone)

Private constructor allowing for complete value spaces allowed by W3C XML Schema 1.0 recommendation for xsd:dateTime and related builtin datatypes. Note that year parameter supports arbitrarily large numbers and fractionalSecond has infinite precision.

param
year of XMLGregorianCalendar to be created.
param
month of XMLGregorianCalendar to be created.
param
day of XMLGregorianCalendar to be created.
param
hour of XMLGregorianCalendar to be created.
param
minute of XMLGregorianCalendar to be created.
param
second of XMLGregorianCalendar to be created.
param
fractionalSecond of XMLGregorianCalendar to be created.
param
timezone of XMLGregorianCalendar to be created.

        	
		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."
                );
                */
            
		}
        
        save();
		
    
private XMLGregorianCalendarImpl(int year, int month, int day, int hour, int minute, int second, int millisecond, int timezone)

Private constructor of value spaces that a java.util.GregorianCalendar instance would need to convert to an XMLGregorianCalendar instance.

XMLGregorianCalendar eon and fractionalSecond are set to null

param
year of XMLGregorianCalendar to be created.
param
month of XMLGregorianCalendar to be created.
param
day of XMLGregorianCalendar to be created.
param
hour of XMLGregorianCalendar to be created.
param
minute of XMLGregorianCalendar to be created.
param
second of XMLGregorianCalendar to be created.
param
millisecond of XMLGregorianCalendar to be created.
param
timezone of XMLGregorianCalendar to be created.


        setYear(year);
        setMonth(month);
        setDay(day);
        setTime(hour, minute, second);
        setTimezone(timezone);
        BigDecimal realMilliseconds = null;
        if (millisecond != DatatypeConstants.FIELD_UNDEFINED) {
            realMilliseconds = BigDecimal.valueOf(millisecond, 3);
        }
        setFractionalSecond(realMilliseconds);

        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."
                    );
             */

        }
        save();
    
public XMLGregorianCalendarImpl(GregorianCalendar cal)

Convert a java.util.GregorianCalendar to XML Schema 1.0 representation.

Field by Field Conversion from java.util.GregorianCalendar to this class
javax.xml.datatype.XMLGregorianCalendar field java.util.GregorianCalendar field
{@link #setYear(int)} ERA == GregorianCalendar.BC ? -YEAR : YEAR
{@link #setMonth(int)} MONTH + 1
{@link #setDay(int)} DAY_OF_MONTH
{@link #setTime(int,int,int, BigDecimal)} HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND
{@link #setTimezone(int)}* (ZONE_OFFSET + DST_OFFSET) / (60*1000)
(in minutes)

*conversion loss of information. It is not possible to represent a java.util.GregorianCalendar daylight savings timezone id in the XML Schema 1.0 date/time datatype representation.

To compute the return value's TimeZone field,

  • when this.getTimezone() != DatatypeConstants.FIELD_UNDEFINED, create a java.util.TimeZone with a custom timezone id using the this.getTimezone().
  • else use the GregorianCalendar default timezone value for the host is defined as specified by java.util.TimeZone.getDefault().
  • param
    cal java.util.GregorianCalendar used to create XMLGregorianCalendar

    
            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);
            save();
        
Methods Summary
public voidadd(javax.xml.datatype.Duration duration)

Add duration to this instance.<\p>

The computation is specified in XML Schema 1.0 Part 2, Appendix E, Adding durations to dateTimes>. date/time field mapping table defines the mapping from XML Schema 1.0 dateTime fields to this class' representation of those fields.

param
duration Duration to add to this XMLGregorianCalendar.
throws
NullPointerException when duration parameter is null.


        /*
         * 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 = MIN_FIELD_VALUE[MONTH];
            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 = MIN_FIELD_VALUE[MINUTE];
        }
        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 = MIN_FIELD_VALUE[HOUR];
        }
        BigInteger dHours = sanitize(duration.getField(DatatypeConstants.HOURS), signum);

        temp = BigInteger.valueOf(startHours).add(dHours).add(carry);
        setHour(temp.mod(TWENTY_FOUR).intValue());
        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 = MIN_FIELD_VALUE[DAY];
        }
        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 = BigDecimal.valueOf(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);
                        break;
                    case MINUTE:
                        setMinute(DatatypeConstants.FIELD_UNDEFINED);
                        break;
                    case SECOND:
                        setSecond(DatatypeConstants.FIELD_UNDEFINED);
                        setFractionalSecond(null);
                        break;
                }
            }
        }
    
private voidcheckFieldValueConstraint(int field, int value)

        if ((value < MIN_FIELD_VALUE[field] && value != DatatypeConstants.FIELD_UNDEFINED) ||
                value > MAX_FIELD_VALUE[field]) {
            /**
            throw new IllegalArgumentException("invalid value " + value +
					       " for " + FIELD_NAME[field] +
					       " field");
             */
            throw new IllegalArgumentException(
                    DatatypeMessageFormatter.formatMessage(null, "InvalidFieldValue", new Object[]{ new Integer(value), FIELD_NAME[field]})
            );
        }
    
public voidclear()

Unset all fields to undefined.

Set all int fields to {@link DatatypeConstants#FIELD_UNDEFINED} and reference fields to null.

       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 java.lang.Objectclone()

Creates and returns a copy of this object.

return
copy of this Object

        // 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);
    
public intcompare(javax.xml.datatype.XMLGregorianCalendar rhs)

Compare two instances of W3C XML Schema 1.0 date/time datatypes according to partial order relation defined in W3C XML Schema 1.0 Part 2, Section 3.2.7.3, Order relation on dateTime.

xsd:dateTime datatype field mapping to accessors of this class are defined in date/time field mapping table.

param
rhs instance of XMLGregorianCalendar to compare
return
the relationship between lhs and rhs as {@link DatatypeConstants#LESSER}, {@link DatatypeConstants#EQUAL}, {@link DatatypeConstants#GREATER} or {@link DatatypeConstants#INDETERMINATE}.
throws
NullPointerException if lhs or rhs parameters are null.


        //MLGregorianCalendar lhs = this;

        int result = DatatypeConstants.INDETERMINATE;
        XMLGregorianCalendar P = this;
        XMLGregorianCalendar Q = 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 = normalizeToTimezone(Q, DatatypeConstants.MIN_TIMEZONE_OFFSET);
            result = internalCompare(P, MinQ);
            if (result == DatatypeConstants.LESSER) {
                return result;
            } 

            // C. step 2
            XMLGregorianCalendar MaxQ = normalizeToTimezone(Q, 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) normalizeToTimezone(Q, Q.getTimezone());
            }

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

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

Implement Step B from http://www.w3.org/TR/xmlschema-2/#dateTime-order.

        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 intcompareField(java.math.BigInteger Pfield, java.math.BigInteger Qfield)

        if (Pfield == null) {
            return (Qfield == null ? DatatypeConstants.EQUAL : DatatypeConstants.INDETERMINATE);
        }
        if (Qfield == null) {
            return DatatypeConstants.INDETERMINATE;
        }
        return Pfield.compareTo(Qfield);
    
private static intcompareField(java.math.BigDecimal Pfield, java.math.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);
    
public static javax.xml.datatype.XMLGregorianCalendarcreateDate(int year, int month, int day, int timezone)

Create a Java representation of XML Schema builtin datatype date or g*.

For example, an instance of gYear can be created invoking this factory with month and day parameters set to {@link DatatypeConstants#FIELD_UNDEFINED}.

param
year of XMLGregorianCalendar to be created.
param
month of XMLGregorianCalendar to be created.
param
day of XMLGregorianCalendar to be created.
param
timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
return
XMLGregorianCalendar created from parameter values.
see
DatatypeConstants#FIELD_UNDEFINED
throws
IllegalArgumentException if any parameter is outside value constraints for the field as specified in date/time field mapping table.


        return new XMLGregorianCalendarImpl(
                year,
                month,
                day,
                DatatypeConstants.FIELD_UNDEFINED, // hour
                DatatypeConstants.FIELD_UNDEFINED, // minute
                DatatypeConstants.FIELD_UNDEFINED, // second
                DatatypeConstants.FIELD_UNDEFINED, // millisecond
                timezone);
    
public static javax.xml.datatype.XMLGregorianCalendarcreateDateTime(java.math.BigInteger year, int month, int day, int hours, int minutes, int seconds, java.math.BigDecimal fractionalSecond, int timezone)

Create a Java representation of XML Schema builtin datatype dateTime. All possible fields are specified for this factory method.

param
year represents both high-order eons and low-order year.
param
month of dateTime
param
day of dateTime
param
hours of dateTime
param
minutes of dateTime
param
seconds of dateTime
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
XMLGregorianCalendar created from parameter values.
see
DatatypeConstants#FIELD_UNDEFINED
throws
IllegalArgumentException if any parameter is outside value constraints for the field as specified in date/time field mapping table.


	    return new XMLGregorianCalendarImpl(
	            year,
	            month, 
	            day, 
	            hours,
	            minutes,
	            seconds, 
	            fractionalSecond,
	            timezone);
	
public static javax.xml.datatype.XMLGregorianCalendarcreateDateTime(int year, int month, int day, int hour, int minute, int second)

Create a Java instance of XML Schema builtin datatype dateTime.

param
year represents both high-order eons and low-order year.
param
month of dateTime
param
day of dateTime
param
hour of dateTime
param
minute of dateTime
param
second of dateTime
return
XMLGregorianCalendar created from parameter values.
throws
IllegalArgumentException if any parameter is outside value constraints for the field as specified in date/time field mapping table.
see
DatatypeConstants#FIELD_UNDEFINED


        return new XMLGregorianCalendarImpl(
                year,
                month,
                day,
                hour,
                minute,
                second,
                DatatypeConstants.FIELD_UNDEFINED,  //millisecond
                DatatypeConstants.FIELD_UNDEFINED //timezone
        );
    
public static javax.xml.datatype.XMLGregorianCalendarcreateDateTime(int year, int month, int day, int hours, int minutes, int seconds, int milliseconds, int timezone)

Create a Java representation of XML Schema builtin datatype dateTime. All possible fields are specified for this factory method.

param
year represents low-order year.
param
month of dateTime
param
day of dateTime
param
hours of dateTime
param
minutes of dateTime
param
seconds of dateTime
param
milliseconds of dateTime. {@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
XMLGregorianCalendar created from parameter values.
throws
IllegalArgumentException if any parameter is outside value constraints for the field as specified in date/time field mapping table.
see
DatatypeConstants#FIELD_UNDEFINED


        return new XMLGregorianCalendarImpl(
                year,
                month,
                day,
                hours,
                minutes,
                seconds,
                milliseconds,
                timezone);
    
public static javax.xml.datatype.XMLGregorianCalendarcreateTime(int hours, int minutes, int seconds, int timezone)
Create a Java instance of XML Schema builtin datatype time.

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
XMLGregorianCalendar created from parameter values.
see
DatatypeConstants#FIELD_UNDEFINED
throws
IllegalArgumentException if any parameter is outside value constraints for the field as specified in date/time field mapping table.


        return new XMLGregorianCalendarImpl(
                DatatypeConstants.FIELD_UNDEFINED, // Year
                DatatypeConstants.FIELD_UNDEFINED, // Month
                DatatypeConstants.FIELD_UNDEFINED, // Day
                hours,
                minutes,
                seconds, 
                DatatypeConstants.FIELD_UNDEFINED, //Millisecond
                timezone);
    
public static javax.xml.datatype.XMLGregorianCalendarcreateTime(int hours, int minutes, int seconds, java.math.BigDecimal fractionalSecond, int timezone)

Create a Java instance of XML Schema builtin datatype time.

param
hours number of hours
param
minutes number of minutes
param
seconds number of seconds
param
fractionalSecond value of null indicates that this optional field is not set.
param
timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
return
XMLGregorianCalendar created from parameter values.
see
DatatypeConstants#FIELD_UNDEFINED
throws
IllegalArgumentException if any parameter is outside value constraints for the field as specified in date/time field mapping table.


        return new XMLGregorianCalendarImpl(
                null,            // Year
                DatatypeConstants.FIELD_UNDEFINED, // month
                DatatypeConstants.FIELD_UNDEFINED, // day
                hours,
                minutes,
                seconds,
                fractionalSecond,
                timezone);
    
public static javax.xml.datatype.XMLGregorianCalendarcreateTime(int hours, int minutes, int seconds, int milliseconds, int timezone)

Create a Java instance of XML Schema builtin datatype time.

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
XMLGregorianCalendar created from parameter values.
see
DatatypeConstants#FIELD_UNDEFINED
throws
IllegalArgumentException if any parameter is outside value constraints for the field as specified in date/time field mapping table.


        return new XMLGregorianCalendarImpl(
                DatatypeConstants.FIELD_UNDEFINED, // year
                DatatypeConstants.FIELD_UNDEFINED, // month
                DatatypeConstants.FIELD_UNDEFINED, // day
                hours,
                minutes,
                seconds,
                milliseconds,
                timezone);
    
public booleanequals(java.lang.Object obj)

Indicates whether parameter obj is "equal to" this one.

param
obj to compare.
return
true when compare(this,(XMLGregorianCalendar)obj) == EQUAL..

	   boolean result = false;
	   if (obj instanceof XMLGregorianCalendar) {
	       result = compare((XMLGregorianCalendar) obj) == DatatypeConstants.EQUAL;
	   }
	   return result;
    
private java.lang.Stringformat(java.lang.String format)

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

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

            switch(format.charAt(fidx++)) {
                case 'Y":
                    if (eon == null) {
                        int absYear = year;
                        if (absYear < 0) {
                            buf.append('-");
                            absYear = -year;
                        }
                        printNumber(buf, absYear, 4);
                    }
                    else {
                        printNumber(buf, getEonAndYear(), 4);
                    }
                    break;
                case 'M":
                    printNumber(buf,getMonth(),2);
                    break;
                case 'D":
                    printNumber(buf,getDay(),2);
                    break;
                case 'h":
                    printNumber(buf,getHour(),2);
                    break;
                case 'm":
                    printNumber(buf,getMinute(),2);
                    break;
                case 's":
                    printNumber(buf,getSecond(),2);
                    if (getFractionalSecond() != null) {
                        String frac = toString(getFractionalSecond());
                        //skip leading zero.
                        buf.append(frac.substring(1, frac.length()));
                    } 
                    break;
                case 'z":
                    int offset = getTimezone();
                    if (offset == 0) {
                        buf.append('Z");
                    } 
                    else if (offset != DatatypeConstants.FIELD_UNDEFINED) {
                        if (offset < 0) {
                            buf.append('-");
                            offset *= -1; 
                        } 
                        else {
                            buf.append('+");
                        }
                        printNumber(buf,offset/60,2);
                        buf.append(':");
                        printNumber(buf,offset%60,2);
                    }
                    break;
                default:
                    throw new InternalError();  // impossible
            }
        }

        return buf.toString();
    
public intgetDay()
Return day in month or {@link DatatypeConstants#FIELD_UNDEFINED}.

Value constraints for this value are summarized in day field of date/time field mapping table.

see
#setDay(int)

        return day;
    
public java.math.BigIntegergetEon()

Return high order component for XML Schema 1.0 dateTime datatype field for year. null if this optional part of the year field is not defined.

Value constraints for this value are summarized in year field of date/time field mapping table.

return
eon of this XMLGregorianCalendar. The value returned is an integer multiple of 10^9.
see
#getYear()
see
#getEonAndYear()

	   return eon;
    
public java.math.BigIntegergetEonAndYear()

Return XML Schema 1.0 dateTime datatype field for year.

Value constraints for this value are summarized in year field of date/time field mapping table.

return
sum of eon and BigInteger.valueOf(year) when both fields are defined. When only year is defined, return it. When both eon and year are not defined, return null.
see
#getEon()
see
#getYear()


        // 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;
    
public java.math.BigDecimalgetFractionalSecond()

Return fractional seconds.

null is returned when this optional field is not defined.

Value constraints are detailed in second field of date/time field mapping table.

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}).

return
fractional seconds of this XMLGregorianCalendar.
see
#getSecond()
see
#setTime(int, int, int, BigDecimal)

	   return fractionalSecond;
    
public intgetHour()
Return hours or {@link DatatypeConstants#FIELD_UNDEFINED}. Returns {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined.

Value constraints for this value are summarized in hour field of date/time field mapping table.

see
#setTime(int, int, int)

        return hour;
    
public intgetMillisecond()

Return millisecond precision of {@link #getFractionalSecond()}.<\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 null, this method must return {@link DatatypeConstants#FIELD_UNDEFINED}.

Value constraints for this value are summarized in second field of date/time field mapping table.

return
Millisecond of this XMLGregorianCalendar.
see
#getFractionalSecond()
see
#setTime(int, int, int)

        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();
        }
    
public intgetMinute()
Return minutes or {@link DatatypeConstants#FIELD_UNDEFINED}.<\p> Returns {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined.

Value constraints for this value are summarized in minute field of date/time field mapping table.

see
#setTime(int, int, int)

        return minute;
    
public intgetMonth()

Return number of month or {@link DatatypeConstants#FIELD_UNDEFINED}.

Value constraints for this value are summarized in month field of date/time field mapping table.

return
year of this XMLGregorianCalendar.

        return month;
    
public intgetSecond()

Return seconds or {@link DatatypeConstants#FIELD_UNDEFINED}.<\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.

Value constraints for this value are summarized in second field of date/time field mapping table.

return
Second of this XMLGregorianCalendar.
see
#getFractionalSecond()
see
#getMillisecond()
see
#setTime(int, int, int)

	   return second;
    
private java.math.BigDecimalgetSeconds()

return
result of adding second and fractional second field


        if (second == DatatypeConstants.FIELD_UNDEFINED) {
            return DECIMAL_ZERO;
        } 
        BigDecimal result = BigDecimal.valueOf((long)second);
        if (fractionalSecond != null){
            return result.add(fractionalSecond);
        } 
        else {
            return result;
        }
    
public java.util.TimeZonegetTimeZone(int defaultZoneoffset)

Returns a java.util.TimeZone for this class.

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).

param
defaultZoneoffset default zoneoffset if this zoneoffset is {@link DatatypeConstants#FIELD_UNDEFINED}.
return
TimeZone for this.

        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) {
                if (minutes < 10) {
                    customTimezoneId.append('0");
                }
                customTimezoneId.append(minutes);
            }
            result = TimeZone.getTimeZone(customTimezoneId.toString());
        }
        return result;
    
public intgetTimezone()
Return timezone offset in minutes or {@link DatatypeConstants#FIELD_UNDEFINED} if this optional field is not defined.

Value constraints for this value are summarized in timezone field of date/time field mapping table.

see
#setTimezone(int)

        return timezone;
    
public javax.xml.namespace.QNamegetXMLSchemaType()

Return the name of the XML Schema date/time type that this instance maps to. Type is computed based on fields that are set.

Required fields for XML Schema 1.0 Date/Time Datatypes.
(timezone is optional for all date/time datatypes)
Datatype year month day hour minute second
{@link DatatypeConstants#DATETIME} X X X X X X
{@link DatatypeConstants#DATE} X X X
{@link DatatypeConstants#TIME} X X X
{@link DatatypeConstants#GYEARMONTH} X X
{@link DatatypeConstants#GMONTHDAY} X X
{@link DatatypeConstants#GYEAR} X
{@link DatatypeConstants#GMONTH} X
{@link DatatypeConstants#GDAY} X

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}.

    	
    	// DATETIME
    	if (year != DatatypeConstants.FIELD_UNDEFINED
    		&& month != DatatypeConstants.FIELD_UNDEFINED
			&& day != DatatypeConstants.FIELD_UNDEFINED
			&& hour != DatatypeConstants.FIELD_UNDEFINED
			&& minute != DatatypeConstants.FIELD_UNDEFINED
			&& second != DatatypeConstants.FIELD_UNDEFINED) {
    		return DatatypeConstants.DATETIME;
    	}

    	// DATE
    	if (year != DatatypeConstants.FIELD_UNDEFINED
    		&& month != DatatypeConstants.FIELD_UNDEFINED
			&& day != DatatypeConstants.FIELD_UNDEFINED
			&& hour == DatatypeConstants.FIELD_UNDEFINED
			&& minute == DatatypeConstants.FIELD_UNDEFINED
			&& second == DatatypeConstants.FIELD_UNDEFINED) {
    		return DatatypeConstants.DATE;
    	}

    	// TIME
    	if (year == DatatypeConstants.FIELD_UNDEFINED
    		&& month == DatatypeConstants.FIELD_UNDEFINED
			&& day == DatatypeConstants.FIELD_UNDEFINED
			&& hour != DatatypeConstants.FIELD_UNDEFINED
			&& minute != DatatypeConstants.FIELD_UNDEFINED
			&& second != DatatypeConstants.FIELD_UNDEFINED) {
    		return DatatypeConstants.TIME;
    	}


    	// GYEARMONTH
    	if (year != DatatypeConstants.FIELD_UNDEFINED
    		&& month != DatatypeConstants.FIELD_UNDEFINED
			&& day == DatatypeConstants.FIELD_UNDEFINED
			&& hour == DatatypeConstants.FIELD_UNDEFINED
			&& minute == DatatypeConstants.FIELD_UNDEFINED
			&& second == DatatypeConstants.FIELD_UNDEFINED) {
    		return DatatypeConstants.GYEARMONTH;
    	}

    	// GMONTHDAY
    	if (year == DatatypeConstants.FIELD_UNDEFINED
    		&& month != DatatypeConstants.FIELD_UNDEFINED
			&& day != DatatypeConstants.FIELD_UNDEFINED
			&& hour == DatatypeConstants.FIELD_UNDEFINED
			&& minute == DatatypeConstants.FIELD_UNDEFINED
			&& second == DatatypeConstants.FIELD_UNDEFINED) {
    		return DatatypeConstants.GMONTHDAY;
    	}

    	// GYEAR
    	if (year != DatatypeConstants.FIELD_UNDEFINED
    		&& month == DatatypeConstants.FIELD_UNDEFINED
			&& day == DatatypeConstants.FIELD_UNDEFINED
			&& hour == DatatypeConstants.FIELD_UNDEFINED
			&& minute == DatatypeConstants.FIELD_UNDEFINED
			&& second == DatatypeConstants.FIELD_UNDEFINED) {
    		return DatatypeConstants.GYEAR;
    	}

    	// GMONTH
    	if (year == DatatypeConstants.FIELD_UNDEFINED
    		&& month != DatatypeConstants.FIELD_UNDEFINED
			&& day == DatatypeConstants.FIELD_UNDEFINED
			&& hour == DatatypeConstants.FIELD_UNDEFINED
			&& minute == DatatypeConstants.FIELD_UNDEFINED
			&& second == DatatypeConstants.FIELD_UNDEFINED) {
    		return DatatypeConstants.GMONTH;
    	}

    	// GDAY
    	if (year == DatatypeConstants.FIELD_UNDEFINED
    		&& month == DatatypeConstants.FIELD_UNDEFINED
			&& day != DatatypeConstants.FIELD_UNDEFINED
			&& hour == DatatypeConstants.FIELD_UNDEFINED
			&& minute == DatatypeConstants.FIELD_UNDEFINED
			&& second == DatatypeConstants.FIELD_UNDEFINED) {
    		return DatatypeConstants.GDAY;
    	}

    	// unknown
		throw new IllegalStateException(
			this.getClass().getName()
			+ "#getXMLSchemaType() :"
            + DatatypeMessageFormatter.formatMessage(null, "InvalidXGCFields", null)
		);
    
public intgetYear()

Return low order component for XML Schema 1.0 dateTime datatype field for year or {@link DatatypeConstants#FIELD_UNDEFINED}.

Value constraints for this value are summarized in year field of date/time field mapping table.

return
year of this XMLGregorianCalendar.
see
#getEon()
see
#getEonAndYear()

	   return year;
    
public inthashCode()

Returns a hash code consistent with the definition of the equals method.

return
hash code of this object.


        // 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 = normalizeToTimezone(this, getTimezone());
        }
        return gc.getYear() + gc.getMonth() + gc.getDay() + 
        gc.getHour() + gc.getMinute() + gc.getSecond();
    
private static intinternalCompare(javax.xml.datatype.XMLGregorianCalendar P, javax.xml.datatype.XMLGregorianCalendar Q)

Implements Step B from http://www.w3.org/TR/xmlschema-2/#dateTime-order

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}.


	    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;
	
private static booleanisDigit(char ch)

        return '0" <= ch && ch <= '9";
    
public booleanisValid()
Validate instance by getXMLSchemaType() constraints.

return
true if data values are valid.

        // 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 (month != DatatypeConstants.FIELD_UNDEFINED && day != DatatypeConstants.FIELD_UNDEFINED) {
            if (year != DatatypeConstants.FIELD_UNDEFINED) {
                if (eon == null) {
                    if (day > maximumDayInMonthFor(year, month)) {
                        return false;
                    }
                }
                else if (day > maximumDayInMonthFor(getEonAndYear(), month)) {
                    return false;
                }
            }
            // Use 2000 as a default since it's a leap year.
            else if (day > maximumDayInMonthFor(2000, month)) {
                return false;
            }
        }

        // http://www.w3.org/2001/05/xmlschema-errata#e2-45
        if (hour == 24 && (minute != 0 || second != 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 && year == 0) {
            return false;
        }
        return true;
    
private static intmaximumDayInMonthFor(java.math.BigInteger year, int month)

    

           
        if (month != DatatypeConstants.FEBRUARY) {
            return DaysInMonth.table[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.table[month];
            }
        }
    
private static intmaximumDayInMonthFor(int year, int month)

        if (month != DatatypeConstants.FEBRUARY) {
            return DaysInMonth.table[month];
        } 
        else {
            if ( ((year %400) == 0) || 
                    ( ((year % 100) != 0) && ((year % 4) == 0))) {
                // is a leap year.
                return 29;
            } 
            else {
                return DaysInMonth.table[DatatypeConstants.FEBRUARY];
            }
        }
    
public javax.xml.datatype.XMLGregorianCalendarnormalize()

Normalize this instance to UTC.

2000-03-04T23:00:00+03:00 normalizes to 2000-03-04T20:00:00Z

Implements W3C XML Schema Part 2, Section 3.2.7.3 (A).


        XMLGregorianCalendar normalized = normalizeToTimezone(this, 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;
    
private javax.xml.datatype.XMLGregorianCalendarnormalizeToTimezone(javax.xml.datatype.XMLGregorianCalendar cal, int timezone)

Normalize this instance to UTC.

2000-03-04T23:00:00+03:00 normalizes to 2000-03-04T20:00:00Z

Implements W3C XML Schema Part 2, Section 3.2.7.3 (A).


        int minutes = timezone;    	
        XMLGregorianCalendar result = (XMLGregorianCalendar) cal.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;
    
public static javax.xml.datatype.XMLGregorianCalendarparse(java.lang.String lexicalRepresentation)

Constructs a new XMLGregorianCalendar object by parsing its lexical string representation as defined in XML Schema 1.0 Part 2, Section 3.2.[7-14].1, Lexical Representation.

The string representation may not have any leading and trailing whitespaces.

The parsing is done field by field so that the following holds for any lexically correct string x:

new XMLGregorianCalendar(x).toXMLFormat().equals(x)
Except for the noted lexical/canonical representation mismatches listed in XML Schema 1.0 errata, Section 3.2.7.2.

Returns a non-null valid XMLGregorianCalendar object that holds the value indicated by the lexicalRepresentation parameter.

param
lexicalRepresentation Lexical representation of one the 8 XML Schema calendar datatypes.
return
XMLGregorianCalendar created from parsing lexicalRepresentation parameter.
throws
IllegalArgumentException If the given string does not conform to the aforementioned specification.
throws
NullPointerException If the given string is null.

    	
		return new XMLGregorianCalendarImpl(lexicalRepresentation);
    
private voidprintNumber(java.lang.StringBuffer out, int number, int nDigits)
Prints an integer as a String.

param
out The formatted string will be appended into this buffer.
param
number The integer to be printed.
param
nDigits The field will be printed by using at least this number of digits. For example, 5 will be printed as "0005" if nDigits==4.

        String s = String.valueOf(number);
        for (int i = s.length(); i < nDigits; i++) {
            out.append('0");
        }
        out.append(s);
    
private voidprintNumber(java.lang.StringBuffer out, java.math.BigInteger number, int nDigits)
Prints an BigInteger as a String.

param
out The formatted string will be appended into this buffer.
param
number The integer to be printed.
param
nDigits The field will be printed by using at least this number of digits. For example, 5 will be printed as "0005" if nDigits==4.

        String s = number.toString();
        for (int i=s.length(); i < nDigits; i++) {
            out.append('0");
        }
        out.append(s);
    
public voidreset()

reset() is designed to allow the reuse of existing XMLGregorianCalendars thus saving resources associated with the creation of new XMLGregorianCalendars.

        eon = orig_eon;
        year = orig_year;
        month = orig_month;
        day = orig_day;
        hour = orig_hour;
        minute = orig_minute;
        second = orig_second;
        fractionalSecond = orig_fracSeconds;
        timezone = orig_timezone;
    
static java.math.BigIntegersanitize(java.lang.Number value, int signum)
Compute value*signum where value==null is treated as value==0.

return
non-null {@link BigInteger}.

        if (signum == 0 || value == null) {
            return BigInteger.ZERO;
        }
        return (signum <  0)? ((BigInteger)value).negate() : (BigInteger)value;
    
private voidsave()

        orig_eon = eon;
        orig_year = year;
        orig_month = month;
        orig_day = day;
        orig_hour = hour;
        orig_minute = minute;
        orig_second = second;
        orig_fracSeconds = fractionalSecond;
        orig_timezone = timezone;
    
public voidsetDay(int day)

Set days in month.

Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

param
day value constraints summarized in day field of date/time field mapping table.
throws
IllegalArgumentException if day parameter is outside value constraints for the field as specified in date/time field mapping table.

  
        checkFieldValueConstraint(DAY, day);
        this.day = day;
    
private voidsetEon(java.math.BigInteger eon)

Set high order part of XSD dateTime year field.

Unset this field by invoking the setter with a parameter value of null.

param
eon value constraints summarized in year field of date/time field mapping table.

        if (eon != null && eon.compareTo(BigInteger.ZERO) == 0) {
            // Treat ZERO as field being undefined.
            this.eon = null;
        } 
        else {
            this.eon = eon;
        }
    
public voidsetFractionalSecond(java.math.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;
    
public voidsetHour(int hour)

        checkFieldValueConstraint(HOUR, hour);
        this.hour = hour;
    
public voidsetMillisecond(int millisecond)

        if (millisecond == DatatypeConstants.FIELD_UNDEFINED) {
            fractionalSecond = null;
        } 
        else {
            checkFieldValueConstraint(MILLISECOND, millisecond);
            fractionalSecond = BigDecimal.valueOf(millisecond, 3);
        } 
    
public voidsetMinute(int minute)

        checkFieldValueConstraint(MINUTE, minute);
        this.minute = minute;
    
public voidsetMonth(int month)

Set month.

Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

param
month value constraints summarized in month field of date/time field mapping table.
throws
IllegalArgumentException if month parameter is outside value constraints for the field as specified in date/time field mapping table.

 
        checkFieldValueConstraint(MONTH, month);
        this.month = month;
    
public voidsetSecond(int second)

        checkFieldValueConstraint(SECOND, second);
        this.second  = second;
    
public voidsetTime(int hour, int minute, int second)

Set time as one unit.

param
hour value constraints are summarized in hour field of date/time field mapping table.
param
minute value constraints are summarized in minute field of date/time field mapping table.
param
second value constraints are summarized in second field of date/time field mapping table.
see
#setTime(int, int, int, BigDecimal)
throws
IllegalArgumentException if any parameter is outside value constraints for the field as specified in date/time field mapping table.

        setTime(hour, minute, second, null);
    
public voidsetTime(int hour, int minute, int second, java.math.BigDecimal fractional)

Set time as one unit, including the optional infinite precison fractional seconds.

param
hour value constraints are summarized in hour field of date/time field mapping table.
param
minute value constraints are summarized in minute field of date/time field mapping table.
param
second value constraints are summarized in second field of date/time field mapping table.
param
fractional value of null indicates this optional field is not set.
throws
IllegalArgumentException if any parameter is outside value constraints for the field as specified in date/time field mapping table.

        setHour(hour);
        setMinute(minute);
        setSecond(second);
        setFractionalSecond(fractional);
    
public voidsetTime(int hour, int minute, int second, int millisecond)

Set time as one unit, including optional milliseconds.

param
hour value constraints are summarized in hour field of date/time field mapping table.
param
minute value constraints are summarized in minute field of date/time field mapping table.
param
second value constraints are summarized in second field of date/time field mapping table.
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 date/time field mapping table.

        setHour(hour);
        setMinute(minute);
        setSecond(second);
        setMillisecond(millisecond);
    
public voidsetTimezone(int offset)

Set the number of minutes in the timezone offset.

Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

param
offset value constraints summarized in timezone field of date/time field mapping table.
throws
IllegalArgumentException if offset parameter is outside value constraints for the field as specified in date/time field mapping table.

        checkFieldValueConstraint(TIMEZONE, offset);
        this.timezone = offset;
    
public voidsetYear(java.math.BigInteger year)

Set low and high order component of XSD dateTime year field.

Unset this field by invoking the setter with a parameter value of null.

param
year value constraints summarized in year field of date/time field mapping table.
throws
IllegalArgumentException if year parameter is outside value constraints for the field as specified in date/time field mapping table.

        if (year == null) {
            this.eon = null;
            this.year = DatatypeConstants.FIELD_UNDEFINED;
        } 
        else {
            BigInteger temp = year.remainder(BILLION_B);
            this.year = temp.intValue();
            setEon(year.subtract(temp));
        }
    
public voidsetYear(int year)

Set year of XSD dateTime year field.

Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

Note: if the absolute value of the year parameter is less than 10^9, the eon component of the XSD year field is set to null by this method.

param
year value constraints are summarized in year field of date/time field mapping table. If year is {@link DatatypeConstants#FIELD_UNDEFINED}, then eon is set to null.

 
        if (year == DatatypeConstants.FIELD_UNDEFINED) {
            this.year = DatatypeConstants.FIELD_UNDEFINED;
            this.eon = null;
        } 
        else if (Math.abs(year) < BILLION_I) {
            this.year = year;
            this.eon = null;
        } 
        else {
            BigInteger theYear = BigInteger.valueOf((long) year);
            BigInteger remainder = theYear.remainder(BILLION_B);
            this.year = remainder.intValue();
            setEon(theYear.subtract(remainder));
        }
    
public java.util.GregorianCalendartoGregorianCalendar()

Convert this to java.util.GregorianCalendar.

When this instance has an undefined field, this conversion relies on the java.util.GregorianCalendar default for its corresponding field. A notable difference between XML Schema 1.0 date/time datatypes and java.util.GregorianCalendar is that Timezone value is optional for date/time datatypes and it is a required field for java.util.GregorianCalendar. See javadoc for java.util.TimeZone.getDefault() on how the default is determined. To explicitly specify the TimeZone instance, see {@link #toGregorianCalendar(TimeZone, Locale, XMLGregorianCalendar)}.

Field by Field Conversion from this class to java.util.GregorianCalendar
java.util.GregorianCalendar field javax.xml.datatype.XMLGregorianCalendar field
ERA {@link #getEonAndYear()}.signum() < 0 ? GregorianCalendar.BC : GregorianCalendar.AD
YEAR {@link #getEonAndYear()}.abs().intValue()*
MONTH {@link #getMonth()} - 1
DAY_OF_MONTH {@link #getDay()}
AM_PM {@link #getHour()} < 12 : Calendar.AM : Calendar.PM
HOUR_OF_DAY {@link #getHour()}
MINUTE {@link #getMinute()}
SECOND {@link #getSecond()}
MILLISECOND get millisecond order from {@link #getFractionalSecond()}*
GregorianCalendar.setTimeZone(TimeZone) {@link #getTimezone()} formatted into Custom timezone id
* designates possible loss of precision during the conversion due to source datatype having higer precison than target datatype.

To ensure consistency in conversion implementations, the new GregorianCalendar should be instantiated in following manner.

  • Using timeZone value as defined above, create a new java.util.GregorianCalendar(timeZone,Locale.getDefault()).
  • Initialize all GregorianCalendar fields by calling {(@link GegorianCalendar#clear()}.
  • Obtain a pure Gregorian Calendar by invoking GregorianCalendar.setGregorianChange( new Date(Long.MIN_VALUE)).
  • Its fields ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY, MINUTE, SECOND and MILLISECOND are set using the method Calendar.set(int,int)

see
#toGregorianCalendar(java.util.TimeZone, java.util.Locale, XMLGregorianCalendar)


        GregorianCalendar result = null;
        final int DEFAULT_TIMEZONE_OFFSET = DatatypeConstants.FIELD_UNDEFINED;
        TimeZone tz = getTimeZone(DEFAULT_TIMEZONE_OFFSET);
        Locale locale = java.util.Locale.getDefault();

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

        // if year( and eon) are undefined, leave default Calendar values
        if (year != DatatypeConstants.FIELD_UNDEFINED) {
            if (eon == null) {
                result.set(Calendar.ERA, year < 0 ? GregorianCalendar.BC : GregorianCalendar.AD);
                result.set(Calendar.YEAR, Math.abs(year));
            }
            else {
                BigInteger eonAndYear = getEonAndYear();
                result.set(Calendar.ERA, eonAndYear.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD);
                result.set(Calendar.YEAR, eonAndYear.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;
    
public java.util.GregorianCalendartoGregorianCalendar(java.util.TimeZone timezone, java.util.Locale aLocale, javax.xml.datatype.XMLGregorianCalendar defaults)

Convert this along with provided parameters to java.util.GregorianCalendar instance.

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 timezone parameter.

To compute the return value's TimeZone field,

  • when parameter timeZone is non-null, it is the timezone field.
  • else when this.getTimezone() != DatatypeConstants.FIELD_UNDEFINED, create a java.util.TimeZone with a custom timezone id using the this.getTimezone().
  • else when defaults.getTimezone() != DatatypeConstants.FIELD_UNDEFINED, create a java.util.TimeZone with a custom timezone id using defaults.getTimezone().
  • else use the GregorianCalendar default timezone value for the host is definedas specified by java.util.TimeZone.getDefault().
  • To ensure consistency in conversion implementations, the new GregorianCalendar should be instantiated in following manner.

    • Create a new java.util.GregorianCalendar(TimeZone, Locale) with TimeZone set as specified above and the Locale parameter.
    • Initialize all GregorianCalendar fields by calling {(@link GegorianCalendar#clear()}.
    • Obtain a pure Gregorian Calendar by invoking GregorianCalendar.setGregorianChange( new Date(Long.MIN_VALUE)).
    • Its fields ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY, MINUTE, SECOND and MILLISECOND are set using the method Calendar.set(int,int)

    param
    timezone provide Timezone. null is a legal value.
    param
    aLocale provide explicit Locale. Use default GregorianCalendar locale if value is null.
    param
    defaults provide default field values to use when corresponding field for this instance is DatatypeConstants.FIELD_UNDEFINED or null. If defaultsis null or a field within the specified defaults is undefined, just use java.util.GregorianCalendar defaults.
    return
    a java.util.GregorianCalendar conversion of this instance.
    see
    #LEAP_YEAR_DEFAULT

            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 = java.util.Locale.getDefault();
            }
            result = new GregorianCalendar(tz, aLocale);
            result.clear();
            result.setGregorianChange(PURE_GREGORIAN_CHANGE);
    
            // if year( and eon) are undefined, leave default Calendar values
            if (year != DatatypeConstants.FIELD_UNDEFINED) {
                if (eon == null) {
                    result.set(Calendar.ERA, year < 0 ? GregorianCalendar.BC : GregorianCalendar.AD);
                    result.set(Calendar.YEAR, Math.abs(year));
                }
                else {
                    final BigInteger eonAndYear = getEonAndYear();
                    result.set(Calendar.ERA, eonAndYear.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD);
                    result.set(Calendar.YEAR, eonAndYear.abs().intValue());
                }
            }
            else {
                // use default if set
                if (defaults != null) {
                    final int defaultYear = defaults.getYear();
                    if (defaultYear != DatatypeConstants.FIELD_UNDEFINED) {
                        if (defaults.getEon() == null) {
                            result.set(Calendar.ERA, defaultYear < 0 ? GregorianCalendar.BC : GregorianCalendar.AD);
                            result.set(Calendar.YEAR, Math.abs(defaultYear));
                        }
                        else {
                            final BigInteger defaultEonAndYear = defaults.getEonAndYear();
                            result.set(Calendar.ERA, defaultEonAndYear.signum() == -1 ? GregorianCalendar.BC : GregorianCalendar.AD);
                            result.set(Calendar.YEAR, defaultEonAndYear.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
                final 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
                final 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
                final 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
                final 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
                final BigDecimal defaultFractionalSecond = (defaults != null) ? defaults.getFractionalSecond() : null;
                if (defaultFractionalSecond != null) { 
                    result.set(Calendar.MILLISECOND, defaults.getMillisecond());
                }
            }
    
            return result;
        
private java.lang.StringtoString(java.math.BigDecimal bd)

Turns {@link BigDecimal} to a string representation.

Due to a behavior change in the {@link BigDecimal#toString()} method in JDK1.5, this had to be implemented here.

param
bd BigDecimal to format as a String
return
String representation of BigDecimal

        String intString = bd.unscaledValue().toString();
        int scale = bd.scale();

        if (scale == 0) {
            return intString;
        }

        /* Insert decimal point */
        StringBuffer buf;
        int insertionPoint = intString.length() - scale;
        if (insertionPoint == 0) { /* Point goes right before intVal */
            return "0." + intString;
        } 
        else if (insertionPoint > 0) { /* Point goes inside intVal */
            buf = new StringBuffer(intString);
            buf.insert(insertionPoint, '.");
        } 
        else { /* We must insert zeros between point and intVal */
            buf = new StringBuffer(3 - insertionPoint + intString.length());
            buf.append("0.");
            for (int i = 0; i < -insertionPoint; i++) {
                buf.append('0");
            }
            buf.append(intString);
        }
        return buf.toString();
    
public java.lang.StringtoXMLFormat()

Return the lexical representation of this instance. The format is specified in XML Schema 1.0 Part 2, Section 3.2.[7-14].1, Lexical Representation".

Specific target lexical representation format is determined by {@link #getXMLSchemaType()}.

return
XML, as String, representation of this XMLGregorianCalendar
throws
java.lang.IllegalStateException if the combination of set fields does not match one of the eight defined XML Schema builtin date/time datatypes.


        QName typekind = getXMLSchemaType();

        String formatString = null;
        if (typekind == DatatypeConstants.DATETIME) {
            formatString = "%Y-%M-%DT%h:%m:%s"+ "%z";
        } 
        else if (typekind == DatatypeConstants.DATE) {
            // Fix 4971612: invalid SCCS macro substitution in data string
            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) {
            // Fix 4971612: invalid SCCS macro substitution in data string
            formatString = "---%D" + "%z";
        } 
        else if (typekind == DatatypeConstants.GYEAR) {
            formatString = "%Y" + "%z";
        } 
        else if (typekind == DatatypeConstants.GYEARMONTH) {
            // Fix 4971612: invalid SCCS macro substitution in data string
            formatString = "%Y-%M" + "%z";
        } 
        else if (typekind == DatatypeConstants.GMONTHDAY) {
            // Fix 4971612: invalid SCCS macro substitution in data string
            formatString = "--%M-%D" +"%z";
        }
        return format(formatString);