XMLGregorianCalendarImplpublic class XMLGregorianCalendarImpl extends XMLGregorianCalendar implements Serializable, CloneableRepresentation 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:
- factory methods to create instances
- accessors/mutators for independent date/time fields
- conversion between this class and W3C XML Schema 1.0 lexical representation
- conversion between this class and
java.util.GregorianCalendar
- partial order relation comparator method, {@link #compare(XMLGregorianCalendar)}
- {@link #equals(Object)} defined relative to {@link #compare(XMLGregorianCalendar)}.
- addition operation with {@link javax.xml.datatype.Duration}.
instance as defined in
W3C XML Schema 1.0 Part 2, Appendix E, Adding durations to dateTimes.
|
Fields Summary |
---|
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 Constant to represent 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 | YEARYear index for MIN_ and MAX_FIELD_VALUES. | private static final int | MONTHMonth index for MIN_ and MAX_FIELD_VALUES. | private static final int | DAYDay index for MIN_ and MAX_FIELD_VALUES. | private static final int | HOURHour index for MIN_ and MAX_FIELD_VALUES. | private static final int | MINUTEMinute index for MIN_ and MAX_FIELD_VALUES. | private static final int | SECONDSecond index for MIN_ and MAX_FIELD_VALUES. | private static final int | MILLISECONDSecond index for MIN_ and MAX_FIELD_VALUES. | private static final int | TIMEZONETimezone index for MIN_ and MAX_FIELD_VALUES | private static final String[] | FIELD_NAMEfield 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 | private static int[] | daysInMonth |
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.
// 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.
// 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."
);
}
| 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.
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."
);
*/
}
| 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
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."
);
*/
}
| 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() .
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);
|
Methods Summary |
---|
public void | add(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.
/*
* 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;
}
}
}
| public void | clear()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.Object | clone()Creates and returns a 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 int | compare(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.
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;
}
}
| private static int | compareField(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 int | compareField(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 int | compareField(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.XMLGregorianCalendar | createDate(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}.
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.XMLGregorianCalendar | createDateTime(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.
return new XMLGregorianCalendarImpl(
year,
month,
day,
hours,
minutes,
seconds,
fractionalSecond,
timezone);
| public static javax.xml.datatype.XMLGregorianCalendar | createDateTime(int year, int month, int day, int hour, int minute, int second)Create a Java instance of XML Schema builtin datatype dateTime.
return new XMLGregorianCalendarImpl(
year,
month,
day,
hour,
minute,
second,
DatatypeConstants.FIELD_UNDEFINED, //millisecond
DatatypeConstants.FIELD_UNDEFINED //timezone
);
| public static javax.xml.datatype.XMLGregorianCalendar | createDateTime(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.
return new XMLGregorianCalendarImpl(
year,
month,
day,
hours,
minutes,
seconds,
milliseconds,
timezone);
| public static javax.xml.datatype.XMLGregorianCalendar | createTime(int hours, int minutes, int seconds, int timezone)Create a Java instance of XML Schema builtin datatype time .
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.XMLGregorianCalendar | createTime(int hours, int minutes, int seconds, java.math.BigDecimal fractionalSecond, int timezone)Create a Java instance of XML Schema builtin datatype time.
return new XMLGregorianCalendarImpl(
null, // Year
DatatypeConstants.FIELD_UNDEFINED, // month
DatatypeConstants.FIELD_UNDEFINED, // day
hours,
minutes,
seconds,
fractionalSecond,
timezone);
| public static javax.xml.datatype.XMLGregorianCalendar | createTime(int hours, int minutes, int seconds, int milliseconds, int timezone)Create a Java instance of XML Schema builtin datatype time.
return new XMLGregorianCalendarImpl(
DatatypeConstants.FIELD_UNDEFINED, // year
DatatypeConstants.FIELD_UNDEFINED, // month
DatatypeConstants.FIELD_UNDEFINED, // day
hours,
minutes,
seconds,
milliseconds,
timezone);
| public boolean | equals(java.lang.Object obj)Indicates whether parameter obj is "equal to" this one.
if (obj == null || !(obj instanceof XMLGregorianCalendar)) {
return false;
}
return compare((XMLGregorianCalendar) obj) == DatatypeConstants.EQUAL;
| private java.lang.String | format(java.lang.String format)Prints this object according to the format specification.
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.
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
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) {
String frac = getFractionalSecond().toString();
// 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);
| public int | getDay()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.
return day;
| public java.math.BigInteger | getEon()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;
| public java.math.BigInteger | getEonAndYear()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.
// 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.BigDecimal | getFractionalSecond()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 fractionalSecond;
| public int | getHour()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.
return hour;
| public int | getMillisecond()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.
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 int | getMinute()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.
return minute;
| public int | getMonth()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 month;
| public int | getSecond()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;
| private java.math.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;
}
| public java.util.TimeZone | getTimeZone(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).
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;
| public int | getTimezone()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.
return timezone;
| public javax.xml.namespace.QName | getXMLSchemaType()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 |
|
|
|
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)
);
}
| public int | getYear()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;
| public int | hashCode()Returns a hash code consistent with the definition of the equals method.
// 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();
| private static int | internalCompare(javax.xml.datatype.XMLGregorianCalendar P, javax.xml.datatype.XMLGregorianCalendar Q)Implements Step B from http://www.w3.org/TR/xmlschema-2/#dateTime-order
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 void | invalidFieldValue(int field, int value)
throw new IllegalArgumentException(
DatatypeMessageFormatter.formatMessage(null, "InvalidFieldValue",
new Object[]{ new Integer(value), FIELD_NAME[field]})
);
| private static boolean | isDigit(char ch)
return '0" <= ch && ch <= '9";
| public boolean | isValid()Validate instance by getXMLSchemaType() constraints.
// 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;
| private static int | maximumDayInMonthFor(java.math.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];
}
}
| public javax.xml.datatype.XMLGregorianCalendar | normalize()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(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.XMLGregorianCalendar | normalizeToTimezone(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) 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;
| public static javax.xml.datatype.XMLGregorianCalendar | parse(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.
return new XMLGregorianCalendarImpl(lexicalRepresentation);
| private int | print2Number(char[] out, int bufptr, int number)Prints an int as two digits into the buffer.
out[bufptr++] = (char) ('0"+(number/10));
out[bufptr++] = (char) ('0"+(number%10));
return bufptr;
| private int | print4Number(char[] out, int bufptr, int number)Prints an int as four digits into the buffer.
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;
| public void | reset()reset() is designed to allow the reuse of existing
XMLGregorianCalendar s thus saving resources associated
with the creation of new XMLGregorianCalendar s.
//PENDING : Implementation of reset method
| static java.math.BigInteger | sanitize(java.lang.Number value, int signum)Compute value*signum where value==null is treated as
value==0.
if (signum == 0 || value == null) {
return BigInteger.ZERO;
}
return (signum < 0)? ((BigInteger)value).negate() : (BigInteger)value;
| public void | setDay(int day)Set days in month.
Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.
if(day<1 || 31<day)
if(day!=DatatypeConstants.FIELD_UNDEFINED)
invalidFieldValue(DAY,day);
this.day = day;
| private void | setEon(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 .
if (eon != null && eon.compareTo(BigInteger.ZERO) == 0) {
// Treat ZERO as field being undefined.
this.eon = null;
} else {
this.eon = eon;
}
| public void | setFractionalSecond(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 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 | 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 | setMinute(int minute)
if(minute<0 || 59<minute)
if(minute!=DatatypeConstants.FIELD_UNDEFINED)
invalidFieldValue(MINUTE, minute);
this.minute = minute;
| public void | setMonth(int month)Set month.
Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.
if(month<DatatypeConstants.JANUARY || DatatypeConstants.DECEMBER<month)
if(month!=DatatypeConstants.FIELD_UNDEFINED)
invalidFieldValue(MONTH, month);
this.month = month;
| 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;
| public void | setTime(int hour, int minute, int second)Set time as one unit.
setTime(hour, minute, second, null);
| public void | setTime(int hour, int minute, int second, java.math.BigDecimal fractional)Set time as one unit, including the optional infinite precison
fractional seconds.
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();
| public void | setTime(int hour, int minute, int second, int millisecond)Set time as one unit, including optional milliseconds.
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();
| public void | setTimezone(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}.
if(offset<-14*60 || 14*60<offset)
if(offset!=DatatypeConstants.FIELD_UNDEFINED)
invalidFieldValue(TIMEZONE,offset);
this.timezone = offset;
| public void | setYear(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 .
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));
}
| public void | setYear(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.
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));
}
| private void | testHour()
// http://www.w3.org/2001/05/xmlschema-errata#e2-45
if (getHour() == 24) {
if (getMinute() != 0
|| getSecond() != 0) {
invalidFieldValue(HOUR, getHour());
}
}
| public java.util.GregorianCalendar | toGregorianCalendar()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)
GregorianCalendar result = null;
final int DEFAULT_TIMEZONE_OFFSET = DatatypeConstants.FIELD_UNDEFINED;
TimeZone tz = getTimeZone(DEFAULT_TIMEZONE_OFFSET);
Locale locale = Locale.getDefault();
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;
| public java.util.GregorianCalendar | toGregorianCalendar(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)
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;
| public java.lang.String | toXMLFormat()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()}.
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);
|
|