KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > datatypes > xsd > XSDDuration


1 /******************************************************************
2  * File: Duration.java
3  * Created by: Dave Reynolds
4  * Created on: 16-Dec-02
5  *
6  * (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
7  * [See end of file]
8  * $Id: XSDDuration.java,v 1.7 2005/02/21 12:02:16 andy_seaborne Exp $
9  *****************************************************************/

10 package com.hp.hpl.jena.datatypes.xsd;
11
12 /**
13  * Represent an XSD duration value. We use a seven dimensional space
14  * with years, months, days, hours, minutes, seconds and fractional seconds.
15  * This deviates from the spec which allows arbitrary position
16  * decimals for seconds.
17  *
18  * @author <a HREF="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
19  * @version $Revision: 1.7 $ on $Date: 2005/02/21 12:02:16 $
20  */

21 public class XSDDuration extends AbstractDateTime {
22
23     /**
24      * Constructor - should only be used by the internals but public scope because
25      * the internals spread across multiple packages.
26      *
27      * @param value the date/time value returned by the parsing
28      */

29     public XSDDuration(Object JavaDoc value) {
30         super(value);
31     }
32     
33     /**
34      * Return the number of years in the duration
35      */

36     public int getYears() {
37         return data[CY];
38     }
39     
40     /**
41      * Return the number of months in the duration
42      */

43     public int getMonths() {
44         return data[M];
45     }
46     
47     /**
48      * Return the number of years in the duration
49      */

50     public int getDays() {
51         return data[D];
52     }
53     
54     /**
55      * Return the number of hours in the duration
56      */

57     public int getHours() {
58         return data[h];
59     }
60     
61     /**
62      * Return the number of minutes in the duration
63      */

64     public int getMinutes() {
65         return data[m];
66     }
67     
68     /**
69      * Return the number of full seconds in the duration
70      */

71     public int getFullSeconds() {
72         return data[s];
73     }
74     
75     /**
76      * Return the number of seconds in the duration, including fractional part
77      */

78     public double getSeconds() {
79         return data[s] + fractionalSeconds;
80     }
81     
82     /**
83      * Return the time component of the duration - i.e. just the hours/mins/seconds,
84      * and returns the values in seconds.
85      */

86     public double getTimePart() {
87         return ((data[h]) * 60l + data[m]) * 60l + getSeconds();
88     }
89     
90     /**
91      * Serializer
92      */

93     public String JavaDoc toString() {
94          StringBuffer JavaDoc message = new StringBuffer JavaDoc(30);
95          int negate = 1;
96          if ( data[CY]<0 ) {
97              message.append('-');
98              negate=-1;
99          }
100          message.append('P');
101          message.append(negate * data[CY]);
102          message.append('Y');
103          message.append(negate * data[M]);
104          message.append('M');
105          message.append(negate * data[D]);
106          message.append('D');
107          message.append('T');
108          message.append(negate * data[h]);
109          message.append('H');
110          message.append(negate * data[m]);
111          message.append('M');
112          message.append(negate * data[s]);
113          message.append('.');
114          message.append(negate * data[ms]);
115          message.append('S');
116
117          return message.toString();
118      }
119
120     // order-relation on duration is a partial order. The dates below are used to
121
// for comparison of 2 durations, based on the fact that
122
// duration x and y is x<=y iff s+x<=s+y
123
// see 3.2.6 duration W3C schema datatype specs
124
//
125
// the dates are in format: {CCYY,MM,DD, H, S, M, MS, timezone}
126
private final static int[][] DATETIMES= {
127         {1696, 9, 1, 0, 0, 0, 0, 'Z'},
128         {1697, 2, 1, 0, 0, 0, 0, 'Z'},
129         {1903, 3, 1, 0, 0, 0, 0, 'Z'},
130         {1903, 7, 1, 0, 0, 0, 0, 'Z'}};
131
132     private int[][] fDuration = null;
133
134     /**
135      * Compares 2 given durations. (refer to W3C Schema Datatypes "3.2.6 duration")
136      *
137      * @param date1 Unnormalized duration
138      * @param date2 Unnormalized duration
139      * @param strict (min/max)Exclusive strict == true ( LESS_THAN ) or ( GREATER_THAN )
140      * (min/max)Inclusive strict == false (LESS_EQUAL) or (GREATER_EQUAL)
141      * @return INDETERMINATE if the order relationship between date1 and date2 is indeterminate.
142      * EQUAL if the order relation between date1 and date2 is EQUAL.
143      * If the strict parameter is true, return LESS_THAN if date1 is less than date2 and
144      * return GREATER_THAN if date1 is greater than date2.
145      * If the strict parameter is false, return LESS_THAN if date1 is less than OR equal to date2 and
146      * return GREATER_THAN if date1 is greater than OR equal to date2
147      */

148     protected short compareDates(int[] date1, int[] date2, boolean strict) {
149
150         //REVISIT: this is unoptimazed vs of comparing 2 durations
151
// Algorithm is described in 3.2.6.2 W3C Schema Datatype specs
152
//
153

154         //add constA to both durations
155
short resultA, resultB= INDETERMINATE;
156
157         //try and see if the objects are equal
158
resultA = compareOrder (date1, date2);
159         if ( resultA == 0 ) {
160             return 0;
161         }
162         if ( fDuration == null ) {
163             fDuration = new int[2][TOTAL_SIZE];
164         }
165         //long comparison algorithm is required
166
int[] tempA = addDuration (date1, 0, fDuration[0]);
167         int[] tempB = addDuration (date2, 0, fDuration[1]);
168         resultA = compareOrder(tempA, tempB);
169         if ( resultA == INDETERMINATE ) {
170             return INDETERMINATE;
171         }
172
173         tempA = addDuration(date1, 1, fDuration[0]);
174         tempB = addDuration(date2, 1, fDuration[1]);
175         resultB = compareOrder(tempA, tempB);
176         resultA = compareResults(resultA, resultB, strict);
177         if (resultA == INDETERMINATE) {
178             return INDETERMINATE;
179         }
180
181         tempA = addDuration(date1, 2, fDuration[0]);
182         tempB = addDuration(date2, 2, fDuration[1]);
183         resultB = compareOrder(tempA, tempB);
184         resultA = compareResults(resultA, resultB, strict);
185         if (resultA == INDETERMINATE) {
186             return INDETERMINATE;
187         }
188
189         tempA = addDuration(date1, 3, fDuration[0]);
190         tempB = addDuration(date2, 3, fDuration[1]);
191         resultB = compareOrder(tempA, tempB);
192         resultA = compareResults(resultA, resultB, strict);
193
194         return resultA;
195     }
196
197     private short compareResults(short resultA, short resultB, boolean strict){
198
199       if ( resultB == INDETERMINATE ) {
200             return INDETERMINATE;
201         }
202         else if ( resultA!=resultB && strict ) {
203             return INDETERMINATE;
204         }
205         else if ( resultA!=resultB && !strict ) {
206             if ( resultA!=0 && resultB!=0 ) {
207                 return INDETERMINATE;
208             }
209             else {
210                 return (resultA!=0)?resultA:resultB;
211             }
212         }
213         return resultA;
214     }
215
216     private int[] addDuration(int[] date, int index, int[] duration) {
217
218         //REVISIT: some code could be shared between normalize() and this method,
219
// however is it worth moving it? The structures are different...
220
//
221

222         resetDateObj(duration);
223         //add months (may be modified additionaly below)
224
int temp = DATETIMES[index][M] + date[M];
225         duration[M] = modulo (temp, 1, 13);
226         int carry = fQuotient (temp, 1, 13);
227
228         //add years (may be modified additionaly below)
229
duration[CY]=DATETIMES[index][CY] + date[CY] + carry;
230
231         //add seconds
232
temp = DATETIMES[index][s] + date[s];
233         carry = fQuotient (temp, 60);
234         duration[s] = mod(temp, 60, carry);
235
236         //add minutes
237
temp = DATETIMES[index][m] +date[m] + carry;
238         carry = fQuotient (temp, 60);
239         duration[m]= mod(temp, 60, carry);
240
241         //add hours
242
temp = DATETIMES[index][h] + date[h] + carry;
243         carry = fQuotient(temp, 24);
244         duration[h] = mod(temp, 24, carry);
245
246
247         duration[D]=DATETIMES[index][D] + date[D] + carry;
248
249         while ( true ) {
250
251             temp=maxDayInMonthFor(duration[CY], duration[M]);
252             if ( duration[D] < 1 ) { //original duration was negative
253
duration[D] = duration[D] + maxDayInMonthFor(duration[CY], duration[M]-1);
254                 carry=-1;
255             }
256             else if ( duration[D] > temp ) {
257                 duration[D] = duration[D] - temp;
258                 carry=1;
259             }
260             else {
261                 break;
262             }
263             temp = duration[M]+carry;
264             duration[M] = modulo(temp, 1, 13);
265             duration[CY] = duration[CY]+fQuotient(temp, 1, 13);
266         }
267
268         duration[utc]='Z';
269         return duration;
270     }
271     
272 }
273
274 /*
275     (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
276     All rights reserved.
277
278     Redistribution and use in source and binary forms, with or without
279     modification, are permitted provided that the following conditions
280     are met:
281
282     1. Redistributions of source code must retain the above copyright
283        notice, this list of conditions and the following disclaimer.
284
285     2. Redistributions in binary form must reproduce the above copyright
286        notice, this list of conditions and the following disclaimer in the
287        documentation and/or other materials provided with the distribution.
288
289     3. The name of the author may not be used to endorse or promote products
290        derived from this software without specific prior written permission.
291
292     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
293     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
294     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
295     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
296     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
297     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
298     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
299     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
300     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
301     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
302 */

303
Popular Tags