DatatypeFactory.java revision f33eae7e84eb6d3b0f4e86b59605bb3de73009f3
1320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson/*
2320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one or more
3320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * contributor license agreements.  See the NOTICE file distributed with
4320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * this work for additional information regarding copyright ownership.
5320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * The ASF licenses this file to You under the Apache License, Version 2.0
6320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * (the "License"); you may not use this file except in compliance with
7320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * the License.  You may obtain a copy of the License at
8320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *
9320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
10320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *
11320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Unless required by applicable law or agreed to in writing, software
12320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
13320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * See the License for the specific language governing permissions and
15320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * limitations under the License.
16320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */
17320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
18320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson//$Id: DatatypeFactory.java 884950 2009-11-27 18:46:18Z mrglavas $
19320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
20320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonpackage javax.xml.datatype;
21320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
22320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport java.math.BigInteger;
23320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport java.math.BigDecimal;
24320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport java.util.GregorianCalendar;
25320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
26320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson/**
27320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Factory that creates new <code>javax.xml.datatype</code> <code>Object</code>s that map XML to/from Java <code>Object</code>s.</p>
28f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
29320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p id="DatatypeFactory.newInstance">{@link #newInstance()} is used to create a new <code>DatatypeFactory</code>.
30320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * The following implementation resolution mechanisms are used in the following order:</p>
31320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <ol>
32320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *    <li>
33320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *      If the system property specified by {@link #DATATYPEFACTORY_PROPERTY}, "<code>javax.xml.datatype.DatatypeFactory</code>",
34320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *      exists, a class with the name of the property's value is instantiated.
35320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *      Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}.
36320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *    </li>
37320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *    <li>
38320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *      If the file ${JAVA_HOME}/lib/jaxp.properties exists, it is loaded in a {@link java.util.Properties} <code>Object</code>.
39320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *      The <code>Properties</code> <code>Object </code> is then queried for the property as documented in the prior step
40320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *      and processed as documented in the prior step.
41320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *    </li>
42320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *    <li>
43320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *      The services resolution mechanism is used, e.g. <code>META-INF/services/java.xml.datatype.DatatypeFactory</code>.
44320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *      Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}.
45320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *    </li>
46320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *    <li>
47320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *      The final mechanism is to attempt to instantiate the <code>Class</code> specified by
48320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *      {@link #DATATYPEFACTORY_IMPLEMENTATION_CLASS}, "<code>javax.xml.datatype.DatatypeFactoryImpl</code>".
49320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *      Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}.
50320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson *    </li>
51f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * </ol>
52f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes *
53320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @author <a href="mailto:Joseph.Fialli@Sun.COM">Joseph Fialli</a>
54320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
55320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @version $Revision: 884950 $, $Date: 2009-11-27 10:46:18 -0800 (Fri, 27 Nov 2009) $
56320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @since 1.5
57320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */
58320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonpublic abstract class DatatypeFactory {
59320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
60320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
61320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Default property name as defined in JSR 206: Java(TM) API for XML Processing (JAXP) 1.3.</p>
62f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
63320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Default value is <code>javax.xml.datatype.DatatypeFactory</code>.</p>
64320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
65320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public static final String DATATYPEFACTORY_PROPERTY = "javax.xml.datatype.DatatypeFactory";
66320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
67320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
68320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Default implementation class name as defined in JSR 206: Java(TM) API for XML Processing (JAXP) 1.3.</p>
69f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
70320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Default value is <code>org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl</code>.</p>
71320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
72320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS = new String("org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl");
73320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
74320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
75320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Protected constructor to prevent instantiation outside of package.</p>
76f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
77320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Use {@link #newInstance()} to create a <code>DatatypeFactory</code>.</p>
78320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
79320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    protected DatatypeFactory() {}
80320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
81320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
82320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Obtain a new instance of a <code>DatatypeFactory</code>.</p>
83f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
84320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The implementation resolution mechanisms are <a href="#DatatypeFactory.newInstance">defined</a> in this
85320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>Class</code>'s documentation.</p>
86f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
87320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New instance of a <code>DocumentBuilderFactory</code>
88320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
89320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws DatatypeConfigurationException If the implementation is not
90320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   available or cannot be instantiated.
91320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
92320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public static DatatypeFactory newInstance()
93320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        throws DatatypeConfigurationException {
94320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        try {
95320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            return (DatatypeFactory) FactoryFinder.find(
96320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                    /* The default property name according to the JAXP spec */
97320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                    DATATYPEFACTORY_PROPERTY,
98320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                    /* The fallback implementation class name */
99320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                    DATATYPEFACTORY_IMPLEMENTATION_CLASS);
100f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        }
101320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        catch (FactoryFinder.ConfigurationError e) {
102320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            throw new DatatypeConfigurationException(e.getMessage(), e.getException());
103320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
104320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
105320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
106320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    // BEGIN android-only
107320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //     omit this method which wasn't included in Java 5
108320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    // /**
109320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //  * @return New instance of a <code>DocumentBuilderFactory</code>
110320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //  *
111320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //  * @throws DatatypeConfigurationException If the implementation is not
112320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //  *   available or cannot be instantiated.
113320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //  * @since 1.6
114320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //  */
115320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    // public static DatatypeFactory newInstance(String factoryClassName,
116320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //         ClassLoader classLoader) throws DatatypeConfigurationException {
117320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //     if (factoryClassName == null) {
118320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //         throw new DatatypeConfigurationException("factoryClassName cannot be null.");
119320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //     }
120320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //     if (classLoader == null) {
121320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //         classLoader = SecuritySupport.getContextClassLoader();
122320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //     }
123320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //     try {
124320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //         return (DatatypeFactory) FactoryFinder.newInstance(factoryClassName, classLoader);
125320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //     }
126320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //     catch (FactoryFinder.ConfigurationError e) {
127320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //         throw new DatatypeConfigurationException(e.getMessage(), e.getException());
128320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    //     }
129320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    // }
130320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    // END android-only
131320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
132320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
133320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Obtain a new instance of a <code>Duration</code>
134320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * specifying the <code>Duration</code> as its string representation, "PnYnMnDTnHnMnS",
135320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * as defined in XML Schema 1.0 section 3.2.6.1.</p>
136f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
137320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p>
138320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <blockquote>
139320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * duration represents a duration of time.
140320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * The value space of duration is a six-dimensional space where the coordinates designate the
141320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively.
142320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * These components are ordered in their significance by their order of appearance i.e. as
143f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * year, month, day, hour, minute, and second.
144320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * </blockquote>
145320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>All six values are set and available from the created {@link Duration}</p>
146f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
147320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The XML Schema specification states that values can be of an arbitrary size.
148320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values.
149320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits
150320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * if implementation capacities are exceeded.</p>
151f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
152320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param lexicalRepresentation <code>String</code> representation of a <code>Duration</code>.
153f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
154320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>Duration</code> created from parsing the <code>lexicalRepresentation</code>.
155f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
156320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code>.
157320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws UnsupportedOperationException If implementation cannot support requested values.
158320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws NullPointerException if <code>lexicalRepresentation</code> is <code>null</code>.
159320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
160320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public abstract Duration newDuration(final String lexicalRepresentation);
161320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
162320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
163320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Obtain a new instance of a <code>Duration</code>
164320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * specifying the <code>Duration</code> as milliseconds.</p>
165f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
166320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p>
167320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <blockquote>
168320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * duration represents a duration of time.
169320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * The value space of duration is a six-dimensional space where the coordinates designate the
170320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively.
171320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * These components are ordered in their significance by their order of appearance i.e. as
172f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * year, month, day, hour, minute, and second.
173320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * </blockquote>
174320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>All six values are set by computing their values from the specified milliseconds
175320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * and are available using the <code>get</code> methods of  the created {@link Duration}.
176320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * The values conform to and are defined by:</p>
177320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <ul>
178320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li>
179320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats">
180320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a>
181320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   </li>
182320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   <li>{@link XMLGregorianCalendar}  Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li>
183320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * </ul>
184f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
185320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e.,
186320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link java.util.Calendar#YEAR} = 1970,
187320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY},
188320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link java.util.Calendar#DATE} = 1, etc.
189320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * This is important as there are variations in the Gregorian Calendar,
190320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY}
191f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * so the result of {@link Duration#getMonths()} and {@link Duration#getDays()} can be influenced.</p>
192f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
193320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param durationInMilliSeconds Duration in milliseconds to create.
194f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
195320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>Duration</code> representing <code>durationInMilliSeconds</code>.
196320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
197320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public abstract Duration newDuration(final long durationInMilliSeconds);
198320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
199320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
200320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Obtain a new instance of a <code>Duration</code>
201320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * specifying the <code>Duration</code> as isPositive, years, months, days, hours, minutes, seconds.</p>
202f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
203320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The XML Schema specification states that values can be of an arbitrary size.
204320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values.
205320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits
206320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * if implementation capacities are exceeded.</p>
207f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
208320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A <code>null</code> value indicates that field is not set.</p>
209f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
210320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param isPositive Set to <code>false</code> to create a negative duration. When the length
211320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   of the duration is zero, this parameter will be ignored.
212320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param years of this <code>Duration</code>
213320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param months of this <code>Duration</code>
214320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param days of this <code>Duration</code>
215320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param hours of this <code>Duration</code>
216320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param minutes of this <code>Duration</code>
217320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param seconds of this <code>Duration</code>
218f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
219320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>Duration</code> created from the specified values.
220f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
221320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws IllegalArgumentException If values are not a valid representation of a <code>Duration</code>.
222320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws UnsupportedOperationException If implementation cannot support requested values.
223320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
224320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public abstract Duration newDuration(
225320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final boolean isPositive,
226320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigInteger years,
227320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigInteger months,
228320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigInteger days,
229320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigInteger hours,
230320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigInteger minutes,
231320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigDecimal seconds);
232320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
233320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
234320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Obtain a new instance of a <code>Duration</code>
235320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * specifying the <code>Duration</code> as isPositive, years, months, days, hours, minutes, seconds.</p>
236f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
237320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
238f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
239320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param isPositive Set to <code>false</code> to create a negative duration. When the length
240320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   of the duration is zero, this parameter will be ignored.
241320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param years of this <code>Duration</code>
242320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param months of this <code>Duration</code>
243320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param days of this <code>Duration</code>
244320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param hours of this <code>Duration</code>
245320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param minutes of this <code>Duration</code>
246320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param seconds of this <code>Duration</code>
247f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
248320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>Duration</code> created from the specified values.
249f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
250320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws IllegalArgumentException If values are not a valid representation of a <code>Duration</code>.
251f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
252320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @see #newDuration(
253320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   boolean isPositive,
254320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   BigInteger years,
255320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   BigInteger months,
256320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   BigInteger days,
257320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   BigInteger hours,
258320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   BigInteger minutes,
259320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   BigDecimal seconds)
260320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
261320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public Duration newDuration(
262320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final boolean isPositive,
263320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int years,
264320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int months,
265320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int days,
266320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int hours,
267320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int minutes,
268320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int seconds) {
269320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
270320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // years may not be set
271320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigInteger realYears = (years != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) years) : null;
272320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
273320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // months may not be set
274320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigInteger realMonths = (months != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) months) : null;
275320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
276320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // days may not be set
277320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigInteger realDays = (days != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) days) : null;
278320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
279320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // hours may not be set
280320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigInteger realHours = (hours != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) hours) : null;
281320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
282320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // minutes may not be set
283320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigInteger realMinutes = (minutes != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) minutes) : null;
284320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
285320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // seconds may not be set
286320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigDecimal realSeconds = (seconds != DatatypeConstants.FIELD_UNDEFINED) ? BigDecimal.valueOf((long) seconds) : null;
287320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
288320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return newDuration(
289320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                isPositive,
290320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                realYears,
291320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                realMonths,
292320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                realDays,
293320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                realHours,
294320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                realMinutes,
295320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                realSeconds
296320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        );
297320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
298320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
299320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
300320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> by parsing its <code>String</code> representation,
301320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * "<em>PnDTnHnMnS</em>", <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
302320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p>
303f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
304320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code>
305320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * whose lexical representation contains only day, hour, minute, and second components.
306320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p>
307f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
308320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>All four values are set and available from the created {@link Duration}</p>
309f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
310320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The XML Schema specification states that values can be of an arbitrary size.
311320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values.
312320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits
313320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * if implementation capacities are exceeded.</p>
314f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
315320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param lexicalRepresentation Lexical representation of a duration.
316f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
317320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>Duration</code> created using the specified <code>lexicalRepresentation</code>.
318f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
319320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws IllegalArgumentException If the given string does not conform to the aforementioned specification.
320320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws UnsupportedOperationException If implementation cannot support requested values.
321320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>.
322320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
323320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public Duration newDurationDayTime(final String lexicalRepresentation) {
324320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (lexicalRepresentation == null) {
325320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            throw new NullPointerException("The lexical representation cannot be null.");
326320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
327320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // The lexical representation must match the pattern [^YM]*(T.*)?
328320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        int pos = lexicalRepresentation.indexOf('T');
329320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        int length = (pos >= 0) ? pos : lexicalRepresentation.length();
330320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        for (int i = 0; i < length; ++i) {
331320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            char c = lexicalRepresentation.charAt(i);
332320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            if (c == 'Y' || c == 'M') {
333320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                throw new IllegalArgumentException("Invalid dayTimeDuration value: " + lexicalRepresentation);
334320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            }
335320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
336320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return newDuration(lexicalRepresentation);
337320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
338320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
339320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
340320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified milliseconds as defined in
341320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
342320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p>
343f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
344320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code>
345320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * whose lexical representation contains only day, hour, minute, and second components.
346320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p>
347f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
348320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>All four values are set by computing their values from the specified milliseconds
349320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * and are available using the <code>get</code> methods of  the created {@link Duration}.
350320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * The values conform to and are defined by:</p>
351320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <ul>
352320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li>
353320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats">
354320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a>
355320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   </li>
356320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   <li>{@link XMLGregorianCalendar}  Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li>
357320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * </ul>
358f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
359320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e.,
360320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link java.util.Calendar#YEAR} = 1970,
361320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY},
362320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link java.util.Calendar#DATE} = 1, etc.
363320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * This is important as there are variations in the Gregorian Calendar,
364320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY}
365320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * so the result of {@link Duration#getDays()} can be influenced.</p>
366f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
367320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Any remaining milliseconds after determining the day, hour, minute and second are discarded.</p>
368f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
369320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create.
370f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
371320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>Duration</code> created with the specified <code>durationInMilliseconds</code>.
372f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
373320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @see <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
374320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>
375320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
376320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public Duration newDurationDayTime(final long durationInMilliseconds) {
377320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        long _durationInMilliseconds = durationInMilliseconds;
378320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (_durationInMilliseconds == 0) {
379f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            return newDuration(true, DatatypeConstants.FIELD_UNDEFINED,
380320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                    DatatypeConstants.FIELD_UNDEFINED, 0, 0, 0, 0);
381320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
382320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        boolean tooLong = false;
383320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        final boolean isPositive;
384320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (_durationInMilliseconds < 0) {
385320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            isPositive = false;
386320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            if (_durationInMilliseconds == Long.MIN_VALUE) {
387320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                _durationInMilliseconds++;
388320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                tooLong = true;
389320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            }
390320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            _durationInMilliseconds *= -1;
391320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
392320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        else {
393320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            isPositive = true;
394320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
395f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
396320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        long val = _durationInMilliseconds;
397320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        int milliseconds = (int) (val % 60000L); // 60000 milliseconds per minute
398320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (tooLong) {
399320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            ++milliseconds;
400320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
401320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (milliseconds % 1000 == 0) {
402320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            int seconds = milliseconds / 1000;
403320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            val = val / 60000L;
404320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            int minutes = (int) (val % 60L); // 60 minutes per hour
405320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            val = val / 60L;
406320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            int hours = (int) (val % 24L); // 24 hours per day
407320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            long days = val / 24L;
408320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            if (days <= ((long) Integer.MAX_VALUE)) {
409320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                return newDuration(isPositive, DatatypeConstants.FIELD_UNDEFINED,
410320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                        DatatypeConstants.FIELD_UNDEFINED, (int) days, hours, minutes, seconds);
411320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            }
412320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            else {
413320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                return newDuration(isPositive, null, null,
414f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                        BigInteger.valueOf(days), BigInteger.valueOf(hours),
415320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                        BigInteger.valueOf(minutes), BigDecimal.valueOf(milliseconds, 3));
416f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            }
417320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
418f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
419320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigDecimal seconds = BigDecimal.valueOf(milliseconds, 3);
420320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        val = val / 60000L;
421320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigInteger minutes = BigInteger.valueOf(val % 60L); // 60 minutes per hour
422320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        val = val / 60L;
423320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigInteger hours = BigInteger.valueOf(val % 24L); // 24 hours per day
424320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        val = val / 24L;
425320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigInteger days = BigInteger.valueOf(val);
426320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return newDuration(isPositive, null, null, days, hours, minutes, seconds);
427320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
428320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
429320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
430320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified
431320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>day</code>, <code>hour</code>, <code>minute</code> and <code>second</code> as defined in
432320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
433320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p>
434f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
435320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code>
436320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * whose lexical representation contains only day, hour, minute, and second components.
437320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p>
438f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
439320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The XML Schema specification states that values can be of an arbitrary size.
440320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values.
441320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits
442320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * if implementation capacities are exceeded.</p>
443f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
444320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A <code>null</code> value indicates that field is not set.</p>
445f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
446320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param isPositive Set to <code>false</code> to create a negative duration. When the length
447320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   of the duration is zero, this parameter will be ignored.
448320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param day Day of <code>Duration</code>.
449320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param hour Hour of <code>Duration</code>.
450320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param minute Minute of <code>Duration</code>.
451320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param second Second of <code>Duration</code>.
452f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
453320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>Duration</code> created with the specified <code>day</code>, <code>hour</code>, <code>minute</code>
454320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * and <code>second</code>.
455f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
456f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * @throws IllegalArgumentException If any values would create an invalid <code>Duration</code>.
457320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws UnsupportedOperationException If implementation cannot support requested values.
458f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     */
459320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public Duration newDurationDayTime(
460320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final boolean isPositive,
461320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigInteger day,
462320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigInteger hour,
463320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigInteger minute,
464320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigInteger second) {
465320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
466320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return newDuration(
467320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                isPositive,
468320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                null,  // years
469320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                null, // months
470320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                day,
471320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                hour,
472320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                minute,
473320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                (second != null)? new BigDecimal(second):null
474320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        );
475320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
476320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
477320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
478320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified
479320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>day</code>, <code>hour</code>, <code>minute</code> and <code>second</code> as defined in
480320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration">
481320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p>
482f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
483320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code>
484320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * whose lexical representation contains only day, hour, minute, and second components.
485320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p>
486f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
487320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
488f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
489320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param isPositive Set to <code>false</code> to create a negative duration. When the length
490320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   of the duration is zero, this parameter will be ignored.
491320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param day Day of <code>Duration</code>.
492320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param hour Hour of <code>Duration</code>.
493320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param minute Minute of <code>Duration</code>.
494320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param second Second of <code>Duration</code>.
495f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
496320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>Duration</code> created with the specified <code>day</code>, <code>hour</code>, <code>minute</code>
497320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * and <code>second</code>.
498f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
499f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * @throws IllegalArgumentException If any values would create an invalid <code>Duration</code>.
500f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     */
501320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public Duration newDurationDayTime(
502320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final boolean isPositive,
503320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int day,
504320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int hour,
505320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int minute,
506320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int second) {
507f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        return newDuration(isPositive,
508320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED,
509320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                day, hour, minute, second);
510320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
511320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
512320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
513320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> by parsing its <code>String</code> representation,
514320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * "<em>PnYnM</em>", <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration">
515320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p>
516f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
517320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code>
518320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * whose lexical representation contains only year and month components.
519320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p>
520f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
521320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Both values are set and available from the created {@link Duration}</p>
522f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
523320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The XML Schema specification states that values can be of an arbitrary size.
524320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values.
525320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits
526320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * if implementation capacities are exceeded.</p>
527f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
528320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param lexicalRepresentation Lexical representation of a duration.
529f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
530320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>Duration</code> created using the specified <code>lexicalRepresentation</code>.
531f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
532320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws IllegalArgumentException If the <code>lexicalRepresentation</code> does not conform to the specification.
533320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws UnsupportedOperationException If implementation cannot support requested values.
534320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>.
535320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
536320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public Duration newDurationYearMonth(final String lexicalRepresentation) {
537320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (lexicalRepresentation == null) {
538320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            throw new NullPointerException("The lexical representation cannot be null.");
539320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
540320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // The lexical representation must match the pattern [^DT]*.
541320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        int length = lexicalRepresentation.length();
542320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        for (int i = 0; i < length; ++i) {
543320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            char c = lexicalRepresentation.charAt(i);
544320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            if (c == 'D' || c == 'T') {
545320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                throw new IllegalArgumentException("Invalid yearMonthDuration value: " + lexicalRepresentation);
546320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            }
547320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
548320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return newDuration(lexicalRepresentation);
549320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
550320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
551320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
552320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified milliseconds as defined in
553320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration">
554320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p>
555f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
556320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code>
557320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * whose lexical representation contains only year and month components.
558320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p>
559f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
560320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Both values are set by computing their values from the specified milliseconds
561320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * and are available using the <code>get</code> methods of  the created {@link Duration}.
562320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * The values conform to and are defined by:</p>
563320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <ul>
564320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li>
565320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats">
566320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a>
567320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   </li>
568320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   <li>{@link XMLGregorianCalendar}  Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li>
569320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * </ul>
570f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
571320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e.,
572320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link java.util.Calendar#YEAR} = 1970,
573320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY},
574320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link java.util.Calendar#DATE} = 1, etc.
575320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * This is important as there are variations in the Gregorian Calendar,
576320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY}
577320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * so the result of {@link Duration#getMonths()} can be influenced.</p>
578f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
579320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Any remaining milliseconds after determining the year and month are discarded.</p>
580f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
581320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create.
582f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
583320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>Duration</code> created using the specified <code>durationInMilliseconds</code>.
584320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
585320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public Duration newDurationYearMonth(final long durationInMilliseconds) {
586320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
587320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return newDuration(durationInMilliseconds);
588320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
589320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
590320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
591320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified
592320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>year</code> and <code>month</code> as defined in
593320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthyDuration">
594320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p>
595f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
596320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The XML Schema specification states that values can be of an arbitrary size.
597320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values.
598320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits
599320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * if implementation capacities are exceeded.</p>
600f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
601320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A <code>null</code> value indicates that field is not set.</p>
602f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
603320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param isPositive Set to <code>false</code> to create a negative duration. When the length
604320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   of the duration is zero, this parameter will be ignored.
605320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param year Year of <code>Duration</code>.
606320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param month Month of <code>Duration</code>.
607f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
608320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>Duration</code> created using the specified <code>year</code> and <code>month</code>.
609f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
610f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * @throws IllegalArgumentException If any values would create an invalid <code>Duration</code>.
611320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws UnsupportedOperationException If implementation cannot support requested values.
612f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     */
613320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public Duration newDurationYearMonth(
614320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final boolean isPositive,
615320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigInteger year,
616320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigInteger month) {
617320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
618320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return newDuration(
619320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                isPositive,
620320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                year,
621320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                month,
622320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                null, // days
623320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                null, // hours
624320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                null, // minutes
625320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                null  // seconds
626320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        );
627320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
628320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
629320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
630320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified
631320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>year</code> and <code>month</code> as defined in
632320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthyDuration">
633320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p>
634f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
635320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
636f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
637320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param isPositive Set to <code>false</code> to create a negative duration. When the length
638320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   of the duration is zero, this parameter will be ignored.
639320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param year Year of <code>Duration</code>.
640320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param month Month of <code>Duration</code>.
641f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
642320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>Duration</code> created using the specified <code>year</code> and <code>month</code>.
643f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
644f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * @throws IllegalArgumentException If any values would create an invalid <code>Duration</code>.
645f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     */
646320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public Duration newDurationYearMonth(
647320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final boolean isPositive,
648320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int year,
649320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int month) {
650f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        return newDuration(isPositive, year, month,
651320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED,
652320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);
653320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
654320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
655320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
656320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a new instance of an <code>XMLGregorianCalendar</code>.</p>
657f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
658320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>All date/time datatype fields set to {@link DatatypeConstants#FIELD_UNDEFINED} or null.</p>
659f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
660320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return New <code>XMLGregorianCalendar</code> with all date/time datatype fields set to
661320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   {@link DatatypeConstants#FIELD_UNDEFINED} or null.
662320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
663320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public abstract XMLGregorianCalendar newXMLGregorianCalendar();
664320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
665320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
666320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a new XMLGregorianCalendar by parsing the String as a lexical representation.</p>
667f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
668f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * <p>Parsing the lexical string representation is defined in
669320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime-order">XML Schema 1.0 Part 2, Section 3.2.[7-14].1,
670320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <em>Lexical Representation</em>.</a></p>
671f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
672320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The string representation may not have any leading and trailing whitespaces.</p>
673f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
674320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>The parsing is done field by field so that
675320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * the following holds for any lexically correct String x:</p>
676320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <pre>
677320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * newXMLGregorianCalendar(x).toXMLFormat().equals(x)
678320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * </pre>
679320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Except for the noted lexical/canonical representation mismatches
680320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * listed in <a href="http://www.w3.org/2001/05/xmlschema-errata#e2-45">
681320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * XML Schema 1.0 errata, Section 3.2.7.2</a>.</p>
682f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
683320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param lexicalRepresentation Lexical representation of one the eight XML Schema date/time datatypes.
684f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
685320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return <code>XMLGregorianCalendar</code> created from the <code>lexicalRepresentation</code>.
686f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
687320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws IllegalArgumentException If the <code>lexicalRepresentation</code> is not a valid <code>XMLGregorianCalendar</code>.
688320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>.
689320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
690320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public abstract XMLGregorianCalendar newXMLGregorianCalendar(final String lexicalRepresentation);
691320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
692320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
693f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * <p>Create an <code>XMLGregorianCalendar</code> from a {@link GregorianCalendar}.</p>
694320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
695320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <table border="2" rules="all" cellpadding="2">
696320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   <thead>
697320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     <tr>
698320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       <th align="center" colspan="2">
699320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *          Field by Field Conversion from
700f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *          {@link GregorianCalendar} to an {@link XMLGregorianCalendar}
701320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       </th>
702320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     </tr>
703320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     <tr>
704320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *        <th><code>java.util.GregorianCalendar</code> field</th>
705320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *        <th><code>javax.xml.datatype.XMLGregorianCalendar</code> field</th>
706320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     </tr>
707320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   </thead>
708320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   <tbody>
709320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     <tr>
710320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       <td><code>ERA == GregorianCalendar.BC ? -YEAR : YEAR</code></td>
711320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       <td>{@link XMLGregorianCalendar#setYear(int year)}</td>
712320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     </tr>
713320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     <tr>
714320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       <td><code>MONTH + 1</code></td>
715320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       <td>{@link XMLGregorianCalendar#setMonth(int month)}</td>
716320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     </tr>
717320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     <tr>
718320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       <td><code>DAY_OF_MONTH</code></td>
719320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       <td>{@link XMLGregorianCalendar#setDay(int day)}</td>
720320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     </tr>
721320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     <tr>
722320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       <td><code>HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND</code></td>
723320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       <td>{@link XMLGregorianCalendar#setTime(int hour, int minute, int second, BigDecimal fractional)}</td>
724320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     </tr>
725320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     <tr>
726320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       <td>
727320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *         <code>(ZONE_OFFSET + DST_OFFSET) / (60*1000)</code><br/>
728320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *         <em>(in minutes)</em>
729320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       </td>
730320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       <td>{@link XMLGregorianCalendar#setTimezone(int offset)}<sup><em>*</em></sup>
731320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *       </td>
732320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *     </tr>
733320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   </tbody>
734320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * </table>
735f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * <p><em>*</em>conversion loss of information. It is not possible to represent
736f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * a <code>java.util.GregorianCalendar</code> daylight savings timezone id in the
737320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * XML Schema 1.0 date/time datatype representation.</p>
738f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
739320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>To compute the return value's <code>TimeZone</code> field,
740320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <ul>
741320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <li>when <code>this.getTimezone() != FIELD_UNDEFINED</code>,
742f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * create a <code>java.util.TimeZone</code> with a custom timezone id
743320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * using the <code>this.getTimezone()</code>.</li>
744f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * <li>else use the <code>GregorianCalendar</code> default timezone value
745f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * for the host is defined as specified by
746f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * <code>java.util.TimeZone.getDefault()</code>.</li></p>
747320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
748320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param cal <code>java.util.GregorianCalendar</code> used to create <code>XMLGregorianCalendar</code>
749f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
750320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return <code>XMLGregorianCalendar</code> created from <code>java.util.GregorianCalendar</code>
751f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
752320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws NullPointerException If <code>cal</code> is <code>null</code>.
753320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
754320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public abstract XMLGregorianCalendar newXMLGregorianCalendar(final GregorianCalendar cal);
755320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
756320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
757f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * <p>Constructor allowing for complete value spaces allowed by
758f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * W3C XML Schema 1.0 recommendation for xsd:dateTime and related
759320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * builtin datatypes. Note that <code>year</code> parameter supports
760f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * arbitrarily large numbers and fractionalSecond has infinite
761320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * precision.</p>
762f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
763320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A <code>null</code> value indicates that field is not set.</p>
764f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
765320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param year of <code>XMLGregorianCalendar</code> to be created.
766320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param month of <code>XMLGregorianCalendar</code> to be created.
767320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param day of <code>XMLGregorianCalendar</code> to be created.
768320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param hour of <code>XMLGregorianCalendar</code> to be created.
769320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param minute of <code>XMLGregorianCalendar</code> to be created.
770320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param second of <code>XMLGregorianCalendar</code> to be created.
771320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param fractionalSecond of <code>XMLGregorianCalendar</code> to be created.
772320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param timezone of <code>XMLGregorianCalendar</code> to be created.
773f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
774320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return <code>XMLGregorianCalendar</code> created from specified values.
775f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
776320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field
777320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar}
778320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance
779320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   as determined by {@link XMLGregorianCalendar#isValid()}.
780320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
781320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public abstract XMLGregorianCalendar newXMLGregorianCalendar(
782320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigInteger year,
783320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int month,
784320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int day,
785320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int hour,
786320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int minute,
787320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int second,
788320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigDecimal fractionalSecond,
789320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int timezone);
790320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
791320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
792320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Constructor of value spaces that a
793320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>java.util.GregorianCalendar</code> instance would need to convert to an
794320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>XMLGregorianCalendar</code> instance.</p>
795f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
796f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * <p><code>XMLGregorianCalendar eon</code> and
797320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <code>fractionalSecond</code> are set to <code>null</code></p>
798320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
799320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
800f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
801320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param year of <code>XMLGregorianCalendar</code> to be created.
802320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param month of <code>XMLGregorianCalendar</code> to be created.
803320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param day of <code>XMLGregorianCalendar</code> to be created.
804320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param hour of <code>XMLGregorianCalendar</code> to be created.
805320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param minute of <code>XMLGregorianCalendar</code> to be created.
806320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param second of <code>XMLGregorianCalendar</code> to be created.
807320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param millisecond of <code>XMLGregorianCalendar</code> to be created.
808320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param timezone of <code>XMLGregorianCalendar</code> to be created.
809f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
810320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return <code>XMLGregorianCalendar</code> created from specified values.
811f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
812320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field
813320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar}
814320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance
815320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   as determined by {@link XMLGregorianCalendar#isValid()}.
816320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
817320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public XMLGregorianCalendar newXMLGregorianCalendar(
818320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int year,
819320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int month,
820320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int day,
821320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int hour,
822320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int minute,
823320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int second,
824320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int millisecond,
825320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int timezone) {
826320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
827320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // year may be undefined
828320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigInteger realYear = (year != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) year) : null;
829320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
830320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // millisecond may be undefined
831320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // millisecond must be >= 0 millisecond <= 1000
832320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigDecimal realMillisecond = null; // undefined value
833320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (millisecond != DatatypeConstants.FIELD_UNDEFINED) {
834320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            if (millisecond < 0 || millisecond > 1000) {
835320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                throw new IllegalArgumentException(
836320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                        "javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendar("
837320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                        + "int year, int month, int day, int hour, int minute, int second, int millisecond, int timezone)"
838320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                        + "with invalid millisecond: " + millisecond
839320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                );
840320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            }
841320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            realMillisecond = BigDecimal.valueOf((long) millisecond, 3);
842320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
843320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
844320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return newXMLGregorianCalendar(
845320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                realYear,
846320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                month,
847320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                day,
848320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                hour,
849320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                minute,
850320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                second,
851320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                realMillisecond,
852320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                timezone
853320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        );
854320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
855320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
856320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
857320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a Java representation of XML Schema builtin datatype <code>date</code> or <code>g*</code>.</p>
858f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
859f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * <p>For example, an instance of <code>gYear</code> can be created invoking this factory
860f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * with <code>month</code> and <code>day</code> parameters set to
861320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * {@link DatatypeConstants#FIELD_UNDEFINED}.</p>
862f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
863320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
864f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
865320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param year of <code>XMLGregorianCalendar</code> to be created.
866320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param month of <code>XMLGregorianCalendar</code> to be created.
867320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param day of <code>XMLGregorianCalendar</code> to be created.
868320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
869f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
870320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return <code>XMLGregorianCalendar</code> created from parameter values.
871f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
872320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @see DatatypeConstants#FIELD_UNDEFINED
873320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
874320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field
875320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar}
876320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance
877320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   as determined by {@link XMLGregorianCalendar#isValid()}.
878320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
879320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public XMLGregorianCalendar newXMLGregorianCalendarDate(
880320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int year,
881320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int month,
882320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int day,
883320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int timezone) {
884320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
885320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return newXMLGregorianCalendar(
886320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                year,
887320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                month,
888320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                day,
889320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, // hour
890320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, // minute
891320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, // second
892320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, // millisecond
893320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                timezone);
894320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
895320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
896320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
897320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a Java instance of XML Schema builtin datatype <code>time</code>.</p>
898f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
899320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
900f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
901320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param hours number of hours
902320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param minutes number of minutes
903320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param seconds number of seconds
904320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
905f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
906320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return <code>XMLGregorianCalendar</code> created from parameter values.
907f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
908320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field
909320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar}
910320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance
911320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   as determined by {@link XMLGregorianCalendar#isValid()}.
912f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
913320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @see DatatypeConstants#FIELD_UNDEFINED
914320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
915320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public XMLGregorianCalendar newXMLGregorianCalendarTime(
916320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int hours,
917320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int minutes,
918320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int seconds,
919320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int timezone) {
920320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
921320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return newXMLGregorianCalendar(
922320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, // Year
923320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, // Month
924320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, // Day
925320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                hours,
926320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                minutes,
927320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                seconds,
928320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, //Millisecond
929320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                timezone);
930320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
931320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
932320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
933320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a Java instance of XML Schema builtin datatype time.</p>
934f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
935320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A <code>null</code> value indicates that field is not set.</p>
936320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
937f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
938320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param hours number of hours
939320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param minutes number of minutes
940320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param seconds number of seconds
941320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param fractionalSecond value of <code>null</code> indicates that this optional field is not set.
942320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
943f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
944320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return <code>XMLGregorianCalendar</code> created from parameter values.
945f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
946320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @see DatatypeConstants#FIELD_UNDEFINED
947320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
948320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field
949320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar}
950320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance
951320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   as determined by {@link XMLGregorianCalendar#isValid()}.
952320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
953320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public XMLGregorianCalendar newXMLGregorianCalendarTime(
954320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int hours,
955320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int minutes,
956320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int seconds,
957320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final BigDecimal fractionalSecond,
958320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int timezone) {
959320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
960320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return newXMLGregorianCalendar(
961320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                null, // year
962320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, // month
963320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                DatatypeConstants.FIELD_UNDEFINED, // day
964320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                hours,
965320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                minutes,
966320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                seconds,
967320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                fractionalSecond,
968320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                timezone);
969320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
970320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
971320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    /**
972320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>Create a Java instance of XML Schema builtin datatype time.</p>
973f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
974320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p>
975f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
976320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param hours number of hours
977320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param minutes number of minutes
978320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param seconds number of seconds
979320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param milliseconds number of milliseconds
980320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set.
981f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
982320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @return <code>XMLGregorianCalendar</code> created from parameter values.
983f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
984320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @see DatatypeConstants#FIELD_UNDEFINED
985320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *
986320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field
987320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar}
988320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance
989320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     *   as determined by {@link XMLGregorianCalendar#isValid()}.
990320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson     */
991320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    public XMLGregorianCalendar newXMLGregorianCalendarTime(
992320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int hours,
993320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int minutes,
994320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int seconds,
995320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int milliseconds,
996320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            final int timezone) {
997320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
998320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // millisecond may be undefined
999320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        // millisecond must be >= 0 millisecond <= 1000
1000320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        BigDecimal realMilliseconds = null; // undefined value
1001320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        if (milliseconds != DatatypeConstants.FIELD_UNDEFINED) {
1002320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            if (milliseconds < 0 || milliseconds > 1000) {
1003320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                throw new IllegalArgumentException(
1004320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                        "javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendarTime("
1005320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                        + "int hours, int minutes, int seconds, int milliseconds, int timezone)"
1006320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                        + "with invalid milliseconds: " + milliseconds
1007320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                );
1008320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            }
1009320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson            realMilliseconds = BigDecimal.valueOf((long) milliseconds, 3);
1010320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        }
1011320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson
1012320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        return newXMLGregorianCalendarTime(
1013320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                hours,
1014320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                minutes,
1015320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                seconds,
1016320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                realMilliseconds,
1017320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson                timezone
1018320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson        );
1019320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson    }
1020320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson}
1021