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: Duration.java 759828 2009-03-30 01:26:29Z mrglavas $ 19320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 20320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonpackage javax.xml.datatype; 21320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 22320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport java.math.BigDecimal; 23320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport java.math.BigInteger; 24320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport java.util.Calendar; 25320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport java.util.Date; 26320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport java.util.GregorianCalendar; 27320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport javax.xml.namespace.QName; 28320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 29320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson/** 30320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Immutable representation of a time span as defined in 31320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * the W3C XML Schema 1.0 specification.</p> 32f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 33320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>A Duration object represents a period of Gregorian time, 34320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * which consists of six fields (years, months, days, hours, 35320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * minutes, and seconds) plus a sign (+/-) field.</p> 36f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 37320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>The first five fields have non-negative (>=0) integers or null 38320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * (which represents that the field is not set), 39320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * and the seconds field has a non-negative decimal or null. 40f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * A negative sign indicates a negative duration.</p> 41f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 42320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>This class provides a number of methods that make it easy 43320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * to use for the duration datatype of XML Schema 1.0 with 44320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * the errata.</p> 45f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 46320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <h2>Order relationship</h2> 47320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Duration objects only have partial order, where two values A and B 48320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * maybe either:</p> 49320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <ol> 50320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <li>A<B (A is shorter than B) 51320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <li>A>B (A is longer than B) 52320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <li>A==B (A and B are of the same duration) 53320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <li>A<>B (Comparison between A and B is indeterminate) 54320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </ol> 55320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 56320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>For example, 30 days cannot be meaningfully compared to one month. 57320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * The {@link #compare(Duration duration)} method implements this 58320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * relationship.</p> 59f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 60320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>See the {@link #isLongerThan(Duration)} method for details about 61320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * the order relationship among <code>Duration</code> objects.</p> 62f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 63320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <h2>Operations over Duration</h2> 64320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>This class provides a set of basic arithmetic operations, such 65320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * as addition, subtraction and multiplication. 66320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Because durations don't have total order, an operation could 67320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * fail for some combinations of operations. For example, you cannot 68320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * subtract 15 days from 1 month. See the javadoc of those methods 69320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * for detailed conditions where this could happen.</p> 70f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 71320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Also, division of a duration by a number is not provided because 72320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * the <code>Duration</code> class can only deal with finite precision 73f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * decimal numbers. For example, one cannot represent 1 sec divided by 3.</p> 74f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 75320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>However, you could substitute a division by 3 with multiplying 76320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * by numbers such as 0.3 or 0.333.</p> 77f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 78320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <h2>Range of allowed values</h2> 79320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 80320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Because some operations of <code>Duration</code> rely on {@link Calendar} 81320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * even though {@link Duration} can hold very large or very small values, 82320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * some of the methods may not work correctly on such <code>Duration</code>s. 83320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * The impacted methods document their dependency on {@link Calendar}. 84f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 85f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 86320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @author <a href="mailto:Joseph.Fialli@Sun.COM">Joseph Fialli</a> 87320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @author <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a> 88320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a> 89f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @version $Revision: 759828 $, $Date: 2009-03-29 18:26:29 -0700 (Sun, 29 Mar 2009) $ 90320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see XMLGregorianCalendar#add(Duration) 91320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @since 1.5 92320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 93320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonpublic abstract class Duration { 94320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 95320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 96f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * <p>Return the name of the XML Schema date/time type that this instance 97320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * maps to. Type is computed based on fields that are set, 98320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * i.e. {@link #isSet(DatatypeConstants.Field field)} == <code>true</code>.</p> 99320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 100320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <table border="2" rules="all" cellpadding="2"> 101320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <thead> 102320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <tr> 103320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <th align="center" colspan="7"> 104320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Required fields for XML Schema 1.0 Date/Time Datatypes.<br/> 105320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <i>(timezone is optional for all date/time datatypes)</i> 106320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </th> 107320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </tr> 108320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </thead> 109320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <tbody> 110320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <tr> 111320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>Datatype</td> 112320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>year</td> 113320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>month</td> 114320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>day</td> 115320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>hour</td> 116320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>minute</td> 117320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>second</td> 118320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </tr> 119320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <tr> 120320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>{@link DatatypeConstants#DURATION}</td> 121320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>X</td> 122320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>X</td> 123320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>X</td> 124320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>X</td> 125320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>X</td> 126320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>X</td> 127320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </tr> 128320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <tr> 129320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>{@link DatatypeConstants#DURATION_DAYTIME}</td> 130320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td></td> 131320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td></td> 132320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>X</td> 133320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>X</td> 134320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>X</td> 135320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>X</td> 136320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </tr> 137320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <tr> 138320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>{@link DatatypeConstants#DURATION_YEARMONTH}</td> 139320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>X</td> 140320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td>X</td> 141320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td></td> 142320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td></td> 143320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td></td> 144320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <td></td> 145320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </tr> 146320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </tbody> 147320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </table> 148f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 149320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return one of the following constants: 150320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * {@link DatatypeConstants#DURATION}, 151320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * {@link DatatypeConstants#DURATION_DAYTIME} or 152320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * {@link DatatypeConstants#DURATION_YEARMONTH}. 153f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 154320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws IllegalStateException If the combination of set fields does not match one of the XML Schema date/time datatypes. 155320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 156320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public QName getXMLSchemaType() { 157320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 158320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson boolean yearSet = isSet(DatatypeConstants.YEARS); 159320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson boolean monthSet = isSet(DatatypeConstants.MONTHS); 160320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson boolean daySet = isSet(DatatypeConstants.DAYS); 161320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson boolean hourSet = isSet(DatatypeConstants.HOURS); 162320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson boolean minuteSet = isSet(DatatypeConstants.MINUTES); 163320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson boolean secondSet = isSet(DatatypeConstants.SECONDS); 164320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 165320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson // DURATION 166320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (yearSet 167320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && monthSet 168320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && daySet 169320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && hourSet 170320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && minuteSet 171320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && secondSet) { 172320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return DatatypeConstants.DURATION; 173320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 174320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 175320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson // DURATION_DAYTIME 176320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (!yearSet 177320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && !monthSet 178320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && daySet 179320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && hourSet 180320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && minuteSet 181320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && secondSet) { 182320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return DatatypeConstants.DURATION_DAYTIME; 183320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 184320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 185320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson // DURATION_YEARMONTH 186320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (yearSet 187320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && monthSet 188320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && !daySet 189320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && !hourSet 190320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && !minuteSet 191320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson && !secondSet) { 192320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return DatatypeConstants.DURATION_YEARMONTH; 193320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 194320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 195320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson // nothing matches 196320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson throw new IllegalStateException( 197320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson "javax.xml.datatype.Duration#getXMLSchemaType():" 198320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson + " this Duration does not match one of the XML Schema date/time datatypes:" 199320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson + " year set = " + yearSet 200320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson + " month set = " + monthSet 201320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson + " day set = " + daySet 202320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson + " hour set = " + hourSet 203320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson + " minute set = " + minuteSet 204320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson + " second set = " + secondSet 205320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson ); 206320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 207320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 208320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 209320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Returns the sign of this duration in -1,0, or 1. 210f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 211320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return 212320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * -1 if this duration is negative, 0 if the duration is zero, 213320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * and 1 if the duration is positive. 214320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 215320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public abstract int getSign(); 216320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 217320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 218320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Get the years value of this <code>Duration</code> as an <code>int</code> or <code>0</code> if not present.</p> 219f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 220320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p><code>getYears()</code> is a convenience method for 221320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * {@link #getField(DatatypeConstants.Field field) getField(DatatypeConstants.YEARS)}.</p> 222f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 223320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>As the return value is an <code>int</code>, an incorrect value will be returned for <code>Duration</code>s 224320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * with years that go beyond the range of an <code>int</code>. 225320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Use {@link #getField(DatatypeConstants.Field field) getField(DatatypeConstants.YEARS)} to avoid possible loss of precision.</p> 226f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 227320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return If the years field is present, return its value as an <code>int</code>, else return <code>0</code>. 228320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 229320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public int getYears() { 230320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return getFieldValueAsInt(DatatypeConstants.YEARS); 231320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 232320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 233320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 234320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Obtains the value of the MONTHS field as an integer value, 235320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * or 0 if not present. 236f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 237320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * This method works just like {@link #getYears()} except 238320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * that this method works on the MONTHS field. 239f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 240320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return Months of this <code>Duration</code>. 241320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 242320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public int getMonths() { 243320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return getFieldValueAsInt(DatatypeConstants.MONTHS); 244320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 245320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 246320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 247320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Obtains the value of the DAYS field as an integer value, 248320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * or 0 if not present. 249f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 250320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * This method works just like {@link #getYears()} except 251320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * that this method works on the DAYS field. 252f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 253320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return Days of this <code>Duration</code>. 254320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 255320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public int getDays() { 256320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return getFieldValueAsInt(DatatypeConstants.DAYS); 257320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 258320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 259320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 260320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Obtains the value of the HOURS field as an integer value, 261320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * or 0 if not present. 262f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 263320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * This method works just like {@link #getYears()} except 264320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * that this method works on the HOURS field. 265f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 266320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return Hours of this <code>Duration</code>. 267f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 268320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 269320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public int getHours() { 270320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return getFieldValueAsInt(DatatypeConstants.HOURS); 271320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 272320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 273320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 274320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Obtains the value of the MINUTES field as an integer value, 275320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * or 0 if not present. 276f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 277320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * This method works just like {@link #getYears()} except 278320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * that this method works on the MINUTES field. 279f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 280320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return Minutes of this <code>Duration</code>. 281f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 282320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 283320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public int getMinutes() { 284320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return getFieldValueAsInt(DatatypeConstants.MINUTES); 285320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 286320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 287320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 288320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Obtains the value of the SECONDS field as an integer value, 289320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * or 0 if not present. 290f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 291320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * This method works just like {@link #getYears()} except 292320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * that this method works on the SECONDS field. 293f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 294320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return seconds in the integer value. The fraction of seconds 295320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * will be discarded (for example, if the actual value is 2.5, 296320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * this method returns 2) 297320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 298320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public int getSeconds() { 299320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return getFieldValueAsInt(DatatypeConstants.SECONDS); 300320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 301320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 302320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 303320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Returns the length of the duration in milliseconds.</p> 304f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 305320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>If the seconds field carries more digits than millisecond order, 306f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * those will be simply discarded (or in other words, rounded to zero.) 307320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * For example, for any Calendar value <code>x</code>,</p> 308320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <pre> 309320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>new Duration("PT10.00099S").getTimeInMills(x) == 10000</code>. 310320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>new Duration("-PT10.00099S").getTimeInMills(x) == -10000</code>. 311320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </pre> 312f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 313320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 314320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Note that this method uses the {@link #addTo(Calendar)} method, 315320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * which may work incorrectly with <code>Duration</code> objects with 316320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * very large values in its fields. See the {@link #addTo(Calendar)} 317320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * method for details. 318f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 319320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param startInstant 320320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * The length of a month/year varies. The <code>startInstant</code> is 321320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * used to disambiguate this variance. Specifically, this method 322320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * returns the difference between <code>startInstant</code> and 323320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>startInstant+duration</code> 324f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 325320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return milliseconds between <code>startInstant</code> and 326320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>startInstant</code> plus this <code>Duration</code> 327320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 328f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @throws NullPointerException if <code>startInstant</code> parameter 329320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * is null. 330f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 331320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 332320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public long getTimeInMillis(final Calendar startInstant) { 333320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson Calendar cal = (Calendar) startInstant.clone(); 334320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson addTo(cal); 335320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return getCalendarTimeInMillis(cal) 336320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson - getCalendarTimeInMillis(startInstant); 337320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 338320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 339320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 340320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Returns the length of the duration in milliseconds.</p> 341f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 342320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>If the seconds field carries more digits than millisecond order, 343320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * those will be simply discarded (or in other words, rounded to zero.) 344f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * For example, for any <code>Date</code> value <code>x</code>,</p> 345320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <pre> 346320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>new Duration("PT10.00099S").getTimeInMills(x) == 10000</code>. 347320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>new Duration("-PT10.00099S").getTimeInMills(x) == -10000</code>. 348320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </pre> 349f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 350320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 351320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Note that this method uses the {@link #addTo(Date)} method, 352320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * which may work incorrectly with <code>Duration</code> objects with 353320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * very large values in its fields. See the {@link #addTo(Date)} 354320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * method for details. 355f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 356320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param startInstant 357320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * The length of a month/year varies. The <code>startInstant</code> is 358320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * used to disambiguate this variance. Specifically, this method 359320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * returns the difference between <code>startInstant</code> and 360320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>startInstant+duration</code>. 361f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 362320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws NullPointerException 363320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * If the startInstant parameter is null. 364f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 365320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return milliseconds between <code>startInstant</code> and 366320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>startInstant</code> plus this <code>Duration</code> 367320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 368320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see #getTimeInMillis(Calendar) 369320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 370320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public long getTimeInMillis(final Date startInstant) { 371320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson Calendar cal = new GregorianCalendar(); 372320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson cal.setTime(startInstant); 373320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson this.addTo(cal); 374320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return getCalendarTimeInMillis(cal) - startInstant.getTime(); 375320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 376320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 377320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 378f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * Gets the value of a field. 379f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 380320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Fields of a duration object may contain arbitrary large value. 381320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Therefore this method is designed to return a {@link Number} object. 382f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 383320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * In case of YEARS, MONTHS, DAYS, HOURS, and MINUTES, the returned 384320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * number will be a non-negative integer. In case of seconds, 385320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * the returned number may be a non-negative decimal value. 386f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 387320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param field 388320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * one of the six Field constants (YEARS,MONTHS,DAYS,HOURS, 389320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * MINUTES, or SECONDS.) 390320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return 391320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * If the specified field is present, this method returns 392320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * a non-null non-negative {@link Number} object that 393320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * represents its value. If it is not present, return null. 394320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * For YEARS, MONTHS, DAYS, HOURS, and MINUTES, this method 395320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * returns a {@link java.math.BigInteger} object. For SECONDS, this 396f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * method returns a {@link java.math.BigDecimal}. 397f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 398320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws NullPointerException If the <code>field</code> is <code>null</code>. 399320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 400320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public abstract Number getField(final DatatypeConstants.Field field); 401f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 402320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 403320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Gets the value of a field as an <code>int</code>. 404f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 405f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @param field 406320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * one of the six Field constants (YEARS,MONTHS,DAYS,HOURS, 407320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * MINUTES, or SECONDS.) 408f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @return 409f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * If the field is present, return its value as an <code>int</code>, 410320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * else return <code>0</code>. 411320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 412320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson private int getFieldValueAsInt(final DatatypeConstants.Field field) { 413320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson Number n = getField(field); 414320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (n != null) { 415320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return n.intValue(); 416320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 417320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return 0; 418320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 419320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 420320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 421320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Checks if a field is set. 422f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 423320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * A field of a duration object may or may not be present. 424320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * This method can be used to test if a field is present. 425f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 426320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param field 427320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * one of the six Field constants (YEARS,MONTHS,DAYS,HOURS, 428320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * MINUTES, or SECONDS.) 429320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return 430320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * true if the field is present. false if not. 431f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 432320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws NullPointerException 433320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * If the field parameter is null. 434320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 435320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public abstract boolean isSet(final DatatypeConstants.Field field); 436320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 437320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 438320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Computes a new duration whose value is <code>this+rhs</code>.</p> 439f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 440320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>For example,</p> 441320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <pre> 442320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "1 day" + "-3 days" = "-2 days" 443320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "1 year" + "1 day" = "1 year and 1 day" 444320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "-(1 hour,50 minutes)" + "-20 minutes" = "-(1 hours,70 minutes)" 445320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "15 hours" + "-3 days" = "-(2 days,9 hours)" 446320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "1 year" + "-1 day" = IllegalStateException 447320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </pre> 448f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 449320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Since there's no way to meaningfully subtract 1 day from 1 month, 450320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * there are cases where the operation fails in 451f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * {@link IllegalStateException}.</p> 452f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 453320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 454320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Formally, the computation is defined as follows.</p> 455320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 456320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Firstly, we can assume that two <code>Duration</code>s to be added 457320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * are both positive without losing generality (i.e., 458320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>(-X)+Y=Y-X</code>, <code>X+(-Y)=X-Y</code>, 459320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>(-X)+(-Y)=-(X+Y)</code>) 460f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 461320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 462f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * Addition of two positive <code>Duration</code>s are simply defined as 463320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * field by field addition where missing fields are treated as 0. 464320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 465320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * A field of the resulting <code>Duration</code> will be unset if and 466f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * only if respective fields of two input <code>Duration</code>s are unset. 467320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 468320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Note that <code>lhs.add(rhs)</code> will be always successful if 469320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>lhs.signum()*rhs.signum()!=-1</code> or both of them are 470320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * normalized.</p> 471f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 472320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param rhs <code>Duration</code> to add to this <code>Duration</code> 473f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 474320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return 475320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * non-null valid Duration object. 476f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 477320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws NullPointerException 478320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * If the rhs parameter is null. 479320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws IllegalStateException 480320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * If two durations cannot be meaningfully added. For 481320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * example, adding negative one day to one month causes 482320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * this exception. 483f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 484f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 485320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see #subtract(Duration) 486320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 487320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public abstract Duration add(final Duration rhs); 488320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 489320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 490320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Adds this duration to a {@link Calendar} object. 491f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 492320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 493320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Calls {@link java.util.Calendar#add(int,int)} in the 494320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * order of YEARS, MONTHS, DAYS, HOURS, MINUTES, SECONDS, and MILLISECONDS 495320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * if those fields are present. Because the {@link Calendar} class 496320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * uses int to hold values, there are cases where this method 497320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * won't work correctly (for example if values of fields 498f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * exceed the range of int.) 499320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </p> 500f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 501320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 502320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Also, since this duration class is a Gregorian duration, this 503320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * method will not work correctly if the given {@link Calendar} 504f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * object is based on some other calendar systems. 505320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </p> 506f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 507320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 508320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Any fractional parts of this <code>Duration</code> object 509320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * beyond milliseconds will be simply ignored. For example, if 510320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * this duration is "P1.23456S", then 1 is added to SECONDS, 511f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 234 is added to MILLISECONDS, and the rest will be unused. 512320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </p> 513f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 514320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 515320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Note that because {@link Calendar#add(int, int)} is using 516320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <tt>int</tt>, <code>Duration</code> with values beyond the 517320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * range of <tt>int</tt> in its fields 518320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * will cause overflow/underflow to the given {@link Calendar}. 519320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * {@link XMLGregorianCalendar#add(Duration)} provides the same 520320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * basic operation as this method while avoiding 521320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * the overflow/underflow issues. 522f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 523320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param calendar 524320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * A calendar object whose value will be modified. 525320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws NullPointerException 526320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * if the calendar parameter is null. 527320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 528320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public abstract void addTo(Calendar calendar); 529320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 530320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 531320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Adds this duration to a {@link Date} object. 532f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 533320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 534320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * The given date is first converted into 535320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * a {@link java.util.GregorianCalendar}, then the duration 536320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * is added exactly like the {@link #addTo(Calendar)} method. 537f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 538320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 539320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * The updated time instant is then converted back into a 540320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * {@link Date} object and used to update the given {@link Date} object. 541f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 542320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 543320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * This somewhat redundant computation is necessary to unambiguously 544320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * determine the duration of months and years. 545f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 546320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param date 547320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * A date object whose value will be modified. 548320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws NullPointerException 549320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * if the date parameter is null. 550320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 551320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public void addTo(Date date) { 552320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 553320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson // check data parameter 554320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (date == null) { 55586acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("date == null"); 556320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 557320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 558320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson Calendar cal = new GregorianCalendar(); 559f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes cal.setTime(date); 560320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson this.addTo(cal); 561320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson date.setTime(getCalendarTimeInMillis(cal)); 562320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 563320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 564320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 565320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Computes a new duration whose value is <code>this-rhs</code>.</p> 566f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 567320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>For example:</p> 568320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <pre> 569320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "1 day" - "-3 days" = "4 days" 570320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "1 year" - "1 day" = IllegalStateException 571320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "-(1 hour,50 minutes)" - "-20 minutes" = "-(1hours,30 minutes)" 572320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "15 hours" - "-3 days" = "3 days and 15 hours" 573320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "1 year" - "-1 day" = "1 year and 1 day" 574320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </pre> 575f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 576320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Since there's no way to meaningfully subtract 1 day from 1 month, 577f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * there are cases where the operation fails in {@link IllegalStateException}.</p> 578f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 579320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Formally the computation is defined as follows. 580320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * First, we can assume that two <code>Duration</code>s are both positive 581320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * without losing generality. (i.e., 582320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>(-X)-Y=-(X+Y)</code>, <code>X-(-Y)=X+Y</code>, 583320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>(-X)-(-Y)=-(X-Y)</code>)</p> 584f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 585320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Then two durations are subtracted field by field. 586320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * If the sign of any non-zero field <tt>F</tt> is different from 587320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * the sign of the most significant field, 588320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 1 (if <tt>F</tt> is negative) or -1 (otherwise) 589320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * will be borrowed from the next bigger unit of <tt>F</tt>.</p> 590f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 591320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>This process is repeated until all the non-zero fields have 592f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * the same sign.</p> 593f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 594320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>If a borrow occurs in the days field (in other words, if 595320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * the computation needs to borrow 1 or -1 month to compensate 596320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * days), then the computation fails by throwing an 597320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * {@link IllegalStateException}.</p> 598f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 599320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param rhs <code>Duration</code> to subtract from this <code>Duration</code>. 600f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 601320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return New <code>Duration</code> created from subtracting <code>rhs</code> from this <code>Duration</code>. 602f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 603320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws IllegalStateException 604320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * If two durations cannot be meaningfully subtracted. For 605320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * example, subtracting one day from one month causes 606320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * this exception. 607f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 608320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws NullPointerException 609320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * If the rhs parameter is null. 610f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 611320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see #add(Duration) 612320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 613320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public Duration subtract(final Duration rhs) { 614320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return add(rhs.negate()); 615320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 616320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 617320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 618320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Computes a new duration whose value is <code>factor</code> times 619320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * longer than the value of this duration.</p> 620f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 621320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>This method is provided for the convenience. 622320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * It is functionally equivalent to the following code:</p> 623320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <pre> 624320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * multiply(new BigDecimal(String.valueOf(factor))) 625320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </pre> 626f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 627320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param factor Factor times longer of new <code>Duration</code> to create. 628f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 629320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return New <code>Duration</code> that is <code>factor</code>times longer than this <code>Duration</code>. 630f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 631320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see #multiply(BigDecimal) 632320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 633320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public Duration multiply(int factor) { 634320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return multiply(BigDecimal.valueOf(factor)); 635320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 636320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 637320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 638320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Computes a new duration whose value is <code>factor</code> times 639320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * longer than the value of this duration. 640f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 641320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 642320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * For example, 643320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <pre> 644320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "P1M" (1 month) * "12" = "P12M" (12 months) 645320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "PT1M" (1 min) * "0.3" = "PT18S" (18 seconds) 646320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "P1M" (1 month) * "1.5" = IllegalStateException 647320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </pre> 648f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 649320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 650320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Since the <code>Duration</code> class is immutable, this method 651320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * doesn't change the value of this object. It simply computes 652320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * a new Duration object and returns it. 653f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 654320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 655320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * The operation will be performed field by field with the precision 656320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * of {@link BigDecimal}. Since all the fields except seconds are 657320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * restricted to hold integers, 658320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * any fraction produced by the computation will be 659320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * carried down toward the next lower unit. For example, 660320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * if you multiply "P1D" (1 day) with "0.5", then it will be 0.5 day, 661320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * which will be carried down to "PT12H" (12 hours). 662320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * When fractions of month cannot be meaningfully carried down 663320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * to days, or year to months, this will cause an 664f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * {@link IllegalStateException} to be thrown. 665320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * For example if you multiple one month by 0.5.</p> 666f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 667320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 668320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * To avoid {@link IllegalStateException}, use 669320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * the {@link #normalizeWith(Calendar)} method to remove the years 670320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * and months fields. 671f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 672320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param factor to multiply by 673f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 674320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return 675320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * returns a non-null valid <code>Duration</code> object 676320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 677f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @throws IllegalStateException if operation produces fraction in 678320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * the months field. 679320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 680f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @throws NullPointerException if the <code>factor</code> parameter is 681320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>null</code>. 682320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 683320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 684320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public abstract Duration multiply(final BigDecimal factor); 685320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 686320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 687320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Returns a new <code>Duration</code> object whose 688320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * value is <code>-this</code>. 689f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 690320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p> 691320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Since the <code>Duration</code> class is immutable, this method 692320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * doesn't change the value of this object. It simply computes 693320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * a new Duration object and returns it. 694f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 695320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return 696320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * always return a non-null valid <code>Duration</code> object. 697320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 698f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes public abstract Duration negate(); 699320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 700320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 701320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Converts the years and months fields into the days field 702320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * by using a specific time instant as the reference point.</p> 703f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 704320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>For example, duration of one month normalizes to 31 days 705320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * given the start time instance "July 8th 2003, 17:40:32".</p> 706f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 707320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Formally, the computation is done as follows:</p> 708320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <ol> 709320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <li>the given Calendar object is cloned</li> 710320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <li>the years, months and days fields will be added to the {@link Calendar} object 711f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * by using the {@link Calendar#add(int,int)} method</li> 712320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <li>the difference between the two Calendars in computed in milliseconds and converted to days, 713320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * if a remainder occurs due to Daylight Savings Time, it is discarded</li> 714320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <li>the computed days, along with the hours, minutes and seconds 715320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * fields of this duration object is used to construct a new 716320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Duration object.</li> 717320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </ol> 718f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 719320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Note that since the Calendar class uses <code>int</code> to 720320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * hold the value of year and month, this method may produce 721320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * an unexpected result if this duration object holds 722320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * a very large value in the years or months fields.</p> 723320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 724320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param startTimeInstant <code>Calendar</code> reference point. 725f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 726320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return <code>Duration</code> of years and months of this <code>Duration</code> as days. 727f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 728320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws NullPointerException If the startTimeInstant parameter is null. 729320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 730320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public abstract Duration normalizeWith(final Calendar startTimeInstant); 731320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 732320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 733320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Partial order relation comparison with this <code>Duration</code> instance.</p> 734f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 735320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Comparison result must be in accordance with 736320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <a href="http://www.w3.org/TR/xmlschema-2/#duration-order">W3C XML Schema 1.0 Part 2, Section 3.2.7.6.2, 737320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <i>Order relation on duration</i></a>.</p> 738f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 739320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Return:</p> 740320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <ul> 741320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <li>{@link DatatypeConstants#LESSER} if this <code>Duration</code> is shorter than <code>duration</code> parameter</li> 742320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <li>{@link DatatypeConstants#EQUAL} if this <code>Duration</code> is equal to <code>duration</code> parameter</li> 743320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <li>{@link DatatypeConstants#GREATER} if this <code>Duration</code> is longer than <code>duration</code> parameter</li> 744320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <li>{@link DatatypeConstants#INDETERMINATE} if a conclusive partial order relation cannot be determined</li> 745320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </ul> 746320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 747320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param duration to compare 748f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 749320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return the relationship between <code>this</code> <code>Duration</code>and <code>duration</code> parameter as 750320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * {@link DatatypeConstants#LESSER}, {@link DatatypeConstants#EQUAL}, {@link DatatypeConstants#GREATER} 751320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * or {@link DatatypeConstants#INDETERMINATE}. 752f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 753320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws UnsupportedOperationException If the underlying implementation 754320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * cannot reasonably process the request, e.g. W3C XML Schema allows for 755320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * arbitrarily large/small/precise values, the request may be beyond the 756320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * implementations capability. 757f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @throws NullPointerException if <code>duration</code> is <code>null</code>. 758320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 759320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see #isShorterThan(Duration) 760320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see #isLongerThan(Duration) 761320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 762320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public abstract int compare(final Duration duration); 763320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 764320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 765320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Checks if this duration object is strictly longer than 766320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * another <code>Duration</code> object.</p> 767f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 768f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * <p>Duration X is "longer" than Y if and only if X>Y 769320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * as defined in the section 3.2.6.2 of the XML Schema 1.0 770320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * specification.</p> 771f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 772320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>For example, "P1D" (one day) > "PT12H" (12 hours) and 773f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * "P2Y" (two years) > "P23M" (23 months).</p> 774f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 775320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param duration <code>Duration</code> to test this <code>Duration</code> against. 776f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 777320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws UnsupportedOperationException If the underlying implementation 778320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * cannot reasonably process the request, e.g. W3C XML Schema allows for 779320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * arbitrarily large/small/precise values, the request may be beyond the 780320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * implementations capability. 781320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws NullPointerException If <code>duration</code> is null. 782f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 783320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return 784320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * true if the duration represented by this object 785320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * is longer than the given duration. false otherwise. 786f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 787320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see #isShorterThan(Duration) 788320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see #compare(Duration duration) 789320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 790320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public boolean isLongerThan(final Duration duration) { 791320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return compare(duration) == DatatypeConstants.GREATER; 792320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 793320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 794320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 795320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Checks if this duration object is strictly shorter than 796320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * another <code>Duration</code> object.</p> 797f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 798320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param duration <code>Duration</code> to test this <code>Duration</code> against. 799f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 800320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return <code>true</code> if <code>duration</code> parameter is shorter than this <code>Duration</code>, 801f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * else <code>false</code>. 802f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 803320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws UnsupportedOperationException If the underlying implementation 804320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * cannot reasonably process the request, e.g. W3C XML Schema allows for 805320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * arbitrarily large/small/precise values, the request may be beyond the 806320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * implementations capability. 807320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws NullPointerException if <code>duration</code> is null. 808320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 809320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see #isLongerThan(Duration duration) 810320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see #compare(Duration duration) 811320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 812320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public boolean isShorterThan(final Duration duration) { 813320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return compare(duration) == DatatypeConstants.LESSER; 814320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 815320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 816320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 817320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Checks if this duration object has the same duration 818320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * as another <code>Duration</code> object.</p> 819f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 820320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>For example, "P1D" (1 day) is equal to "PT24H" (24 hours).</p> 821f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 822320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Duration X is equal to Y if and only if time instant 823320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * t+X and t+Y are the same for all the test time instants 824f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * specified in the section 3.2.6.2 of the XML Schema 1.0 825320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * specification.</p> 826f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 827320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Note that there are cases where two <code>Duration</code>s are 828320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * "incomparable" to each other, like one month and 30 days. 829320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * For example,</p> 830320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <pre> 831320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * !new Duration("P1M").isShorterThan(new Duration("P30D")) 832320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * !new Duration("P1M").isLongerThan(new Duration("P30D")) 833320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * !new Duration("P1M").equals(new Duration("P30D")) 834320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </pre> 835f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 836320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param duration 837320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * A non-null valid <code>Duration</code> object. 838f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 839320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return 840320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>true</code> if this duration is the same length as 841320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>duration</code>. 842320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>false</code> if <code>duration</code> is not a 843320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <code>Duration</code> object, is <code>null</code>, 844320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * or its length is different from this duration. 845f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 846320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @throws UnsupportedOperationException If the underlying implementation 847320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * cannot reasonably process the request, e.g. W3C XML Schema allows for 848320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * arbitrarily large/small/precise values, the request may be beyond the 849320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * implementations capability. 850320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * 851320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @see #compare(Duration duration) 852320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 853320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public boolean equals(final Object duration) { 854320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (duration == this) { 855320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return true; 856320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 857320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (duration instanceof Duration) { 858320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return compare((Duration) duration) == DatatypeConstants.EQUAL; 859320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 860320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return false; 861320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 862320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 863320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 864320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Returns a hash code consistent with the definition of the equals method. 865f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 866f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @see Object#hashCode() 867320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 868320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public abstract int hashCode(); 869320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 870320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 871320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Returns a <code>String</code> representation of this <code>Duration</code> <code>Object</code>.</p> 872f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 873320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>The result is formatted according to the XML Schema 1.0 specification and can be always parsed back later into the 874320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * equivalent <code>Duration</code> <code>Object</code> by {@link DatatypeFactory#newDuration(String lexicalRepresentation)}.</p> 875f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 876320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Formally, the following holds for any <code>Duration</code> 877f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * <code>Object</code> x:</p> 878320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <pre> 879320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * new Duration(x.toString()).equals(x) 880320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * </pre> 881f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 882320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return A non-<code>null</code> valid <code>String</code> representation of this <code>Duration</code>. 883320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 884320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public String toString() { 8857f0c06f737b6f1f6b3a5bb30111f95dd0ca586a2Brian Carlstrom StringBuilder buf = new StringBuilder(); 886320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 887320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (getSign() < 0) { 888320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.append('-'); 889320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 890320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.append('P'); 891320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 892320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson BigInteger years = (BigInteger) getField(DatatypeConstants.YEARS); 893320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (years != null) { 894320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.append(years).append('Y'); 895320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 896320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 897320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson BigInteger months = (BigInteger) getField(DatatypeConstants.MONTHS); 898320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (months != null) { 899320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.append(months).append('M'); 900320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 901320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 902320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson BigInteger days = (BigInteger) getField(DatatypeConstants.DAYS); 903320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (days != null) { 904320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.append(days).append('D'); 905320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 906320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 907320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson BigInteger hours = (BigInteger) getField(DatatypeConstants.HOURS); 908320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson BigInteger minutes = (BigInteger) getField(DatatypeConstants.MINUTES); 909320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson BigDecimal seconds = (BigDecimal) getField(DatatypeConstants.SECONDS); 910320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (hours != null || minutes != null || seconds != null) { 911320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.append('T'); 912320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (hours != null) { 913320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.append(hours).append('H'); 914320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 915320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (minutes != null) { 916320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.append(minutes).append('M'); 917320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 918320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (seconds != null) { 919320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.append(toString(seconds)).append('S'); 920320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 921320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 922320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 923320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return buf.toString(); 924320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 925320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 926320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 927320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Turns {@link BigDecimal} to a string representation.</p> 928f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 929320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Due to a behavior change in the {@link BigDecimal#toString()} 930320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * method in JDK1.5, this had to be implemented here.</p> 931f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 932320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param bd <code>BigDecimal</code> to format as a <code>String</code> 933f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 934f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * @return <code>String</code> representation of <code>BigDecimal</code> 935320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 936320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson private String toString(BigDecimal bd) { 937320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson String intString = bd.unscaledValue().toString(); 938320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson int scale = bd.scale(); 939320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 940320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (scale == 0) { 941320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return intString; 942320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 943320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 944320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /* Insert decimal point */ 9457f0c06f737b6f1f6b3a5bb30111f95dd0ca586a2Brian Carlstrom StringBuilder buf; 946320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson int insertionPoint = intString.length() - scale; 947320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson if (insertionPoint == 0) { /* Point goes right before intVal */ 948320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return "0." + intString; 949f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes } 950320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson else if (insertionPoint > 0) { /* Point goes inside intVal */ 9517f0c06f737b6f1f6b3a5bb30111f95dd0ca586a2Brian Carlstrom buf = new StringBuilder(intString); 952320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.insert(insertionPoint, '.'); 953f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes } 954320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson else { /* We must insert zeros between point and intVal */ 9557f0c06f737b6f1f6b3a5bb30111f95dd0ca586a2Brian Carlstrom buf = new StringBuilder(3 - insertionPoint + intString.length()); 956320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.append("0."); 957320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson for (int i = 0; i < -insertionPoint; i++) { 958320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.append('0'); 959320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 960320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson buf.append(intString); 961320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 962320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return buf.toString(); 963320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 964320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 965320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 966320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson /** 967320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>Calls the {@link Calendar#getTimeInMillis} method. 968320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * Prior to JDK1.4, this method was protected and therefore 969320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * cannot be invoked directly.</p> 970f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 971320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * <p>TODO: In future, this should be replaced by <code>cal.getTimeInMillis()</code>.</p> 972f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 973320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @param cal <code>Calendar</code> to get time in milliseconds. 974f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 975320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson * @return Milliseconds of <code>cal</code>. 976320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson */ 977320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson private static long getCalendarTimeInMillis(final Calendar cal) { 978320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson return cal.getTime().getTime(); 979320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 980320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson} 981