1/*
2 * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package javax.xml.datatype;
27
28import javax.xml.namespace.QName;
29import java.math.BigDecimal;
30import java.math.BigInteger;
31import java.util.TimeZone;
32import java.util.GregorianCalendar;
33
34/**
35 * <p>Representation for W3C XML Schema 1.0 date/time datatypes.
36 * Specifically, these date/time datatypes are
37 * {@link DatatypeConstants#DATETIME},
38 * {@link DatatypeConstants#TIME},
39 * {@link DatatypeConstants#DATE},
40 * {@link DatatypeConstants#GYEARMONTH},
41 * {@link DatatypeConstants#GMONTHDAY},
42 * {@link DatatypeConstants#GYEAR},
43 * {@link DatatypeConstants#GMONTH}, and
44 * {@link DatatypeConstants#GDAY}
45 * defined in the XML Namespace
46 * {@code "http://www.w3.org/2001/XMLSchema"}.
47 * These datatypes are normatively defined in
48 * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">W3C XML Schema 1.0 Part 2, Section 3.2.7-14</a>.
49 *
50 * <p>The table below defines the mapping between XML Schema 1.0
51 * date/time datatype fields and this class' fields. It also summarizes
52 * the value constraints for the date and time fields defined in
53 * <a href="http://www.w3.org/TR/xmlschema-2/#isoformats">W3C XML Schema 1.0 Part 2, Appendix D,
54 * <i>ISO 8601 Date and Time Formats</i></a>.
55 *
56 * <a id="datetimefieldmapping"></a>
57 * <table class="striped">
58 *   <caption>Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</caption>
59 *   <thead>
60 *     <tr>
61 *       <th scope="col">XML Schema 1.0<br>
62 *           datatype<br>
63 *            field</th>
64 *       <th scope="col">Related<br>XMLGregorianCalendar<br>Accessor(s)</th>
65 *       <th scope="col">Value Range</th>
66 *     </tr>
67 *   </thead>
68 *   <tbody>
69 *     <tr>
70 *       <th scope="row"><a id="datetimefield-year">year</a></th>
71 *       <td> {@link #getYear()} + {@link #getEon()} or<br>
72 *            {@link #getEonAndYear}
73 *       </td>
74 *       <td> {@code getYear()} is a value between -(10^9-1) to (10^9)-1
75 *            or {@link DatatypeConstants#FIELD_UNDEFINED}.<br>
76 *            {@link #getEon()} is high order year value in billion of years.<br>
77 *            {@code getEon()} has values greater than or equal to (10^9) or less than or equal to -(10^9).
78 *            A value of null indicates field is undefined.<br>
79 *            Given that <a href="http://www.w3.org/2001/05/xmlschema-errata#e2-63">XML Schema 1.0 errata</a> states that the year zero
80 *            will be a valid lexical value in a future version of XML Schema,
81 *            this class allows the year field to be set to zero. Otherwise,
82 *            the year field value is handled exactly as described
83 *            in the errata and [ISO-8601-1988]. Note that W3C XML Schema 1.0
84 *            validation does not allow for the year field to have a value of zero.
85 *            </td>
86 *     </tr>
87 *     <tr>
88 *       <th scope="row"><a id="datetimefield-month">month</a></th>
89 *       <td> {@link #getMonth()} </td>
90 *       <td> 1 to 12 or {@link DatatypeConstants#FIELD_UNDEFINED} </td>
91 *     </tr>
92 *     <tr>
93 *       <th scope="row"><a id="datetimefield-day">day</a></th>
94 *       <td> {@link #getDay()} </td>
95 *       <td> Independent of month, max range is 1 to 31 or {@link DatatypeConstants#FIELD_UNDEFINED}.<br>
96 *            The normative value constraint stated relative to month
97 *            field's value is in <a href="http://www.w3.org/TR/xmlschema-2/#isoformats">W3C XML Schema 1.0 Part 2, Appendix D</a>.
98 *       </td>
99 *     </tr>
100 *     <tr>
101 *       <th scope="row"><a id="datetimefield-hour">hour</a></th>
102 *       <td>{@link #getHour()}</td>
103 *       <td>
104 *         0 to 23 or {@link DatatypeConstants#FIELD_UNDEFINED}.
105 *         An hour value of 24 is allowed to be set in the lexical space provided the minute and second
106 *         field values are zero. However, an hour value of 24 is not allowed in value space and will be
107 *         transformed to represent the value of the first instance of the following day as per
108 *         <a href="http://www.w3.org/TR/xmlschema-2/#built-in-primitive-datatypes">
109 *         XML Schema Part 2: Datatypes Second Edition, 3.2 Primitive datatypes</a>.
110 *       </td>
111 *     </tr>
112 *     <tr>
113 *       <th scope="row"><a id="datetimefield-minute">minute</a></th>
114 *       <td> {@link #getMinute()} </td>
115 *       <td> 0 to 59 or {@link DatatypeConstants#FIELD_UNDEFINED} </td>
116 *     </tr>
117 *     <tr>
118 *       <th scope="row"><a id="datetimefield-second">second</a></th>
119 *       <td>
120 *         {@link #getSecond()} + {@link #getMillisecond()}/1000 or<br>
121 *         {@link #getSecond()} + {@link #getFractionalSecond()}
122 *       </td>
123 *       <td>
124 *         {@link #getSecond()} from 0 to 60 or {@link DatatypeConstants#FIELD_UNDEFINED}.<br>
125 *         <i>(Note: 60 only allowable for leap second.)</i><br>
126 *         {@link #getFractionalSecond()} allows for infinite precision over the range from 0.0 to 1.0 when
127 *         the {@link #getSecond()} is defined.<br>
128 *         {@code FractionalSecond} is optional and has a value of {@code null} when it is undefined.<br>
129 *            {@link #getMillisecond()} is the convenience
130 *            millisecond precision of value of {@link #getFractionalSecond()}.
131 *       </td>
132 *     </tr>
133 *     <tr>
134 *       <th scope="row"><a id="datetimefield-timezone">timezone</a></th>
135 *       <td> {@link #getTimezone()} </td>
136 *       <td> Number of minutes or {@link DatatypeConstants#FIELD_UNDEFINED}.
137 *         Value range from -14 hours (-14 * 60 minutes) to 14 hours (14 * 60 minutes).
138 *       </td>
139 *     </tr>
140 *   </tbody>
141 *  </table>
142 *
143 * <p>All maximum value space constraints listed for the fields in the table
144 * above are checked by factory methods, {@link DatatypeFactory},
145 * setter methods and parse methods of
146 * this class. {@code IllegalArgumentException} is thrown when a
147 * parameter's value is outside the value constraint for the field or
148 * if the composite
149 * values constitute an invalid XMLGregorianCalendar instance (for example, if
150 * the 31st of June is specified).
151 *
152 * <p>The following operations are defined for this class:
153 * <ul>
154 *   <li>accessors/mutators for independent date/time fields</li>
155 *   <li>conversion between this class and W3C XML Schema 1.0 lexical representation,
156 *     {@link #toString()}, {@link DatatypeFactory#newXMLGregorianCalendar(String lexicalRepresentation)}</li>
157 *   <li>conversion between this class and {@link GregorianCalendar},
158 *     {@link #toGregorianCalendar(java.util.TimeZone timezone, java.util.Locale aLocale, XMLGregorianCalendar defaults)},
159 *     {@link DatatypeFactory}</li>
160 *   <li>partial order relation comparator method, {@link #compare(XMLGregorianCalendar xmlGregorianCalendar)}</li>
161 *   <li>{@link #equals(Object)} defined relative to {@link #compare(XMLGregorianCalendar xmlGregorianCalendar)}.</li>
162 *   <li>addition operation with {@link Duration}
163 *      instance as defined in <a href="http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes">
164 *      W3C XML Schema 1.0 Part 2, Appendix E, <i>Adding durations to dateTimes</i></a>.
165 *   </li>
166 * </ul>
167 *
168 * @author <a href="mailto:Joseph.Fialli@Sun.com">Joseph Fialli</a>
169 * @author <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a>
170 * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
171 * @author <a href="mailto:Sunitha.Reddy@Sun.com">Sunitha Reddy</a>
172 * @see Duration
173 * @see DatatypeFactory
174 * @since 1.5
175 */
176
177public abstract class XMLGregorianCalendar
178        implements Cloneable {
179
180    /**
181     * Default no-arg constructor.
182     *
183     * <p>Note: Always use the {@link DatatypeFactory} to
184     * construct an instance of {@code XMLGregorianCalendar}.
185     * The constructor on this class cannot be guaranteed to
186     * produce an object with a consistent state and may be
187     * removed in the future.
188     */
189    public XMLGregorianCalendar() {
190    }
191
192    /**
193     * Unset all fields to undefined.
194     *
195     * <p>Set all int fields to {@link DatatypeConstants#FIELD_UNDEFINED} and reference fields
196     * to null.
197     */
198    public abstract void clear();
199
200    /**
201     * Reset this {@code XMLGregorianCalendar} to its original values.
202     *
203     * <p>{@code XMLGregorianCalendar} is reset to the same values as when it was created with
204     * {@link DatatypeFactory#newXMLGregorianCalendar()},
205     * {@link DatatypeFactory#newXMLGregorianCalendar(String lexicalRepresentation)},
206     * {@link DatatypeFactory#newXMLGregorianCalendar(
207     *   BigInteger year,
208     *   int month,
209     *   int day,
210     *   int hour,
211     *   int minute,
212     *   int second,
213     *   BigDecimal fractionalSecond,
214     *   int timezone)},
215     * {@link DatatypeFactory#newXMLGregorianCalendar(
216     *   int year,
217     *   int month,
218     *   int day,
219     *   int hour,
220     *   int minute,
221     *   int second,
222     *   int millisecond,
223     *   int timezone)},
224     * {@link DatatypeFactory#newXMLGregorianCalendar(GregorianCalendar cal)},
225     * {@link DatatypeFactory#newXMLGregorianCalendarDate(
226     *   int year,
227     *   int month,
228     *   int day,
229     *   int timezone)},
230     * {@link DatatypeFactory#newXMLGregorianCalendarTime(
231     *   int hours,
232     *   int minutes,
233     *   int seconds,
234     *   int timezone)},
235     * {@link DatatypeFactory#newXMLGregorianCalendarTime(
236     *   int hours,
237     *   int minutes,
238     *   int seconds,
239     *   BigDecimal fractionalSecond,
240     *   int timezone)} or
241     * {@link DatatypeFactory#newXMLGregorianCalendarTime(
242     *   int hours,
243     *   int minutes,
244     *   int seconds,
245     *   int milliseconds,
246     *   int timezone)}.
247     *
248     * <p>{@code reset()} is designed to allow the reuse of existing {@code XMLGregorianCalendar}s
249     * thus saving resources associated with the creation of new {@code XMLGregorianCalendar}s.
250     */
251    public abstract void reset();
252
253    /**
254     * Set low and high order component of XSD {@code dateTime} year field.
255     *
256     * <p>Unset this field by invoking the setter with a parameter value of {@code null}.
257     *
258     * @param year value constraints summarized in <a href="#datetimefield-year">year field of date/time field mapping table</a>.
259     *
260     * @throws IllegalArgumentException if {@code year} parameter is
261     * outside value constraints for the field as specified in
262     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
263     */
264    public abstract void setYear(BigInteger year);
265
266    /**
267     * Set year of XSD {@code dateTime} year field.
268     *
269     * <p>Unset this field by invoking the setter with a parameter value of
270     * {@link DatatypeConstants#FIELD_UNDEFINED}.
271     *
272     * <p>Note: if the absolute value of the {@code year} parameter
273     * is less than 10^9, the eon component of the XSD year field is set to
274     * {@code null} by this method.
275     *
276     * @param year value constraints are summarized in <a href="#datetimefield-year">year field of date/time field mapping table</a>.
277     *   If year is {@link DatatypeConstants#FIELD_UNDEFINED}, then eon is set to {@code null}.
278     */
279    public abstract void setYear(int year);
280
281    /**
282     * Set month.
283     *
284     * <p>Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.
285     *
286     * @param month value constraints summarized in <a href="#datetimefield-month">month field of date/time field mapping table</a>.
287     *
288     * @throws IllegalArgumentException if {@code month} parameter is
289     * outside value constraints for the field as specified in
290     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
291     */
292    public abstract void setMonth(int month);
293
294    /**
295     * Set days in month.
296     *
297     * <p>Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.
298     *
299     * @param day value constraints summarized in <a href="#datetimefield-day">day field of date/time field mapping table</a>.
300     *
301     * @throws IllegalArgumentException if {@code day} parameter is
302     * outside value constraints for the field as specified in
303     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
304     */
305    public abstract void setDay(int day);
306
307    /**
308     * Set the number of minutes in the timezone offset.
309     *
310     * <p>Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.
311     *
312     * @param offset value constraints summarized in <a href="#datetimefield-timezone">
313     *   timezone field of date/time field mapping table</a>.
314     *
315     * @throws IllegalArgumentException if {@code offset} parameter is
316     * outside value constraints for the field as specified in
317     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
318     */
319    public abstract void setTimezone(int offset);
320
321    /**
322     * Set time as one unit.
323     *
324     * @param hour value constraints are summarized in
325     * <a href="#datetimefield-hour">hour field of date/time field mapping table</a>.
326     * @param minute value constraints are summarized in
327     * <a href="#datetimefield-minute">minute field of date/time field mapping table</a>.
328     * @param second value constraints are summarized in
329     * <a href="#datetimefield-second">second field of date/time field mapping table</a>.
330     *
331     * @see #setTime(int, int, int, BigDecimal)
332     *
333     * @throws IllegalArgumentException if any parameter is
334     * outside value constraints for the field as specified in
335     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
336     */
337    public void setTime(int hour, int minute, int second) {
338
339        setTime(
340                hour,
341                minute,
342                second,
343                null // fractional
344        );
345    }
346
347    /**
348     * Set hours.
349     *
350     * <p>Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.
351     *
352     * @param hour value constraints summarized in <a href="#datetimefield-hour">hour field of date/time field mapping table</a>.
353     *
354     * @throws IllegalArgumentException if {@code hour} parameter is outside value constraints for the field as specified in
355     *   <a href="#datetimefieldmapping">date/time field mapping table</a>.
356     */
357    public abstract void setHour(int hour);
358
359    /**
360     * Set minutes.
361     *
362     * <p>Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.
363     *
364     * @param minute value constraints summarized in <a href="#datetimefield-minute">minute field of date/time field mapping table</a>.
365     *
366     * @throws IllegalArgumentException if {@code minute} parameter is outside value constraints for the field as specified in
367     *   <a href="#datetimefieldmapping">date/time field mapping table</a>.
368     */
369    public abstract void setMinute(int minute);
370
371    /**
372     * Set seconds.
373     *
374     * <p>Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.
375     *
376     * @param second value constraints summarized in <a href="#datetimefield-second">second field of date/time field mapping table</a>.
377     *
378     * @throws IllegalArgumentException if {@code second} parameter is outside value constraints for the field as specified in
379     *   <a href="#datetimefieldmapping">date/time field mapping table</a>.
380     */
381    public abstract void setSecond(int second);
382
383    /**
384     * Set milliseconds.
385     *
386     * <p>Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.
387     *
388     * @param millisecond value constraints summarized in
389     *   <a href="#datetimefield-second">second field of date/time field mapping table</a>.
390     *
391     * @throws IllegalArgumentException if {@code millisecond} parameter is outside value constraints for the field as specified
392     *   in <a href="#datetimefieldmapping">date/time field mapping table</a>.
393     */
394    public abstract void setMillisecond(int millisecond);
395
396    /**
397     * Set fractional seconds.
398     *
399     * <p>Unset this field by invoking the setter with a parameter value of {@code null}.
400     *
401     * @param fractional value constraints summarized in
402     *   <a href="#datetimefield-second">second field of date/time field mapping table</a>.
403     *
404     * @throws IllegalArgumentException if {@code fractional} parameter is outside value constraints for the field as specified
405     *   in <a href="#datetimefieldmapping">date/time field mapping table</a>.
406     */
407    public abstract void setFractionalSecond(BigDecimal fractional);
408
409
410    /**
411     * Set time as one unit, including the optional infinite precision
412     * fractional seconds.
413     *
414     * @param hour value constraints are summarized in
415     * <a href="#datetimefield-hour">hour field of date/time field mapping table</a>.
416     * @param minute value constraints are summarized in
417     * <a href="#datetimefield-minute">minute field of date/time field mapping table</a>.
418     * @param second value constraints are summarized in
419     * <a href="#datetimefield-second">second field of date/time field mapping table</a>.
420     * @param fractional value of {@code null} indicates this optional
421     *   field is not set.
422     *
423     * @throws IllegalArgumentException if any parameter is
424     * outside value constraints for the field as specified in
425     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
426     */
427    public void setTime(
428            int hour,
429            int minute,
430            int second,
431            BigDecimal fractional) {
432
433        setHour(hour);
434        setMinute(minute);
435        setSecond(second);
436        setFractionalSecond(fractional);
437    }
438
439
440    /**
441     * Set time as one unit, including optional milliseconds.
442     *
443     * @param hour value constraints are summarized in
444     * <a href="#datetimefield-hour">hour field of date/time field mapping table</a>.
445     * @param minute value constraints are summarized in
446     * <a href="#datetimefield-minute">minute field of date/time field mapping table</a>.
447     * @param second value constraints are summarized in
448     * <a href="#datetimefield-second">second field of date/time field mapping table</a>.
449     * @param millisecond value of {@link DatatypeConstants#FIELD_UNDEFINED} indicates this
450     *                    optional field is not set.
451     *
452     * @throws IllegalArgumentException if any parameter is
453     * outside value constraints for the field as specified in
454     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
455     */
456    public void setTime(int hour, int minute, int second, int millisecond) {
457
458        setHour(hour);
459        setMinute(minute);
460        setSecond(second);
461        setMillisecond(millisecond);
462    }
463
464    /**
465     * Returns the high order component for XML Schema 1.0 dateTime datatype field for
466     * {@code year}.
467     * {@code null} if this optional part of the year field is not defined.
468     *
469     * <p>Value constraints for this value are summarized in
470     * <a href="#datetimefield-year">year field of date/time field mapping table</a>.
471     * @return The eon of this {@code XMLGregorianCalendar}. The value
472     * returned is an integer multiple of 10^9.
473     *
474     * @see #getYear()
475     * @see #getEonAndYear()
476     */
477    public abstract BigInteger getEon();
478
479    /**
480     * Returns the low order component for XML Schema 1.0 dateTime datatype field for
481     * {@code year} or {@link DatatypeConstants#FIELD_UNDEFINED}.
482     *
483     * <p>Value constraints for this value are summarized in
484     * <a href="#datetimefield-year">year field of date/time field mapping table</a>.
485     *
486     * @return The year of this {@code XMLGregorianCalendar}.
487     *
488     * @see #getEon()
489     * @see #getEonAndYear()
490     */
491    public abstract int getYear();
492
493    /**
494     * Returns the XML Schema 1.0 dateTime datatype field for
495     * {@code year}.
496     *
497     * <p>Value constraints for this value are summarized in
498     * <a href="#datetimefield-year">year field of date/time field mapping table</a>.
499     *
500     * @return sum of {@code eon} and {@code BigInteger.valueOf(year)}
501     * when both fields are defined. When only {@code year} is defined,
502     * return it. When both {@code eon} and {@code year} are not
503     * defined, return {@code null}.
504     *
505     * @see #getEon()
506     * @see #getYear()
507     */
508    public abstract BigInteger getEonAndYear();
509
510    /**
511     * Returns the month of this calendar or {@link DatatypeConstants#FIELD_UNDEFINED}.
512     *
513     * <p>Value constraints for this value are summarized in
514     * <a href="#datetimefield-month">month field of date/time field mapping table</a>.
515     *
516     * @return The month of this {@code XMLGregorianCalendar}, from 1 to 12.
517     *
518     */
519    public abstract int getMonth();
520
521    /**
522     * Returns the day of month or {@link DatatypeConstants#FIELD_UNDEFINED}.
523     *
524     * <p>Value constraints for this value are summarized in
525     * <a href="#datetimefield-day">day field of date/time field mapping table</a>.
526     *
527     * @return The day of month of this {@code XMLGregorianCalendar}, from 1 to 31.
528     *
529     * @see #setDay(int)
530     */
531    public abstract int getDay();
532
533    /**
534     * Returns the Timezone offset in minutes or
535     * {@link DatatypeConstants#FIELD_UNDEFINED} if this optional field is not defined.
536     *
537     * <p>Value constraints for this value are summarized in
538     * <a href="#datetimefield-timezone">timezone field of date/time field mapping table</a>.
539     *
540     * @return The Timezone offset in minutes of this {@code XMLGregorianCalendar}.
541     *
542     * @see #setTimezone(int)
543     */
544    public abstract int getTimezone();
545
546    /**
547     * Returns the hour of day or
548     * {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined.
549     *
550     * <p>Value constraints for this value are summarized in
551     * <a href="#datetimefield-hour">hour field of date/time field mapping table</a>.
552     *
553     * @return The hour of day of this {@code XMLGregorianCalendar}, from 0 to 23.
554     *
555     * @see #setTime(int, int, int)
556     */
557    public abstract int getHour();
558
559    /**
560     * Returns the minute of hour or
561     * {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined.
562     *
563     * <p>Value constraints for this value are summarized in
564     * <a href="#datetimefield-minute">minute field of date/time field mapping table</a>.
565     *
566     * @return The minute of hour of this {@code XMLGregorianCalendar}, from 0 to 59.
567     *
568     * @see #setTime(int, int, int)
569     */
570    public abstract int getMinute();
571
572    /**
573     * Returns the second of minute or
574     * {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined.
575     * When this field is not defined, the optional xs:dateTime
576     * fractional seconds field, represented by
577     * {@link #getFractionalSecond()} and {@link #getMillisecond()},
578     * must not be defined.
579     *
580     * <p>Value constraints for this value are summarized in
581     * <a href="#datetimefield-second">second field of date/time field mapping table</a>.
582     *
583     * @return The second of minute of this {@code XMLGregorianCalendar},  from 0 to 59.
584     *
585     * @see #getFractionalSecond()
586     * @see #getMillisecond()
587     * @see #setTime(int, int, int)
588     */
589    public abstract int getSecond();
590
591    /**
592     * Returns the millisecond precision of {@link #getFractionalSecond()}.
593     *
594     * <p>This method represents a convenience accessor to infinite
595     * precision fractional second value returned by
596     * {@link #getFractionalSecond()}. The returned value is the rounded
597     * down to milliseconds value of
598     * {@link #getFractionalSecond()}. When {@link #getFractionalSecond()}
599     * returns {@code null}, this method must return
600     * {@link DatatypeConstants#FIELD_UNDEFINED}.
601     *
602     * <p>Value constraints for this value are summarized in
603     * <a href="#datetimefield-second">second field of date/time field mapping table</a>.
604     *
605     * @return The millisecond precision of this {@code XMLGregorianCalendar}.
606     *
607     * @see #getFractionalSecond()
608     * @see #setTime(int, int, int)
609     */
610    public int getMillisecond() {
611
612        BigDecimal fractionalSeconds = getFractionalSecond();
613
614        // is field undefined?
615        if (fractionalSeconds == null) {
616            return DatatypeConstants.FIELD_UNDEFINED;
617        }
618
619        return getFractionalSecond().movePointRight(3).intValue();
620    }
621
622    /**
623     * Returns fractional seconds.
624     *
625     * <p>{@code null} is returned when this optional field is not defined.
626     *
627     * <p>Value constraints are detailed in
628     * <a href="#datetimefield-second">second field of date/time field mapping table</a>.
629     *
630     * <p>This optional field can only have a defined value when the
631     * xs:dateTime second field, represented by {@link #getSecond()},
632     * does not return {@link DatatypeConstants#FIELD_UNDEFINED}.
633     *
634     * @return Fractional seconds of this {@code XMLGregorianCalendar}.
635     *
636     * @see #getSecond()
637     * @see #setTime(int, int, int, BigDecimal)
638     */
639    public abstract BigDecimal getFractionalSecond();
640
641    // comparisons
642    /**
643     * Compare two instances of W3C XML Schema 1.0 date/time datatypes
644     * according to partial order relation defined in
645     * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime-order">W3C XML Schema 1.0 Part 2, Section 3.2.7.3,
646     * <i>Order relation on dateTime</i></a>.
647     *
648     * <p>{@code xsd:dateTime} datatype field mapping to accessors of
649     * this class are defined in
650     * <a href="#datetimefieldmapping">date/time field mapping table</a>.
651     *
652     * @param xmlGregorianCalendar Instance of {@code XMLGregorianCalendar} to compare
653     *
654     * @return The relationship between {@code this} {@code XMLGregorianCalendar} and
655     *   the specified {@code xmlGregorianCalendar} as
656     *   {@link DatatypeConstants#LESSER},
657     *   {@link DatatypeConstants#EQUAL},
658     *   {@link DatatypeConstants#GREATER} or
659     *   {@link DatatypeConstants#INDETERMINATE}.
660     *
661     * @throws NullPointerException if {@code xmlGregorianCalendar} is null.
662     */
663    public abstract int compare(XMLGregorianCalendar xmlGregorianCalendar);
664
665    /**
666     * Normalize this instance to UTC.
667     *
668     * <p>2000-03-04T23:00:00+03:00 normalizes to 2000-03-04T20:00:00Z
669     * <p>Implements W3C XML Schema Part 2, Section 3.2.7.3 (A).
670     *
671     * @return {@code this} {@code XMLGregorianCalendar} normalized to UTC.
672     */
673    public abstract XMLGregorianCalendar normalize();
674
675    /**
676     * Compares this calendar to the specified object. The result is
677     * {@code true} if and only if the argument is not null and is an
678     * {@code XMLGregorianCalendar} object that represents the same
679     * instant in time as this object.
680     *
681     * @param obj to compare.
682     *
683     * @return {@code true} when {@code obj} is an instance of
684     * {@code XMLGregorianCalendar} and
685     * {@link #compare(XMLGregorianCalendar obj)}
686     * returns {@link DatatypeConstants#EQUAL},
687     * otherwise {@code false}.
688     */
689    @Override
690    public boolean equals(Object obj) {
691
692        if (obj == null || !(obj instanceof XMLGregorianCalendar)) {
693            return false;
694        }
695        return compare((XMLGregorianCalendar) obj) == DatatypeConstants.EQUAL;
696    }
697
698    /**
699     * Returns a hash code consistent with the definition of the equals method.
700     *
701     * @return hash code of this object.
702     */
703    @Override
704    public int hashCode() {
705
706        // Following two dates compare to EQUALS since in different timezones.
707        // 2000-01-15T12:00:00-05:00 == 2000-01-15T13:00:00-04:00
708        //
709        // Must ensure both instances generate same hashcode by normalizing
710        // this to UTC timezone.
711        int timezone = getTimezone();
712        if (timezone == DatatypeConstants.FIELD_UNDEFINED) {
713            timezone = 0;
714        }
715        XMLGregorianCalendar gc = this;
716        if (timezone != 0) {
717            gc = this.normalize();
718        }
719        return gc.getYear()
720                + gc.getMonth()
721                + gc.getDay()
722                + gc.getHour()
723                + gc.getMinute()
724                + gc.getSecond();
725    }
726
727    /**
728     * Return the lexical representation of {@code this} instance.
729     * The format is specified in
730     * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime-order">XML Schema 1.0 Part 2, Section 3.2.[7-14].1,
731     * <i>Lexical Representation</i>".</a>
732     *
733     * <p>Specific target lexical representation format is determined by
734     * {@link #getXMLSchemaType()}.
735     *
736     * @return XML, as {@code String}, representation of this {@code XMLGregorianCalendar}
737     *
738     * @throws IllegalStateException if the combination of set fields
739     *    does not match one of the eight defined XML Schema builtin date/time datatypes.
740     */
741    public abstract String toXMLFormat();
742
743    /**
744     * Return the name of the XML Schema date/time type that this instance
745     * maps to. Type is computed based on fields that are set.
746     *
747     * <table class="striped">
748     *   <caption>Required fields for XML Schema 1.0 Date/Time Datatypes.<br>
749     *         <i>(timezone is optional for all date/time datatypes)</i></caption>
750     *   <thead>
751     *     <tr>
752     *       <th scope="col">Datatype</th>
753     *       <th scope="col">year</th>
754     *       <th scope="col">month</th>
755     *       <th scope="col">day</th>
756     *       <th scope="col">hour</th>
757     *       <th scope="col">minute</th>
758     *       <th scope="col">second</th>
759     *     </tr>
760     *   </thead>
761     *   <tbody>
762     *     <tr>
763     *       <th scope="row">{@link DatatypeConstants#DATETIME}</th>
764     *       <td>X</td>
765     *       <td>X</td>
766     *       <td>X</td>
767     *       <td>X</td>
768     *       <td>X</td>
769     *       <td>X</td>
770     *     </tr>
771     *     <tr>
772     *       <th scope="row">{@link DatatypeConstants#DATE}</th>
773     *       <td>X</td>
774     *       <td>X</td>
775     *       <td>X</td>
776     *       <td></td>
777     *       <td></td>
778     *       <td></td>
779     *     </tr>
780     *     <tr>
781     *       <th scope="row">{@link DatatypeConstants#TIME}</th>
782     *       <td></td>
783     *       <td></td>
784     *       <td></td>
785     *       <td>X</td>
786     *       <td>X</td>
787     *       <td>X</td>
788     *     </tr>
789     *     <tr>
790     *       <th scope="row">{@link DatatypeConstants#GYEARMONTH}</th>
791     *       <td>X</td>
792     *       <td>X</td>
793     *       <td></td>
794     *       <td></td>
795     *       <td></td>
796     *       <td></td>
797     *     </tr>
798     *     <tr>
799     *       <th scope="row">{@link DatatypeConstants#GMONTHDAY}</th>
800     *       <td></td>
801     *       <td>X</td>
802     *       <td>X</td>
803     *       <td></td>
804     *       <td></td>
805     *       <td></td>
806     *     </tr>
807     *     <tr>
808     *       <th scope="row">{@link DatatypeConstants#GYEAR}</th>
809     *       <td>X</td>
810     *       <td></td>
811     *       <td></td>
812     *       <td></td>
813     *       <td></td>
814     *       <td></td>
815     *     </tr>
816     *     <tr>
817     *       <th scope="row">{@link DatatypeConstants#GMONTH}</th>
818     *       <td></td>
819     *       <td>X</td>
820     *       <td></td>
821     *       <td></td>
822     *       <td></td>
823     *       <td></td>
824     *     </tr>
825     *     <tr>
826     *       <th scope="row">{@link DatatypeConstants#GDAY}</th>
827     *       <td></td>
828     *       <td></td>
829     *       <td>X</td>
830     *       <td></td>
831     *       <td></td>
832     *       <td></td>
833     *     </tr>
834     *   </tbody>
835     * </table>
836     *
837     * @throws java.lang.IllegalStateException if the combination of set fields
838     *    does not match one of the eight defined XML Schema builtin
839     *    date/time datatypes.
840     * @return One of the following class constants:
841     *   {@link DatatypeConstants#DATETIME},
842     *   {@link DatatypeConstants#TIME},
843     *   {@link DatatypeConstants#DATE},
844     *   {@link DatatypeConstants#GYEARMONTH},
845     *   {@link DatatypeConstants#GMONTHDAY},
846     *   {@link DatatypeConstants#GYEAR},
847     *   {@link DatatypeConstants#GMONTH} or
848     *   {@link DatatypeConstants#GDAY}.
849     */
850    public abstract QName getXMLSchemaType();
851
852    /**
853     * Returns a {@code String} representation of this {@code XMLGregorianCalendar} {@code Object}.
854     *
855     * <p>The result is a lexical representation generated by {@link #toXMLFormat()}.
856     *
857     * @return A non-{@code null} valid {@code String} representation of this {@code XMLGregorianCalendar}.
858     *
859     * @throws IllegalStateException if the combination of set fields
860     *    does not match one of the eight defined XML Schema builtin date/time datatypes.
861     *
862     * @see #toXMLFormat()
863     */
864    @Override
865    public String toString() {
866
867        return toXMLFormat();
868    }
869
870    /**
871     * Validate instance by {@code getXMLSchemaType()} constraints.
872     * @return true if data values are valid.
873     */
874    public abstract boolean isValid();
875
876    /**
877     * Add {@code duration} to this instance.
878     *
879     * <p>The computation is specified in
880     * <a href="http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes">XML Schema 1.0 Part 2, Appendix E,
881     * <i>Adding durations to dateTimes</i></a>.
882     * <a href="#datetimefieldmapping">date/time field mapping table</a>
883     * defines the mapping from XML Schema 1.0 {@code dateTime} fields
884     * to this class' representation of those fields.
885     *
886     * @param duration Duration to add to this {@code XMLGregorianCalendar}.
887     *
888     * @throws NullPointerException  when {@code duration} parameter is {@code null}.
889     */
890    public abstract void add(Duration duration);
891
892    /**
893     * Convert this {@code XMLGregorianCalendar} to a {@link GregorianCalendar}.
894     *
895     * <p>When {@code this} instance has an undefined field, this
896     * conversion relies on the {@code java.util.GregorianCalendar} default
897     * for its corresponding field. A notable difference between
898     * XML Schema 1.0 date/time datatypes and {@code java.util.GregorianCalendar}
899     * is that Timezone value is optional for date/time datatypes and it is
900     * a required field for {@code java.util.GregorianCalendar}. See javadoc
901     * for {@code java.util.TimeZone.getDefault()} on how the default
902     * is determined. To explicitly specify the {@code TimeZone}
903     * instance, see
904     * {@link #toGregorianCalendar(TimeZone, Locale, XMLGregorianCalendar)}.
905     *
906     * <table class="striped">
907     *   <caption>Field by Field Conversion from this class to
908     *          {@code java.util.GregorianCalendar}</caption>
909     *   <thead>
910     *     <tr>
911     *        <th scope="col">{@code java.util.GregorianCalendar} field</th>
912     *        <th scope="col">{@code javax.xml.datatype.XMLGregorianCalendar} field</th>
913     *     </tr>
914     *   </thead>
915     *   <tbody>
916     *     <tr>
917     *       <th scope="row">{@code ERA}</th>
918     *       <td>{@link #getEonAndYear()}{@code .signum() < 0 ? GregorianCalendar.BC : GregorianCalendar.AD}</td>
919     *     </tr>
920     *     <tr>
921     *       <th scope="row">{@code YEAR}</th>
922     *       <td>{@link #getEonAndYear()}{@code .abs().intValue()}<i>*</i></td>
923     *     </tr>
924     *     <tr>
925     *       <th scope="row">{@code MONTH}</th>
926     *       <td>{@link #getMonth()} - {@link DatatypeConstants#JANUARY} + {@link GregorianCalendar#JANUARY}</td>
927     *     </tr>
928     *     <tr>
929     *       <th scope="row">{@code DAY_OF_MONTH}</th>
930     *       <td>{@link #getDay()}</td>
931     *     </tr>
932     *     <tr>
933     *       <th scope="row">{@code HOUR_OF_DAY}</th>
934     *       <td>{@link #getHour()}</td>
935     *     </tr>
936     *     <tr>
937     *       <th scope="row">{@code MINUTE}</th>
938     *       <td>{@link #getMinute()}</td>
939     *     </tr>
940     *     <tr>
941     *       <th scope="row">{@code SECOND}</th>
942     *       <td>{@link #getSecond()}</td>
943     *     </tr>
944     *     <tr>
945     *       <th scope="row">{@code MILLISECOND}</th>
946     *       <td>get millisecond order from {@link #getFractionalSecond()}<i>*</i> </td>
947     *     </tr>
948     *     <tr>
949     *       <th scope="row">{@code GregorianCalendar.setTimeZone(TimeZone)}</th>
950     *       <td>{@link #getTimezone()} formatted into Custom timezone id</td>
951     *     </tr>
952     *   </tbody>
953     * </table>
954     * <i>*</i> designates possible loss of precision during the conversion due
955     * to source datatype having higher precision than target datatype.
956     *
957     * <p>To ensure consistency in conversion implementations, the new
958     * {@code GregorianCalendar} should be instantiated in following
959     * manner.
960     * <ul>
961     *   <li>Using {@code timeZone} value as defined above, create a new
962     * {@code java.util.GregorianCalendar(timeZone,Locale.getDefault())}.
963     *   </li>
964     *   <li>Initialize all GregorianCalendar fields by calling {@link java.util.GregorianCalendar#clear()}.</li>
965     *   <li>Obtain a pure Gregorian Calendar by invoking
966     *   {@code GregorianCalendar.setGregorianChange(
967     *   new Date(Long.MIN_VALUE))}.</li>
968     *   <li>Its fields ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY,
969     *       MINUTE, SECOND and MILLISECOND are set using the method
970     *       {@code Calendar.set(int,int)}</li>
971     * </ul>
972     *
973     * @return An instance of {@link java.util.GregorianCalendar}.
974     *
975     * @see #toGregorianCalendar(java.util.TimeZone, java.util.Locale, XMLGregorianCalendar)
976     */
977    public abstract GregorianCalendar toGregorianCalendar();
978
979    /**
980     * Convert this {@code XMLGregorianCalendar} along with provided parameters
981     * to a {@link GregorianCalendar} instance.
982     *
983     * <p> Since XML Schema 1.0 date/time datetypes has no concept of
984     * timezone ids or daylight savings timezone ids, this conversion operation
985     * allows the user to explicitly specify one with
986     * {@code timezone} parameter.
987     *
988     * <p>To compute the return value's {@code TimeZone} field,
989     * <ul>
990     * <li>when parameter {@code timeZone} is non-null,
991     * it is the timezone field.</li>
992     * <li>else when {@code this.getTimezone() != FIELD_UNDEFINED},
993     * create a {@code java.util.TimeZone} with a custom timezone id
994     * using the {@code this.getTimezone()}.</li>
995     * <li>else when {@code defaults.getTimezone() != FIELD_UNDEFINED},
996     * create a {@code java.util.TimeZone} with a custom timezone id
997     * using {@code defaults.getTimezone()}.</li>
998     * <li>else use the {@code GregorianCalendar} default timezone value
999     * for the host is defined as specified by
1000     * {@code java.util.TimeZone.getDefault()}.</li>
1001     * </ul>
1002     *
1003     * <p>To ensure consistency in conversion implementations, the new
1004     * {@code GregorianCalendar} should be instantiated in following
1005     * manner.
1006     * <ul>
1007     *   <li>Create a new {@code java.util.GregorianCalendar(TimeZone,
1008     *       Locale)} with TimeZone set as specified above and the
1009     *       {@code Locale} parameter.
1010     *   </li>
1011     *   <li>Initialize all GregorianCalendar fields by calling {@link GregorianCalendar#clear()}</li>
1012     *   <li>Obtain a pure Gregorian Calendar by invoking
1013     *   {@code GregorianCalendar.setGregorianChange(
1014     *   new Date(Long.MIN_VALUE))}.</li>
1015     *   <li>Its fields ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY,
1016     *       MINUTE, SECOND and MILLISECOND are set using the method
1017     *       {@code Calendar.set(int,int)}</li>
1018     * </ul>
1019     *
1020     * @param timezone provide Timezone. {@code null} is a legal value.
1021     * @param aLocale  provide explicit Locale. Use default GregorianCalendar locale if
1022     *                 value is {@code null}.
1023     * @param defaults provide default field values to use when corresponding
1024     *                 field for this instance is FIELD_UNDEFINED or null.
1025     *                 If {@code defaults}is {@code null} or a field
1026     *                 within the specified {@code defaults} is undefined,
1027     *                 just use {@code java.util.GregorianCalendar} defaults.
1028     * @return a java.util.GregorianCalendar conversion of this instance.
1029     */
1030    public abstract GregorianCalendar toGregorianCalendar(
1031            java.util.TimeZone timezone,
1032            java.util.Locale aLocale,
1033            XMLGregorianCalendar defaults);
1034
1035    /**
1036     * Returns a {@code java.util.TimeZone} for this class.
1037     *
1038     * <p>If timezone field is defined for this instance,
1039     * returns TimeZone initialized with custom timezone id
1040     * of zoneoffset. If timezone field is undefined,
1041     * try the defaultZoneoffset that was passed in.
1042     * If defaultZoneoffset is FIELD_UNDEFINED, return
1043     * default timezone for this host.
1044     * (Same default as java.util.GregorianCalendar).
1045     *
1046     * @param defaultZoneoffset default zoneoffset if this zoneoffset is
1047     * {@link DatatypeConstants#FIELD_UNDEFINED}.
1048     *
1049     * @return TimeZone for this.
1050     */
1051    public abstract TimeZone getTimeZone(int defaultZoneoffset);
1052
1053
1054
1055    /**
1056     * Creates and returns a copy of this object.
1057     *
1058     * @return copy of this {@code Object}
1059     */
1060    @Override
1061    public abstract Object clone();
1062}
1063