KickJava   Java API By Example, From Geeks To Geeks.

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


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

10 package com.hp.hpl.jena.datatypes.xsd;
11
12 /**
13  * Base class for representation of XSD duration, time, date/time
14  * and related datatype instances. We are using the Xerces internal
15  * packages for the all heavy lifting which represent date/times
16  * using an int array. These wrapper classes just provide more
17  * convenient access to the date values.
18  * <p>
19  * This class includees code derived from Xerces 2.6.0 Copyright (c) 1999-2002 The Apache Software Foundation. All rights
20  * reserved.
21  * </p>
22  *
23  * @author <a HREF="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
24  * @version $Revision: 1.9 $ on $Date: 2005/02/21 12:02:03 $
25  */

26 public class AbstractDateTime {
27
28     /** The array of year/month etc values as ints */
29     protected int[] data;
30     
31     /** The fractional seconds */
32     protected double fractionalSeconds;
33     
34     //define constants
35
protected final static int CY = 0, M = 1, D = 2, h = 3,
36     m = 4, s = 5, ms = 6, utc=7, hh=0, mm=1;
37         
38     //size for all objects must have the same fields:
39
//CCYY, MM, DD, h, m, s, ms + timeZone
40
protected final static int TOTAL_SIZE = 8;
41
42     /** constant to indicate a less than relationship from compare() */
43     public static final short LESS_THAN = -1;
44     /** constant to indicate an equals relationship from compare() */
45     public static final short EQUAL = 0;
46     /** constant to indicate a greater than relationship from compare() */
47     public static final short GREATER_THAN = 1;
48     /** constant to indicate an indeterminate relationship from compare() */
49     public static final short INDETERMINATE = 2;
50
51     /**
52      * Constructor
53      * @param value the date/time value returned by the parsing
54      */

55     public AbstractDateTime(Object JavaDoc value) {
56         data = (int[]) value;
57         if (data[utc] == 0) data[utc]='Z';
58         extractFractionalSeconds();
59     }
60     
61     /**
62      * Comparison function. Not quite the same as normal java compare
63      * because XSD date/times are not always comparable.
64      *
65      * @param other the time/date to compare to
66      * @return an order flag - one of LESS_THAN, EQUAL, GREATER_THEN, INDETERMINATE
67      */

68     public int compare(AbstractDateTime other) {
69         return compareDates(data, other.data, true);
70     }
71     
72     /**
73      * Convert the strange fractional second part from Xerces into a true fraction.
74      */

75     protected void extractFractionalSeconds() {
76         if (data[ms] != 0) {
77             int fs = data[ms];
78             double log10 = Math.log((double)fs)/2.302585093;
79             int exp = 1 + (int)(log10 / 10);
80             fractionalSeconds = ((double)fs) / Math.pow(10.0, (double)exp);
81         }
82     }
83     
84     /**
85      * Equality function
86      */

87     public boolean equals(Object JavaDoc obj) {
88         if (obj instanceof AbstractDateTime) {
89             AbstractDateTime adt = (AbstractDateTime) obj;
90             for (int i = 0; i < data.length; i++) {
91                 if (data[i] != adt.data[i]) return false;
92             }
93             return true;
94         }
95         return false;
96     }
97     
98     /**
99      * hash function
100      */

101     public int hashCode() {
102         int hash = 0;
103         for (int i = 0; i < data.length; i++) {
104             hash = (hash << 1) ^ data[i];
105         }
106         return hash;
107     }
108     
109 // --------------------------------------------------------------------
110
// This code is adapated from Xerces 2.6.0 AbstractDateTimeDV.
111
// Copyright (c) 1999-2003 The Apache Software Foundation. All rights
112
// reserved.
113
// --------------------------------------------------------------------
114

115     /**
116      * Compare algorithm described in dateDime (3.2.7).
117      *
118      * @param date1 normalized date representation of the first value
119      * @param date2 normalized date representation of the second value
120      * @param strict
121      * @return less, greater, less_equal, greater_equal, equal
122      */

123     protected short compareDates(int[] date1, int[] date2, boolean strict) {
124         if ( date1[utc]==date2[utc] ) {
125             return compareOrder(date1, date2);
126         }
127         short c1, c2;
128         
129         int[] tempDate = new int[TOTAL_SIZE];
130         int[] timeZone = new int[2];
131
132         if ( date1[utc]=='Z' ) {
133
134             //compare date1<=date1<=(date2 with time zone -14)
135
//
136
cloneDate(date2, tempDate); //clones date1 value to global temporary storage: fTempDate
137
timeZone[hh]=14;
138             timeZone[mm]=0;
139             tempDate[utc]='+';
140             normalize(tempDate, timeZone);
141             c1 = compareOrder(date1, tempDate);
142             if (c1 == LESS_THAN)
143                 return c1;
144
145             //compare date1>=(date2 with time zone +14)
146
//
147
cloneDate(date2, tempDate); //clones date1 value to global temporary storage: tempDate
148
timeZone[hh]=14;
149             timeZone[mm]=0;
150             tempDate[utc]='-';
151             normalize(tempDate, timeZone);
152             c2 = compareOrder(date1, tempDate);
153             if (c2 == GREATER_THAN)
154                 return c2;
155
156             return INDETERMINATE;
157         }
158         else if ( date2[utc]=='Z' ) {
159
160             //compare (date1 with time zone -14)<=date2
161
//
162
cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate
163
timeZone[hh]=14;
164             timeZone[mm]=0;
165             tempDate[utc]='-';
166             normalize(tempDate, timeZone);
167             c1 = compareOrder(tempDate, date2);
168             if (c1 == LESS_THAN)
169                 return c1;
170
171             //compare (date1 with time zone +14)<=date2
172
//
173
cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate
174
timeZone[hh]=14;
175             timeZone[mm]=0;
176             tempDate[utc]='+';
177             normalize(tempDate, timeZone);
178             c2 = compareOrder(tempDate, date2);
179             if (c2 == GREATER_THAN)
180                 return c2;
181
182             return INDETERMINATE;
183         }
184         return INDETERMINATE;
185
186     }
187
188     /**
189      * Given normalized values, determines order-relation
190      * between give date/time objects.
191      *
192      * @param date1 date/time object
193      * @param date2 date/time object
194      * @return 0 if date1 and date2 are equal, a value less than 0 if date1 is less than date2, a value greater than 0 if date1 is greater than date2
195      */

196     protected short compareOrder (int[] date1, int[] date2) {
197
198         for ( int i=0;i<TOTAL_SIZE;i++ ) {
199             if ( date1[i]<date2[i] ) {
200                 return -1;
201             }
202             else if ( date1[i]>date2[i] ) {
203                 return 1;
204             }
205         }
206         return 0;
207     }
208     /**
209       * If timezone present - normalize dateTime [E Adding durations to dateTimes]
210       * Public to allow reuse with type objects.
211       *
212       * @param date CCYY-MM-DDThh:mm:ss+03
213       */

214      public static void normalize (int[] date, int[] timeZone) {
215
216          // REVISIT: we have common code in addDuration() for durations
217
// should consider reorganizing it.
218
//
219

220          //add minutes (from time zone)
221
int negate = 1;
222          if (date[utc]=='+') {
223              negate = -1;
224          }
225          int temp = date[m] + negate*timeZone[mm];
226          int carry = fQuotient (temp, 60);
227          date[m]= mod(temp, 60, carry);
228
229          //add hours
230
temp = date[h] + negate*timeZone[hh] + carry;
231          carry = fQuotient(temp, 24);
232          date[h]=mod(temp, 24, carry);
233
234          date[D]=date[D]+carry;
235
236          while ( true ) {
237              temp=maxDayInMonthFor(date[CY], date[M]);
238              if (date[D]<1) {
239                  date[D] = date[D] + maxDayInMonthFor(date[CY], date[M]-1);
240                  carry=-1;
241              }
242              else if ( date[D]>temp ) {
243                  date[D]=date[D]-temp;
244                  carry=1;
245              }
246              else {
247                  break;
248              }
249              temp=date[M]+carry;
250              date[M]=modulo(temp, 1, 13);
251              date[CY]=date[CY]+fQuotient(temp, 1, 13);
252          }
253          date[utc]='Z';
254      }
255
256
257     /**
258      * Resets object representation of date/time
259      *
260      * @param data date/time object
261      */

262     protected void resetDateObj (int[] data) {
263         for ( int i=0;i<TOTAL_SIZE;i++ ) {
264             data[i]=0;
265         }
266     }
267
268     /**
269      * Given {year,month} computes maximum
270      * number of days for given month
271      *
272      * @param year
273      * @param month
274      * @return integer containg the number of days in a given month
275      */

276     protected static int maxDayInMonthFor(int year, int month) {
277         //validate days
278
if ( month==4 || month==6 || month==9 || month==11 ) {
279             return 30;
280         }
281         else if ( month==2 ) {
282             if ( isLeapYear(year) ) {
283                 return 29;
284             }
285             else {
286                 return 28;
287             }
288         }
289         else {
290             return 31;
291         }
292     }
293
294     private static boolean isLeapYear(int year) {
295
296         //REVISIT: should we take care about Julian calendar?
297
return((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)));
298     }
299
300     //
301
// help function described in W3C PR Schema [E Adding durations to dateTimes]
302
//
303
protected static int mod (int a, int b, int quotient) {
304         //modulo(a, b) = a - fQuotient(a,b)*b
305
return (a - quotient*b) ;
306     }
307
308     //
309
// help function described in W3C PR Schema [E Adding durations to dateTimes]
310
//
311
protected static int fQuotient (int a, int b) {
312
313         //fQuotient(a, b) = the greatest integer less than or equal to a/b
314
return (int)Math.floor((float)a/b);
315     }
316
317     //
318
// help function described in W3C PR Schema [E Adding durations to dateTimes]
319
//
320
protected static int modulo (int temp, int low, int high) {
321         //modulo(a - low, high - low) + low
322
int a = temp - low;
323         int b = high - low;
324         return (mod (a, b, fQuotient(a, b)) + low) ;
325     }
326
327     //
328
// help function described in W3C PR Schema [E Adding durations to dateTimes]
329
//
330
protected static int fQuotient (int temp, int low, int high) {
331         //fQuotient(a - low, high - low)
332

333         return fQuotient(temp - low, high - low);
334     }
335     
336     //
337
//Private help functions
338
//
339

340     private void cloneDate (int[] finalValue, int[] tempDate) {
341         System.arraycopy(finalValue, 0, tempDate, 0, TOTAL_SIZE);
342     }
343    
344 // --------------------------------------------------------------------
345
// End of code is adapated from Xerces 2.6.0 AbstractDateTimeDV.
346
// --------------------------------------------------------------------
347

348 }
349
350 /*
351     (c) Copyright 2002, 2003, 2004, 2005 Hewlett-Packard Development Company, LP
352     All rights reserved.
353
354     Redistribution and use in source and binary forms, with or without
355     modification, are permitted provided that the following conditions
356     are met:
357
358     1. Redistributions of source code must retain the above copyright
359        notice, this list of conditions and the following disclaimer.
360
361     2. Redistributions in binary form must reproduce the above copyright
362        notice, this list of conditions and the following disclaimer in the
363        documentation and/or other materials provided with the distribution.
364
365     3. The name of the author may not be used to endorse or promote products
366        derived from this software without specific prior written permission.
367
368     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
369     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
370     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
371     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
372     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
373     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
374     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
375     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
376     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
377     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
378 */

379
Popular Tags