KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > sql > Timestamp


1 /*
2  * @(#)Timestamp.java 1.58 04/05/18
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.sql;
9
10 /**
11  * <P>A thin wrapper around <code>java.util.Date</code> that allows
12  * the JDBC API to identify this as an SQL <code>TIMESTAMP</code> value.
13  * It adds the ability
14  * to hold the SQL <code>TIMESTAMP</code> nanos value and provides formatting and
15  * parsing operations to support the JDBC escape syntax for timestamp values.
16  *
17  * <P><B>Note:</B> This type is a composite of a <code>java.util.Date</code> and a
18  * separate nanoseconds value. Only integral seconds are stored in the
19  * <code>java.util.Date</code> component. The fractional seconds - the nanos - are
20  * separate. The <code>Timestamp.equals(Object)</code> method never returns
21  * <code>true</code> when passed a value of type <code>java.util.Date</code>
22  * because the nanos component of a date is unknown.
23  * As a result, the <code>Timestamp.equals(Object)</code>
24  * method is not symmetric with respect to the
25  * <code>java.util.Date.equals(Object)</code>
26  * method. Also, the <code>hashcode</code> method uses the underlying
27  * <code>java.util.Date</code>
28  * implementation and therefore does not include nanos in its computation.
29  * <P>
30  * Due to the differences between the <code>Timestamp</code> class
31  * and the <code>java.util.Date</code>
32  * class mentioned above, it is recommended that code not view
33  * <code>Timestamp</code> values generically as an instance of
34  * <code>java.util.Date</code>. The
35  * inheritance relationship between <code>Timestamp</code>
36  * and <code>java.util.Date</code> really
37  * denotes implementation inheritance, and not type inheritance.
38  */

39 public class Timestamp extends java.util.Date JavaDoc {
40
41     /**
42      * Constructs a <code>Timestamp</code> object initialized
43      * with the given values.
44      *
45      * @param year the year minus 1900
46      * @param month 0 to 11
47      * @param date 1 to 31
48      * @param hour 0 to 23
49      * @param minute 0 to 59
50      * @param second 0 to 59
51      * @param nano 0 to 999,999,999
52      * @deprecated instead use the constructor <code>Timestamp(long millis)</code>
53      * @exception IllegalArgumentException if the nano argument is out of bounds
54      */

55     @Deprecated JavaDoc
56     public Timestamp(int year, int month, int date,
57              int hour, int minute, int second, int nano) {
58     super(year, month, date, hour, minute, second);
59     if (nano > 999999999 || nano < 0) {
60         throw new IllegalArgumentException JavaDoc("nanos > 999999999 or < 0");
61     }
62     nanos = nano;
63     }
64
65     /**
66      * Constructs a <code>Timestamp</code> object
67      * using a milliseconds time value. The
68      * integral seconds are stored in the underlying date value; the
69      * fractional seconds are stored in the <code>nanos</code> field of
70      * the <code>Timestamp</code> object.
71      *
72      * @param time milliseconds since January 1, 1970, 00:00:00 GMT.
73      * A negative number is the number of milliseconds before
74      * January 1, 1970, 00:00:00 GMT.
75      * @see java.util.Calendar for more information
76      */

77     public Timestamp(long time) {
78     super((time/1000)*1000);
79     nanos = (int)((time%1000) * 1000000);
80     if (nanos < 0) {
81         nanos = 1000000000 + nanos;
82         super.setTime(((time/1000)-1)*1000);
83     }
84     }
85
86     /**
87      * Sets this <code>Timestamp</code> object to represent a point in time that is
88      * <tt>time</tt> milliseconds after January 1, 1970 00:00:00 GMT.
89      *
90      * @param time the number of milliseconds.
91      * @see #getTime
92      * @see #Timestamp(long time)
93      * @see java.util.Calendar for more information
94      */

95     public void setTime(long time) {
96     super.setTime((time/1000)*1000);
97     nanos = (int)((time%1000) * 1000000);
98     if (nanos < 0) {
99         nanos = 1000000000 + nanos;
100         super.setTime(((time/1000)-1)*1000);
101     }
102     }
103
104     /**
105      * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
106      * represented by this <code>Timestamp</code> object.
107      *
108      * @return the number of milliseconds since January 1, 1970, 00:00:00 GMT
109      * represented by this date.
110      * @see #setTime
111      */

112     public long getTime() {
113         long time = super.getTime();
114         return (time + (nanos / 1000000));
115     }
116             
117
118     /**
119      * @serial
120      */

121     private int nanos;
122
123     /**
124      * Converts a <code>String</code> object in JDBC timestamp escape format to a
125      * <code>Timestamp</code> value.
126      *
127      * @param s timestamp in format <code>yyyy-mm-dd hh:mm:ss.fffffffff</code>
128      * @return corresponding <code>Timestamp</code> value
129      * @exception java.lang.IllegalArgumentException if the given argument
130      * does not have the format <code>yyyy-mm-dd hh:mm:ss.fffffffff</code>
131      */

132     public static Timestamp JavaDoc valueOf(String JavaDoc s) {
133     String JavaDoc date_s;
134     String JavaDoc time_s;
135     String JavaDoc nanos_s;
136     int year;
137     int month;
138     int day;
139     int hour;
140     int minute;
141     int second;
142     int a_nanos = 0;
143     int firstDash;
144     int secondDash;
145     int dividingSpace;
146     int firstColon = 0;
147     int secondColon = 0;
148     int period = 0;
149     String JavaDoc formatError = "Timestamp format must be yyyy-mm-dd hh:mm:ss.fffffffff";
150     String JavaDoc zeros = "000000000";
151
152     if (s == null) throw new java.lang.IllegalArgumentException JavaDoc("null string");
153
154     // Split the string into date and time components
155
s = s.trim();
156     dividingSpace = s.indexOf(' ');
157     if (dividingSpace > 0) {
158         date_s = s.substring(0,dividingSpace);
159         time_s = s.substring(dividingSpace+1);
160     } else {
161         throw new java.lang.IllegalArgumentException JavaDoc(formatError);
162     }
163
164
165     // Parse the date
166
firstDash = date_s.indexOf('-');
167     secondDash = date_s.indexOf('-', firstDash+1);
168
169     // Parse the time
170
if (time_s == null)
171         throw new java.lang.IllegalArgumentException JavaDoc(formatError);
172     firstColon = time_s.indexOf(':');
173     secondColon = time_s.indexOf(':', firstColon+1);
174     period = time_s.indexOf('.', secondColon+1);
175
176     // Convert the date
177
if ((firstDash > 0) & (secondDash > 0) &
178         (secondDash < date_s.length()-1)) {
179         year = Integer.parseInt(date_s.substring(0, firstDash)) - 1900;
180         month =
181         Integer.parseInt(date_s.substring
182                  (firstDash+1, secondDash)) - 1;
183         day = Integer.parseInt(date_s.substring(secondDash+1));
184     } else {
185         throw new java.lang.IllegalArgumentException JavaDoc(formatError);
186     }
187
188     // Convert the time; default missing nanos
189
if ((firstColon > 0) & (secondColon > 0) &
190         (secondColon < time_s.length()-1)) {
191         hour = Integer.parseInt(time_s.substring(0, firstColon));
192         minute =
193         Integer.parseInt(time_s.substring(firstColon+1, secondColon));
194         if ((period > 0) & (period < time_s.length()-1)) {
195         second =
196             Integer.parseInt(time_s.substring(secondColon+1, period));
197         nanos_s = time_s.substring(period+1);
198         if (nanos_s.length() > 9)
199             throw new java.lang.IllegalArgumentException JavaDoc(formatError);
200         if (!Character.isDigit(nanos_s.charAt(0)))
201             throw new java.lang.IllegalArgumentException JavaDoc(formatError);
202         nanos_s = nanos_s + zeros.substring(0,9-nanos_s.length());
203         a_nanos = Integer.parseInt(nanos_s);
204         } else if (period > 0) {
205         throw new java.lang.IllegalArgumentException JavaDoc(formatError);
206         } else {
207         second = Integer.parseInt(time_s.substring(secondColon+1));
208         }
209     } else {
210         throw new java.lang.IllegalArgumentException JavaDoc();
211     }
212
213     return new Timestamp JavaDoc(year, month, day, hour, minute, second, a_nanos);
214     }
215
216     /**
217      * Formats a timestamp in JDBC timestamp escape format.
218      * <code>yyyy-mm-dd hh:mm:ss.fffffffff</code>,
219      * where <code>ffffffffff</code> indicates nanoseconds.
220      * <P>
221      * NOTE: To specify a timestamp for the class
222      * <code>java.text.SimpleDateFormat</code>, use "yyyy.MM.dd" rather than
223      * "yyyy-mm-dd". In the context of <code>java.text.SimpleDateFormat</code>,
224      * "mm" indicates minutes rather than the month. Note that
225      * <code>java.text.SimpleDateFormat</code> does not allow for the
226      * nanoseconds component of a <code>Timestamp</code> object.
227      * For Example:
228      * <PRE>
229      *
230      * Format Pattern Result
231      * -------------- ------
232      * "yyyy.MM.dd G 'at' hh:mm:ss z" --> 2002.07.10 AD at 15:08:56 PDT
233      *
234      * </PRE>
235      * @return a <code>String</code> object in
236      * <code>yyyy-mm-dd hh:mm:ss.fffffffff</code> format
237      */

238     public String JavaDoc toString () {
239
240     int year = super.getYear() + 1900;
241     int month = super.getMonth() + 1;
242     int day = super.getDate();
243     int hour = super.getHours();
244     int minute = super.getMinutes();
245     int second = super.getSeconds();
246     String JavaDoc yearString;
247     String JavaDoc monthString;
248     String JavaDoc dayString;
249     String JavaDoc hourString;
250     String JavaDoc minuteString;
251     String JavaDoc secondString;
252     String JavaDoc nanosString;
253     String JavaDoc zeros = "000000000";
254     String JavaDoc yearZeros = "0000";
255     StringBuffer JavaDoc timestampBuf;
256
257     if (year < 1000) {
258         // Add leading zeros
259
yearString = "" + year;
260         yearString = yearZeros.substring(0, (4-yearString.length())) +
261         yearString;
262     } else {
263         yearString = "" + year;
264     }
265     if (month < 10) {
266         monthString = "0" + month;
267     } else {
268         monthString = Integer.toString(month);
269     }
270     if (day < 10) {
271         dayString = "0" + day;
272     } else {
273         dayString = Integer.toString(day);
274     }
275     if (hour < 10) {
276         hourString = "0" + hour;
277     } else {
278         hourString = Integer.toString(hour);
279     }
280     if (minute < 10) {
281         minuteString = "0" + minute;
282     } else {
283         minuteString = Integer.toString(minute);
284     }
285     if (second < 10) {
286         secondString = "0" + second;
287     } else {
288         secondString = Integer.toString(second);
289     }
290     if (nanos == 0) {
291         nanosString = "0";
292     } else {
293         nanosString = Integer.toString(nanos);
294
295         // Add leading zeros
296
nanosString = zeros.substring(0, (9-nanosString.length())) +
297         nanosString;
298
299         // Truncate trailing zeros
300
char[] nanosChar = new char[nanosString.length()];
301         nanosString.getChars(0, nanosString.length(), nanosChar, 0);
302         int truncIndex = 8;
303         while (nanosChar[truncIndex] == '0') {
304         truncIndex--;
305         }
306     
307         nanosString = new String JavaDoc(nanosChar, 0, truncIndex + 1);
308     }
309
310     // do a string buffer here instead.
311
timestampBuf = new StringBuffer JavaDoc();
312     timestampBuf.append(yearString);
313     timestampBuf.append("-");
314     timestampBuf.append(monthString);
315     timestampBuf.append("-");
316     timestampBuf.append(dayString);
317     timestampBuf.append(" ");
318     timestampBuf.append(hourString);
319     timestampBuf.append(":");
320     timestampBuf.append(minuteString);
321     timestampBuf.append(":");
322     timestampBuf.append(secondString);
323     timestampBuf.append(".");
324     timestampBuf.append(nanosString);
325     
326     return (timestampBuf.toString());
327     }
328
329     /**
330      * Gets this <code>Timestamp</code> object's <code>nanos</code> value.
331      *
332      * @return this <code>Timestamp</code> object's fractional seconds component
333      * @see #setNanos
334      */

335     public int getNanos() {
336     return nanos;
337     }
338
339     /**
340      * Sets this <code>Timestamp</code> object's <code>nanos</code> field
341      * to the given value.
342      *
343      * @param n the new fractional seconds component
344      * @exception java.lang.IllegalArgumentException if the given argument
345      * is greater than 999999999 or less than 0
346      * @see #getNanos
347      */

348     public void setNanos(int n) {
349     if (n > 999999999 || n < 0) {
350         throw new IllegalArgumentException JavaDoc("nanos > 999999999 or < 0");
351     }
352     nanos = n;
353     }
354
355     /**
356      * Tests to see if this <code>Timestamp</code> object is
357      * equal to the given <code>Timestamp</code> object.
358      *
359      * @param ts the <code>Timestamp</code> value to compare with
360      * @return <code>true</code> if the given <code>Timestamp</code>
361      * object is equal to this <code>Timestamp</code> object;
362      * <code>false</code> otherwise
363      */

364     public boolean equals(Timestamp JavaDoc ts) {
365     if (super.equals(ts)) {
366         if (nanos == ts.nanos) {
367         return true;
368         } else {
369         return false;
370         }
371     } else {
372         return false;
373     }
374     }
375
376     /**
377      * Tests to see if this <code>Timestamp</code> object is
378      * equal to the given object.
379      *
380      * This version of the method <code>equals</code> has been added
381      * to fix the incorrect
382      * signature of <code>Timestamp.equals(Timestamp)</code> and to preserve backward
383      * compatibility with existing class files.
384      *
385      * Note: This method is not symmetric with respect to the
386      * <code>equals(Object)</code> method in the base class.
387      *
388      * @param ts the <code>Object</code> value to compare with
389      * @return <code>true</code> if the given <code>Object</code>
390      * instance is equal to this <code>Timestamp</code> object;
391      * <code>false</code> otherwise
392      */

393     public boolean equals(java.lang.Object JavaDoc ts) {
394       if (ts instanceof Timestamp JavaDoc) {
395     return this.equals((Timestamp JavaDoc)ts);
396       } else {
397     return false;
398       }
399     }
400
401     /**
402      * Indicates whether this <code>Timestamp</code> object is
403      * earlier than the given <code>Timestamp</code> object.
404      *
405      * @param ts the <code>Timestamp</code> value to compare with
406      * @return <code>true</code> if this <code>Timestamp</code> object is earlier;
407      * <code>false</code> otherwise
408      */

409     public boolean before(Timestamp JavaDoc ts) {
410     return compareTo(ts) < 0;
411     }
412
413     /**
414      * Indicates whether this <code>Timestamp</code> object is
415      * later than the given <code>Timestamp</code> object.
416      *
417      * @param ts the <code>Timestamp</code> value to compare with
418      * @return <code>true</code> if this <code>Timestamp</code> object is later;
419      * <code>false</code> otherwise
420      */

421     public boolean after(Timestamp JavaDoc ts) {
422     return compareTo(ts) > 0;
423     }
424
425     /**
426      * Compares this <code>Timestamp</code> object to the given
427      * <code>Timestamp</code> object.
428      *
429      * @param ts the <code>Timestamp</code> object to be compared to
430      * this <code>Timestamp</code> object
431      * @return the value <code>0</code> if the two <code>Timestamp</code>
432      * objects are equal; a value less than <code>0</code> if this
433      * <code>Timestamp</code> object is before the given argument;
434      * and a value greater than <code>0</code> if this
435      * <code>Timestamp</code> object is after the given argument.
436      * @since 1.2
437      */

438     public int compareTo(Timestamp JavaDoc ts) {
439         int i = super.compareTo(ts);
440         if (i == 0) {
441             if (nanos > ts.nanos) {
442             return 1;
443             } else if (nanos < ts.nanos) {
444                 return -1;
445             }
446         }
447         return i;
448
449     }
450
451     /**
452      * Compares this <code>Timestamp</code> object to the given
453      * <code>Date</code>, which must be a <code>Timestamp</code>
454      * object. If the argument is not a <code>Timestamp</code> object,
455      * this method throws a <code>ClassCastException</code> object.
456      * (<code>Timestamp</code> objects are
457      * comparable only to other <code>Timestamp</code> objects.)
458      *
459      * @param o the <code>Date</code> to be compared, which must be a
460      * <code>Timestamp</code> object
461      * @return the value <code>0</code> if this <code>Timestamp</code> object
462      * and the given object are equal; a value less than <code>0</code>
463      * if this <code>Timestamp</code> object is before the given argument;
464      * and a value greater than <code>0</code> if this
465      * <code>Timestamp</code> object is after the given argument.
466      *
467      * @since 1.5
468      */

469     public int compareTo(java.util.Date JavaDoc o) {
470        if(o instanceof Timestamp JavaDoc) {
471             // When Timestamp instance compare it with a Timestamp
472
// Hence it is basically calling this.compareTo((Timestamp))o);
473
// Note typecasting is safe because o is instance of Timestamp
474
return compareTo((Timestamp JavaDoc)o);
475       } else {
476             // When Date doing a o.compareTo(this)
477
// will give wrong results.
478
Timestamp JavaDoc ts = new Timestamp JavaDoc(o.getTime());
479           return this.compareTo(ts);
480       }
481     }
482
483     static final long serialVersionUID = 2745179027874758501L;
484
485 }
486
487
Popular Tags