Save This Page
Home » openjdk-7 » java » sql » [javadoc | source]
    1   /*
    2    * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package java.sql;
   27   
   28   import java.util.StringTokenizer;
   29   
   30   /**
   31    * <P>A thin wrapper around <code>java.util.Date</code> that allows
   32    * the JDBC API to identify this as an SQL <code>TIMESTAMP</code> value.
   33    * It adds the ability
   34    * to hold the SQL <code>TIMESTAMP</code> fractional seconds value, by allowing
   35    * the specification of fractional seconds to a precision of nanoseconds.
   36    * A Timestamp also provides formatting and
   37    * parsing operations to support the JDBC escape syntax for timestamp values.
   38    *
   39    * <p>The precision of a Timestamp object is calculated to be either:
   40    * <ul>
   41    * <li><code>19 </code>, which is the number of characters in yyyy-mm-dd hh:mm:ss
   42    * <li> <code> 20 + s </code>, which is the number
   43    * of characters in the yyyy-mm-dd hh:mm:ss.[fff...] and <code>s</code> represents  the scale of the given Timestamp,
   44    * its fractional seconds precision.
   45    *</ul>
   46    *
   47    * <P><B>Note:</B> This type is a composite of a <code>java.util.Date</code> and a
   48    * separate nanoseconds value. Only integral seconds are stored in the
   49    * <code>java.util.Date</code> component. The fractional seconds - the nanos - are
   50    * separate.  The <code>Timestamp.equals(Object)</code> method never returns
   51    * <code>true</code> when passed an object
   52    * that isn't an instance of <code>java.sql.Timestamp</code>,
   53    * because the nanos component of a date is unknown.
   54    * As a result, the <code>Timestamp.equals(Object)</code>
   55    * method is not symmetric with respect to the
   56    * <code>java.util.Date.equals(Object)</code>
   57    * method.  Also, the <code>hashcode</code> method uses the underlying
   58    * <code>java.util.Date</code>
   59    * implementation and therefore does not include nanos in its computation.
   60    * <P>
   61    * Due to the differences between the <code>Timestamp</code> class
   62    * and the <code>java.util.Date</code>
   63    * class mentioned above, it is recommended that code not view
   64    * <code>Timestamp</code> values generically as an instance of
   65    * <code>java.util.Date</code>.  The
   66    * inheritance relationship between <code>Timestamp</code>
   67    * and <code>java.util.Date</code> really
   68    * denotes implementation inheritance, and not type inheritance.
   69    */
   70   public class Timestamp extends java.util.Date {
   71   
   72       /**
   73        * Constructs a <code>Timestamp</code> object initialized
   74        * with the given values.
   75        *
   76        * @param year the year minus 1900
   77        * @param month 0 to 11
   78        * @param date 1 to 31
   79        * @param hour 0 to 23
   80        * @param minute 0 to 59
   81        * @param second 0 to 59
   82        * @param nano 0 to 999,999,999
   83        * @deprecated instead use the constructor <code>Timestamp(long millis)</code>
   84        * @exception IllegalArgumentException if the nano argument is out of bounds
   85        */
   86       @Deprecated
   87       public Timestamp(int year, int month, int date,
   88                        int hour, int minute, int second, int nano) {
   89           super(year, month, date, hour, minute, second);
   90           if (nano > 999999999 || nano < 0) {
   91               throw new IllegalArgumentException("nanos > 999999999 or < 0");
   92           }
   93           nanos = nano;
   94       }
   95   
   96       /**
   97        * Constructs a <code>Timestamp</code> object
   98        * using a milliseconds time value. The
   99        * integral seconds are stored in the underlying date value; the
  100        * fractional seconds are stored in the <code>nanos</code> field of
  101        * the <code>Timestamp</code> object.
  102        *
  103        * @param time milliseconds since January 1, 1970, 00:00:00 GMT.
  104        *        A negative number is the number of milliseconds before
  105        *         January 1, 1970, 00:00:00 GMT.
  106        * @see java.util.Calendar
  107        */
  108       public Timestamp(long time) {
  109           super((time/1000)*1000);
  110           nanos = (int)((time%1000) * 1000000);
  111           if (nanos < 0) {
  112               nanos = 1000000000 + nanos;
  113               super.setTime(((time/1000)-1)*1000);
  114           }
  115       }
  116   
  117       /**
  118        * Sets this <code>Timestamp</code> object to represent a point in time that is
  119        * <tt>time</tt> milliseconds after January 1, 1970 00:00:00 GMT.
  120        *
  121        * @param time   the number of milliseconds.
  122        * @see #getTime
  123        * @see #Timestamp(long time)
  124        * @see java.util.Calendar
  125        */
  126       public void setTime(long time) {
  127           super.setTime((time/1000)*1000);
  128           nanos = (int)((time%1000) * 1000000);
  129           if (nanos < 0) {
  130               nanos = 1000000000 + nanos;
  131               super.setTime(((time/1000)-1)*1000);
  132           }
  133       }
  134   
  135       /**
  136        * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT
  137        * represented by this <code>Timestamp</code> object.
  138        *
  139        * @return  the number of milliseconds since January 1, 1970, 00:00:00 GMT
  140        *          represented by this date.
  141        * @see #setTime
  142        */
  143       public long getTime() {
  144           long time = super.getTime();
  145           return (time + (nanos / 1000000));
  146       }
  147   
  148   
  149       /**
  150        * @serial
  151        */
  152       private int nanos;
  153   
  154       /**
  155        * Converts a <code>String</code> object in JDBC timestamp escape format to a
  156        * <code>Timestamp</code> value.
  157        *
  158        * @param s timestamp in format <code>yyyy-mm-dd hh:mm:ss[.f...]</code>.  The
  159        * fractional seconds may be omitted.
  160        * @return corresponding <code>Timestamp</code> value
  161        * @exception java.lang.IllegalArgumentException if the given argument
  162        * does not have the format <code>yyyy-mm-dd hh:mm:ss[.f...]</code>
  163        */
  164       public static Timestamp valueOf(String s) {
  165           String date_s;
  166           String time_s;
  167           String nanos_s;
  168           int year;
  169           int month;
  170           int day;
  171           int hour;
  172           int minute;
  173           int second;
  174           int a_nanos = 0;
  175           int firstDash;
  176           int secondDash;
  177           int dividingSpace;
  178           int firstColon = 0;
  179           int secondColon = 0;
  180           int period = 0;
  181           String formatError = "Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]";
  182           String zeros = "000000000";
  183           String delimiterDate = "-";
  184           String delimiterTime = ":";
  185           StringTokenizer stringTokeninzerDate;
  186           StringTokenizer stringTokeninzerTime;
  187   
  188           if (s == null) throw new java.lang.IllegalArgumentException("null string");
  189   
  190           int counterD = 0;
  191           int intDate[] = {4,2,2};
  192   
  193           int counterT = 0;
  194           int intTime[] = {2,2,12};
  195   
  196           // Split the string into date and time components
  197           s = s.trim();
  198           dividingSpace = s.indexOf(' ');
  199           if (dividingSpace > 0) {
  200               date_s = s.substring(0,dividingSpace);
  201               time_s = s.substring(dividingSpace+1);
  202           } else {
  203               throw new java.lang.IllegalArgumentException(formatError);
  204           }
  205   
  206           stringTokeninzerTime = new StringTokenizer(time_s, delimiterTime);
  207           stringTokeninzerDate = new StringTokenizer(date_s, delimiterDate);
  208   
  209           while(stringTokeninzerDate.hasMoreTokens()) {
  210                String tokenDate = stringTokeninzerDate.nextToken();
  211                if(tokenDate.length() != intDate[counterD] ) {
  212                   throw new java.lang.IllegalArgumentException(formatError);
  213                }
  214                counterD++;
  215           }
  216   
  217           /*
  218            //Commenting this portion out for checking of time
  219   
  220           while(stringTokeninzerTime.hasMoreTokens()) {
  221                String tokenTime = stringTokeninzerTime.nextToken();
  222   
  223                if (counterT < 2 && tokenTime.length() != intTime[counterT]  ) {
  224                   throw new java.lang.IllegalArgumentException(formatError);
  225                }
  226                counterT++;
  227           }
  228           */
  229   
  230           // Parse the date
  231           firstDash = date_s.indexOf('-');
  232           secondDash = date_s.indexOf('-', firstDash+1);
  233   
  234           // Parse the time
  235           if (time_s == null)
  236               throw new java.lang.IllegalArgumentException(formatError);
  237           firstColon = time_s.indexOf(':');
  238           secondColon = time_s.indexOf(':', firstColon+1);
  239           period = time_s.indexOf('.', secondColon+1);
  240   
  241           // Convert the date
  242           if ((firstDash > 0) && (secondDash > 0) &&
  243               (secondDash < date_s.length()-1)) {
  244               year = Integer.parseInt(date_s.substring(0, firstDash)) - 1900;
  245               month =
  246                   Integer.parseInt(date_s.substring
  247                                    (firstDash+1, secondDash)) - 1;
  248               day = Integer.parseInt(date_s.substring(secondDash+1));
  249           } else {
  250               throw new java.lang.IllegalArgumentException(formatError);
  251           }
  252   
  253           // Convert the time; default missing nanos
  254           if ((firstColon > 0) & (secondColon > 0) &
  255               (secondColon < time_s.length()-1)) {
  256               hour = Integer.parseInt(time_s.substring(0, firstColon));
  257               minute =
  258                   Integer.parseInt(time_s.substring(firstColon+1, secondColon));
  259               if ((period > 0) & (period < time_s.length()-1)) {
  260                   second =
  261                       Integer.parseInt(time_s.substring(secondColon+1, period));
  262                   nanos_s = time_s.substring(period+1);
  263                   if (nanos_s.length() > 9)
  264                       throw new java.lang.IllegalArgumentException(formatError);
  265                   if (!Character.isDigit(nanos_s.charAt(0)))
  266                       throw new java.lang.IllegalArgumentException(formatError);
  267                   nanos_s = nanos_s + zeros.substring(0,9-nanos_s.length());
  268                   a_nanos = Integer.parseInt(nanos_s);
  269               } else if (period > 0) {
  270                   throw new java.lang.IllegalArgumentException(formatError);
  271               } else {
  272                   second = Integer.parseInt(time_s.substring(secondColon+1));
  273               }
  274           } else {
  275               throw new java.lang.IllegalArgumentException();
  276           }
  277   
  278           return new Timestamp(year, month, day, hour, minute, second, a_nanos);
  279       }
  280   
  281       /**
  282        * Formats a timestamp in JDBC timestamp escape format.
  283        *         <code>yyyy-mm-dd hh:mm:ss.fffffffff</code>,
  284        * where <code>ffffffffff</code> indicates nanoseconds.
  285        * <P>
  286        * @return a <code>String</code> object in
  287        *           <code>yyyy-mm-dd hh:mm:ss.fffffffff</code> format
  288        */
  289       public String toString () {
  290   
  291           int year = super.getYear() + 1900;
  292           int month = super.getMonth() + 1;
  293           int day = super.getDate();
  294           int hour = super.getHours();
  295           int minute = super.getMinutes();
  296           int second = super.getSeconds();
  297           String yearString;
  298           String monthString;
  299           String dayString;
  300           String hourString;
  301           String minuteString;
  302           String secondString;
  303           String nanosString;
  304           String zeros = "000000000";
  305           String yearZeros = "0000";
  306           StringBuffer timestampBuf;
  307   
  308           if (year < 1000) {
  309               // Add leading zeros
  310               yearString = "" + year;
  311               yearString = yearZeros.substring(0, (4-yearString.length())) +
  312                   yearString;
  313           } else {
  314               yearString = "" + year;
  315           }
  316           if (month < 10) {
  317               monthString = "0" + month;
  318           } else {
  319               monthString = Integer.toString(month);
  320           }
  321           if (day < 10) {
  322               dayString = "0" + day;
  323           } else {
  324               dayString = Integer.toString(day);
  325           }
  326           if (hour < 10) {
  327               hourString = "0" + hour;
  328           } else {
  329               hourString = Integer.toString(hour);
  330           }
  331           if (minute < 10) {
  332               minuteString = "0" + minute;
  333           } else {
  334               minuteString = Integer.toString(minute);
  335           }
  336           if (second < 10) {
  337               secondString = "0" + second;
  338           } else {
  339               secondString = Integer.toString(second);
  340           }
  341           if (nanos == 0) {
  342               nanosString = "0";
  343           } else {
  344               nanosString = Integer.toString(nanos);
  345   
  346               // Add leading zeros
  347               nanosString = zeros.substring(0, (9-nanosString.length())) +
  348                   nanosString;
  349   
  350               // Truncate trailing zeros
  351               char[] nanosChar = new char[nanosString.length()];
  352               nanosString.getChars(0, nanosString.length(), nanosChar, 0);
  353               int truncIndex = 8;
  354               while (nanosChar[truncIndex] == '0') {
  355                   truncIndex--;
  356               }
  357   
  358               nanosString = new String(nanosChar, 0, truncIndex + 1);
  359           }
  360   
  361           // do a string buffer here instead.
  362           timestampBuf = new StringBuffer(20+nanosString.length());
  363           timestampBuf.append(yearString);
  364           timestampBuf.append("-");
  365           timestampBuf.append(monthString);
  366           timestampBuf.append("-");
  367           timestampBuf.append(dayString);
  368           timestampBuf.append(" ");
  369           timestampBuf.append(hourString);
  370           timestampBuf.append(":");
  371           timestampBuf.append(minuteString);
  372           timestampBuf.append(":");
  373           timestampBuf.append(secondString);
  374           timestampBuf.append(".");
  375           timestampBuf.append(nanosString);
  376   
  377           return (timestampBuf.toString());
  378       }
  379   
  380       /**
  381        * Gets this <code>Timestamp</code> object's <code>nanos</code> value.
  382        *
  383        * @return this <code>Timestamp</code> object's fractional seconds component
  384        * @see #setNanos
  385        */
  386       public int getNanos() {
  387           return nanos;
  388       }
  389   
  390       /**
  391        * Sets this <code>Timestamp</code> object's <code>nanos</code> field
  392        * to the given value.
  393        *
  394        * @param n the new fractional seconds component
  395        * @exception java.lang.IllegalArgumentException if the given argument
  396        *            is greater than 999999999 or less than 0
  397        * @see #getNanos
  398        */
  399       public void setNanos(int n) {
  400           if (n > 999999999 || n < 0) {
  401               throw new IllegalArgumentException("nanos > 999999999 or < 0");
  402           }
  403           nanos = n;
  404       }
  405   
  406       /**
  407        * Tests to see if this <code>Timestamp</code> object is
  408        * equal to the given <code>Timestamp</code> object.
  409        *
  410        * @param ts the <code>Timestamp</code> value to compare with
  411        * @return <code>true</code> if the given <code>Timestamp</code>
  412        *         object is equal to this <code>Timestamp</code> object;
  413        *         <code>false</code> otherwise
  414        */
  415       public boolean equals(Timestamp ts) {
  416           if (super.equals(ts)) {
  417               if  (nanos == ts.nanos) {
  418                   return true;
  419               } else {
  420                   return false;
  421               }
  422           } else {
  423               return false;
  424           }
  425       }
  426   
  427       /**
  428        * Tests to see if this <code>Timestamp</code> object is
  429        * equal to the given object.
  430        *
  431        * This version of the method <code>equals</code> has been added
  432        * to fix the incorrect
  433        * signature of <code>Timestamp.equals(Timestamp)</code> and to preserve backward
  434        * compatibility with existing class files.
  435        *
  436        * Note: This method is not symmetric with respect to the
  437        * <code>equals(Object)</code> method in the base class.
  438        *
  439        * @param ts the <code>Object</code> value to compare with
  440        * @return <code>true</code> if the given <code>Object</code> is an instance
  441        *         of a <code>Timestamp</code> that
  442        *         is equal to this <code>Timestamp</code> object;
  443        *         <code>false</code> otherwise
  444        */
  445       public boolean equals(java.lang.Object ts) {
  446         if (ts instanceof Timestamp) {
  447           return this.equals((Timestamp)ts);
  448         } else {
  449           return false;
  450         }
  451       }
  452   
  453       /**
  454        * Indicates whether this <code>Timestamp</code> object is
  455        * earlier than the given <code>Timestamp</code> object.
  456        *
  457        * @param ts the <code>Timestamp</code> value to compare with
  458        * @return <code>true</code> if this <code>Timestamp</code> object is earlier;
  459        *        <code>false</code> otherwise
  460        */
  461       public boolean before(Timestamp ts) {
  462           return compareTo(ts) < 0;
  463       }
  464   
  465       /**
  466        * Indicates whether this <code>Timestamp</code> object is
  467        * later than the given <code>Timestamp</code> object.
  468        *
  469        * @param ts the <code>Timestamp</code> value to compare with
  470        * @return <code>true</code> if this <code>Timestamp</code> object is later;
  471        *        <code>false</code> otherwise
  472        */
  473       public boolean after(Timestamp ts) {
  474           return compareTo(ts) > 0;
  475       }
  476   
  477       /**
  478        * Compares this <code>Timestamp</code> object to the given
  479        * <code>Timestamp</code> object.
  480        *
  481        * @param   ts   the <code>Timestamp</code> object to be compared to
  482        *                this <code>Timestamp</code> object
  483        * @return  the value <code>0</code> if the two <code>Timestamp</code>
  484        *          objects are equal; a value less than <code>0</code> if this
  485        *          <code>Timestamp</code> object is before the given argument;
  486        *          and a value greater than <code>0</code> if this
  487        *          <code>Timestamp</code> object is after the given argument.
  488        * @since   1.4
  489        */
  490       public int compareTo(Timestamp ts) {
  491           int i = super.compareTo(ts);
  492           if (i == 0) {
  493               if (nanos > ts.nanos) {
  494                       return 1;
  495               } else if (nanos < ts.nanos) {
  496                   return -1;
  497               }
  498           }
  499           return i;
  500   
  501       }
  502   
  503       /**
  504        * Compares this <code>Timestamp</code> object to the given
  505        * <code>Date</code>, which must be a <code>Timestamp</code>
  506        * object. If the argument is not a <code>Timestamp</code> object,
  507        * this method throws a <code>ClassCastException</code> object.
  508        * (<code>Timestamp</code> objects are
  509        * comparable only to other <code>Timestamp</code> objects.)
  510        *
  511        * @param o the <code>Date</code> to be compared, which must be a
  512        *        <code>Timestamp</code> object
  513        * @return  the value <code>0</code> if this <code>Timestamp</code> object
  514        *          and the given object are equal; a value less than <code>0</code>
  515        *          if this  <code>Timestamp</code> object is before the given argument;
  516        *          and a value greater than <code>0</code> if this
  517        *          <code>Timestamp</code> object is after the given argument.
  518        *
  519        * @since   1.5
  520        */
  521       public int compareTo(java.util.Date o) {
  522          if(o instanceof Timestamp) {
  523               // When Timestamp instance compare it with a Timestamp
  524               // Hence it is basically calling this.compareTo((Timestamp))o);
  525               // Note typecasting is safe because o is instance of Timestamp
  526              return compareTo((Timestamp)o);
  527         } else {
  528               // When Date doing a o.compareTo(this)
  529               // will give wrong results.
  530             Timestamp ts = new Timestamp(o.getTime());
  531             return this.compareTo(ts);
  532         }
  533       }
  534   
  535       static final long serialVersionUID = 2745179027874758501L;
  536   
  537   }

Save This Page
Home » openjdk-7 » java » sql » [javadoc | source]