Source for java.sql.Timestamp

   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:    */
  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:    */
 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:    */
 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:    */
 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:    */
 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:     */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 315:   public int compareTo(java.util.Date obj)
 316:   {
 317:     return compareTo((Timestamp) obj);
 318:   }
 319: }