1 /* Time.java -- Wrapper around java.util.Date 2 Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package java.sql; 40 41 import java.text.DecimalFormat; 42 import java.text.ParseException; 43 import java.text.SimpleDateFormat; 44 45 /** 46 * This class is a wrapper around java.util.Date to allow the JDBC 47 * driver to identify the value as a SQL Timestamp. Note that this 48 * class also adds an additional field for nano-seconds, and so 49 * is not completely identical to <code>java.util.Date</code> as 50 * the <code>java.sql.Date</code> and <code>java.sql.Time</code> 51 * classes are. 52 * 53 * @author Aaron M. Renn (arenn@urbanophile.com) 54 */ 55 public class Timestamp extends java.util.Date 56 { 57 static final long serialVersionUID = 2745179027874758501L; 58 59 /** 60 * Used for parsing and formatting this date. 61 */ 62 private static SimpleDateFormat dateFormat = 63 new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 64 private static DecimalFormat decimalFormat = new DecimalFormat("000000000"); 65 private static StringBuffer sbuf = new StringBuffer(29); 66 67 /** 68 * The nanosecond value for this object 69 */ 70 private int nanos; 71 72 /** 73 * This method returns a new instance of this class by parsing a 74 * date in JDBC format into a Java date. 75 * 76 * @param str The string to parse. 77 * @return The resulting <code>java.sql.Timestamp</code> value. 78 */ valueOf(String str)79 public static Timestamp valueOf(String str) 80 { 81 int nanos = 0; 82 int dot = str.indexOf('.'); 83 if (dot != -1) 84 { 85 if (str.lastIndexOf('.') != dot) 86 throw new IllegalArgumentException(str); 87 88 int len = str.length() - dot - 1; 89 if (len < 1 || len > 9) 90 throw new IllegalArgumentException(str); 91 92 nanos = Integer.parseInt(str.substring(dot + 1)); 93 for (int i = len; i < 9; i++) 94 nanos *= 10; 95 96 str = str.substring(0, dot); 97 98 } 99 100 try 101 { 102 java.util.Date d; 103 synchronized (dateFormat) 104 { 105 d = (java.util.Date) dateFormat.parseObject(str); 106 } 107 108 if (d == null) 109 throw new IllegalArgumentException(str); 110 111 Timestamp ts = new Timestamp(d.getTime() + nanos / 1000000); 112 ts.nanos = nanos; 113 return ts; 114 } 115 catch (ParseException e) 116 { 117 throw new IllegalArgumentException(str); 118 } 119 } 120 121 /** 122 * This method initializes a new instance of this class with the 123 * specified year, month, and day. 124 * 125 * @param year The year for this Timestamp (year - 1900) 126 * @param month The month for this Timestamp (0-11) 127 * @param day The day for this Timestamp (1-31) 128 * @param hour The hour for this Timestamp (0-23) 129 * @param minute The minute for this Timestamp (0-59) 130 * @param second The second for this Timestamp (0-59) 131 * @param nanos The nanosecond value for this Timestamp (0 to 999,999,9999) 132 * @deprecated 133 */ Timestamp(int year, int month, int day, int hour, int minute, int second, int nanos)134 public Timestamp(int year, int month, int day, int hour, int minute, 135 int second, int nanos) 136 { 137 super(year, month, day, hour, minute, second); 138 this.nanos = nanos; 139 } 140 141 /** 142 * This method initializes a new instance of this class with the 143 * specified time value representing the number of milliseconds since 144 * Jan 1, 1970 at 12:00 midnight GMT. 145 * 146 * @param date The time value to intialize this <code>Time</code> to. 147 */ Timestamp(long date)148 public Timestamp(long date) 149 { 150 super(date - (date % 1000)); 151 nanos = (int) (date % 1000) * 1000000; 152 } 153 154 /** 155 * Return the value of this Timestamp as the number of milliseconds 156 * since Jan 1, 1970 at 12:00 midnight GMT. 157 */ getTime()158 public long getTime() 159 { 160 return super.getTime() + (nanos / 1000000); 161 } 162 163 /** 164 * This method returns this date in JDBC format. 165 * 166 * @return This date as a string. 167 */ toString()168 public String toString() 169 { 170 synchronized (dateFormat) 171 { 172 sbuf.setLength(0); 173 dateFormat.format(this, sbuf, null); 174 sbuf.append('.'); 175 decimalFormat.format(nanos, sbuf, null); 176 int end = sbuf.length() - 1; 177 while (end > 20 && sbuf.charAt(end) == '0') 178 end--; 179 return sbuf.substring(0, end + 1); 180 } 181 } 182 183 /** 184 * This method returns the nanosecond value for this object. 185 * @return The nanosecond value for this object. 186 */ getNanos()187 public int getNanos() 188 { 189 return nanos; 190 } 191 192 /** 193 * This method sets the nanosecond value for this object. 194 * 195 * @param nanos The nanosecond value for this object. 196 */ setNanos(int nanos)197 public void setNanos(int nanos) 198 { 199 this.nanos = nanos; 200 } 201 202 /** 203 * This methods tests whether this object is earlier than the specified 204 * object. 205 * 206 * @param ts The other <code>Timestamp</code> to test against. 207 * @return <code>true</code> if this object is earlier than the other object, 208 * <code>false</code> otherwise. 209 */ before(Timestamp ts)210 public boolean before(Timestamp ts) 211 { 212 long time1 = getTime(); 213 long time2 = ts.getTime(); 214 if (time1 < time2 || (time1 == time2 && getNanos() < ts.getNanos())) 215 return true; 216 return false; 217 } 218 219 /** 220 * This methods tests whether this object is later than the specified 221 * object. 222 * 223 * @param ts The other <code>Timestamp</code> to test against. 224 * 225 * @return <code>true</code> if this object is later than the other object, 226 * <code>false</code> otherwise. 227 */ after(Timestamp ts)228 public boolean after(Timestamp ts) 229 { 230 long time1 = getTime(); 231 long time2 = ts.getTime(); 232 if (time1 > time2 || (time1 == time2 && getNanos() > ts.getNanos())) 233 return true; 234 return false; 235 } 236 237 /** 238 * This method these the specified <code>Object</code> for equality 239 * against this object. This will be true if an only if the specified 240 * object is an instance of <code>Timestamp</code> and has the same 241 * time value fields. 242 * 243 * @param obj The object to test against for equality. 244 * 245 * @return <code>true</code> if the specified object is equal to this 246 * object, <code>false</code> otherwise. 247 */ equals(Object obj)248 public boolean equals(Object obj) 249 { 250 if (!(obj instanceof Timestamp)) 251 return false; 252 253 return equals((Timestamp) obj); 254 } 255 256 /** 257 * This method tests the specified timestamp for equality against this 258 * object. This will be true if and only if the specified object is 259 * not <code>null</code> and contains all the same time value fields 260 * as this object. 261 * 262 * @param ts The <code>Timestamp</code> to test against for equality. 263 * 264 * @return <code>true</code> if the specified object is equal to this 265 * object, <code>false</code> otherwise. 266 */ equals(Timestamp ts)267 public boolean equals(Timestamp ts) 268 { 269 if (ts == null) 270 return false; 271 272 if (ts.getTime() != getTime()) 273 return false; 274 275 if (ts.getNanos() != getNanos()) 276 return false; 277 278 return true; 279 } 280 281 /** 282 * Compares this <code>Timestamp</code> to another one. 283 * 284 * @param ts The other Timestamp. 285 * @return <code>0</code>, if both <code>Timestamp</code>'s represent exactly 286 * the same date, a negative value if this <code>Timestamp</code> is 287 * before the specified <code>Timestamp</code> and a positive value 288 * otherwise. 289 * @since 1.2 290 */ compareTo(Timestamp ts)291 public int compareTo(Timestamp ts) 292 { 293 int s = super.compareTo((java.util.Date) ts); 294 if (s != 0) 295 return s; 296 // If Date components were equal, then we check the nanoseconds. 297 return nanos - ts.nanos; 298 } 299 300 /** 301 * Compares this <code>Timestamp</code> to another one. This behaves like 302 * <code>compareTo(Timestamp)</code>, but it may throw a 303 * <code>ClassCastException</code>, if the specified object is not of type 304 * <code>Timestamp</code>. 305 * 306 * @param obj The object to compare with. 307 * @return <code>0</code>, if both <code>Timestamp</code>'s represent exactly 308 * the same date, a negative value if this <code>Timestamp</code> is 309 * before the specified <code>Timestamp</code> and a positive value 310 * otherwise. 311 * @exception ClassCastException if obj is not of type Timestamp. 312 * @see #compareTo(Timestamp) 313 * @since 1.2 314 */ compareTo(java.util.Date obj)315 public int compareTo(java.util.Date obj) 316 { 317 return compareTo((Timestamp) obj); 318 } 319 } 320