home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / sql / Timestamp.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  11.3 KB  |  382 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)Timestamp.java    1.29 98/09/29
  3.  *
  4.  * Copyright 1996-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.sql;
  16.  
  17. /**
  18.  * <P>This class is a thin wrapper around java.util.Date that allows
  19.  * JDBC to identify this as a SQL TIMESTAMP value. It adds the ability
  20.  * to hold the SQL TIMESTAMP nanos value and provides formatting and
  21.  * parsing operations to support the JDBC escape syntax for timestamp
  22.  * values.
  23.  *
  24.  * <P><B>Note:</B> This type is a composite of a java.util.Date and a
  25.  * separate nanos value. Only integral seconds are stored in the
  26.  * <code>java.util.Date</code> component. The fractional seconds - the nanos - are
  27.  * separate. The <code>getTime</code> method will return only integral seconds. If
  28.  * a time value that includes the fractional seconds is desired, you
  29.  * must convert nanos to milliseconds (nanos/1000000) and add this to
  30.  * the <code>getTime</code> value.  The
  31.  * <code>Timestamp.equals(Object)</code> method never returns 
  32.  * true when passed a value of type <code>java.util.Date</code>
  33.  * because the nanos component of a date is unknown.
  34.  * As a result, the <code>Timestamp.equals(Object)</code>
  35.  * method is not symmetric with respect to the
  36.  * <code>java.util.Date.equals(Object)</code>
  37.  * method.  Also, the <code>hashcode</code> method uses the underlying 
  38.  * <code>java.util.Data</code> 
  39.  * implementation and therefore does not include nanos in its computation.  
  40.  * 
  41.  * Due to the differences between the <code>Timestamp</code> class
  42.  * and the <code>java.util.Date</code>
  43.  * class mentioned above, it is recommended that code not view
  44.  * <code>Timestamp</code> values generically as an instance of
  45.  * <code>java.util.Date</code>.  The
  46.  * inheritance relationship between <code>Timestamp</code>
  47.  * and <code>java.util.Date</code> really 
  48.  * denotes implementation inheritance, and not type inheritance.  
  49.  */
  50. public class Timestamp extends java.util.Date {
  51.  
  52.     /**
  53.      * Constructs a <code>Timestamp</code> object initialized
  54.      * with the given values.
  55.      *
  56.      * @param year year-1900
  57.      * @param month 0 to 11 
  58.      * @param day 1 to 31
  59.      * @param hour 0 to 23
  60.      * @param minute 0 to 59
  61.      * @param second 0 to 59
  62.      * @param nano 0 to 999,999,999
  63.      * @deprecated instead use the constructor <code>Timestamp(long millis)</code>
  64.      */
  65.     public Timestamp(int year, int month, int date, 
  66.              int hour, int minute, int second, int nano) {
  67.     super(year, month, date, hour, minute, second);
  68.     if (nano > 999999999 || nano < 0) {
  69.         throw new IllegalArgumentException("nanos > 999999999 or < 0");
  70.     }
  71.     nanos = nano;
  72.     }
  73.  
  74.     /**
  75.      * Constructs a <code>Timestamp</code> object 
  76.      * using a milliseconds time value. The
  77.      * integral seconds are stored in the underlying date value; the
  78.      * fractional seconds are stored in the <code>nanos</code> field of
  79.      * the <code>Timestamp</code> object.
  80.      *
  81.      * @param time milliseconds since January 1, 1970, 00:00:00 GMT.
  82.      *        A negative number is the number of milliseconds before 
  83.      *         January 1, 1970, 00:00:00 GMT.
  84.      */
  85.     public Timestamp(long time) {
  86.     super((time/1000)*1000);
  87.     nanos = (int)((time%1000) * 1000000);
  88.     if (nanos < 0) {
  89.         nanos = 1000000000 + nanos;        
  90.         setTime(((time/1000)-1)*1000);
  91.     }
  92.     }
  93.  
  94.     /**
  95.      * @serial
  96.      */
  97.     private int nanos;
  98.  
  99.     /**
  100.      * Converts a string in JDBC timestamp escape format to a
  101.      * <code>Timestamp</code> value.
  102.      *
  103.      * @param s timestamp in format <code>yyyy-mm-dd hh:mm:ss.fffffffff</code>
  104.      * @return corresponding <code>Timestamp</code> value
  105.      * @exception java.lang.IllegalArgumentException if the given argument
  106.      * does not have the format <code>yyyy-mm-dd hh:mm:ss.fffffffff</code>
  107.      */
  108.     public static Timestamp valueOf(String s) {
  109.     String date_s;
  110.     String time_s;
  111.     String nanos_s;
  112.     int year;
  113.     int month;
  114.     int day;
  115.     int hour;
  116.     int minute;
  117.     int second;
  118.     int a_nanos = 0;
  119.     int firstDash;
  120.     int secondDash;
  121.     int dividingSpace;
  122.     int firstColon = 0;
  123.     int secondColon = 0;
  124.     int period = 0;
  125.     String formatError = "Timestamp format must be yyyy-mm-dd hh:mm:ss.fffffffff";
  126.     String zeros = "000000000";
  127.  
  128.     if (s == null) throw new java.lang.IllegalArgumentException("null string");
  129.  
  130.     // Split the string into date and time components
  131.     s = s.trim();
  132.     dividingSpace = s.indexOf(' ');
  133.     if (dividingSpace > 0) {
  134.         date_s = s.substring(0,dividingSpace);
  135.         time_s = s.substring(dividingSpace+1);
  136.     } else {
  137.         throw new java.lang.IllegalArgumentException(formatError);
  138.     }
  139.  
  140.  
  141.     // Parse the date
  142.     firstDash = date_s.indexOf('-');
  143.     secondDash = date_s.indexOf('-', firstDash+1);
  144.  
  145.     // Parse the time
  146.     if (time_s == null) 
  147.         throw new java.lang.IllegalArgumentException(formatError);
  148.     firstColon = time_s.indexOf(':');
  149.     secondColon = time_s.indexOf(':', firstColon+1);
  150.     period = time_s.indexOf('.', secondColon+1);
  151.  
  152.     // Convert the date
  153.     if ((firstDash > 0) & (secondDash > 0) & 
  154.         (secondDash < date_s.length()-1)) {
  155.         year = Integer.parseInt(date_s.substring(0, firstDash)) - 1900;
  156.         month = 
  157.         Integer.parseInt(date_s.substring
  158.                  (firstDash+1, secondDash)) - 1;
  159.         day = Integer.parseInt(date_s.substring(secondDash+1));
  160.     } else {        
  161.         throw new java.lang.IllegalArgumentException(formatError);
  162.     }
  163.  
  164.     // Convert the time; default missing nanos
  165.     if ((firstColon > 0) & (secondColon > 0) & 
  166.         (secondColon < time_s.length()-1)) {
  167.         hour = Integer.parseInt(time_s.substring(0, firstColon));
  168.         minute = 
  169.         Integer.parseInt(time_s.substring(firstColon+1, secondColon));
  170.         if ((period > 0) & (period < time_s.length()-1)) {
  171.         second = 
  172.             Integer.parseInt(time_s.substring(secondColon+1, period));
  173.         nanos_s = time_s.substring(period+1);
  174.         if (nanos_s.length() > 9) 
  175.             throw new java.lang.IllegalArgumentException(formatError);
  176.         if (!Character.isDigit(nanos_s.charAt(0)))
  177.             throw new java.lang.IllegalArgumentException(formatError);
  178.         nanos_s = nanos_s + zeros.substring(0,9-nanos_s.length());
  179.         a_nanos = Integer.parseInt(nanos_s);
  180.         } else if (period > 0) {
  181.         throw new java.lang.IllegalArgumentException(formatError);
  182.         } else {
  183.         second = Integer.parseInt(time_s.substring(secondColon+1));
  184.         }
  185.     } else {
  186.         throw new java.lang.IllegalArgumentException();
  187.     }
  188.  
  189.     return new Timestamp(year, month, day, hour, minute, second, a_nanos);
  190.     }
  191.  
  192.     /**
  193.      * Formats a timestamp in JDBC timestamp escape format.
  194.      *
  195.      * @return a String in <code>yyyy-mm-dd hh:mm:ss.fffffffff</code> format
  196.      * @overrides toString in class <code>java.util.Date</code>
  197.      */
  198.     public String toString () {
  199.     int year = super.getYear() + 1900;
  200.     int month = super.getMonth() + 1;
  201.     int day = super.getDate();
  202.     int hour = super.getHours();
  203.     int minute = super.getMinutes();
  204.     int second = super.getSeconds();
  205.     String yearString;
  206.     String monthString;
  207.     String dayString;
  208.     String hourString;
  209.     String minuteString;
  210.     String secondString;
  211.     String nanosString;
  212.     String zeros = "000000000";
  213.  
  214.         
  215.     yearString = "" + year;
  216.     if (month < 10) {
  217.         monthString = "0" + month;
  218.     } else {        
  219.         monthString = Integer.toString(month);
  220.     }
  221.     if (day < 10) {
  222.         dayString = "0" + day;
  223.     } else {        
  224.         dayString = Integer.toString(day);
  225.     }
  226.     if (hour < 10) {
  227.         hourString = "0" + hour;
  228.     } else {        
  229.         hourString = Integer.toString(hour);
  230.     }
  231.     if (minute < 10) {
  232.         minuteString = "0" + minute;
  233.     } else {        
  234.         minuteString = Integer.toString(minute);
  235.     }
  236.     if (second < 10) {
  237.         secondString = "0" + second;
  238.     } else {        
  239.         secondString = Integer.toString(second);
  240.     }
  241.     if (nanos == 0) {
  242.         nanosString = "0";
  243.     } else {
  244.         nanosString = Integer.toString(nanos);
  245.  
  246.         // Add leading zeros
  247.         nanosString = zeros.substring(0,(9-nanosString.length())) + 
  248.         nanosString;
  249.         
  250.         // Truncate trailing zeros
  251.         char[] nanosChar = new char[nanosString.length()];
  252.         nanosString.getChars(0, nanosString.length(), nanosChar, 0);
  253.         int truncIndex = 8;        
  254.         while (nanosChar[truncIndex] == '0') {
  255.         truncIndex--;
  256.         }
  257.         nanosString = new String(nanosChar,0,truncIndex+1);
  258.     }
  259.     
  260.     return (yearString + "-" + monthString + "-" + dayString + " " + 
  261.         hourString + ":" + minuteString + ":" + secondString + "."
  262.                 + nanosString);
  263.     }
  264.  
  265.     /**
  266.      * Gets this <code>Timestamp</code> object's <code>nanos</code> value.
  267.      *
  268.      * @return this <code>Timestamp</code> object's fractional seconds component
  269.      */
  270.     public int getNanos() {
  271.     return nanos;
  272.     }
  273.  
  274.     /**
  275.      * Sets this <code>Timestamp</code> object's <code>nanos</code> value
  276.      * to the given value.
  277.      *
  278.      * @param n the new fractional seconds component
  279.      * @exception java.lang.IllegalArgumentException if the given argument
  280.      *            is greater than 999999999 or less than 0
  281.      */
  282.     public void setNanos(int n) {
  283.     if (n > 999999999 || n < 0) {
  284.         throw new IllegalArgumentException("nanos > 999999999 or < 0");
  285.     }
  286.     nanos = n;
  287.     }
  288.  
  289.     /**
  290.      * Tests to see if this <code>Timestamp</code> object is
  291.      * equal to the given <code>Timestamp</code> object.
  292.      *
  293.      * @param ts the <code>Timestamp</code> value to compare with
  294.      */
  295.     public boolean equals(Timestamp ts) {
  296.     if (super.equals(ts)) {
  297.         if  (nanos == ts.nanos) {
  298.         return true;
  299.         } else {
  300.         return false;
  301.         }
  302.     } else {
  303.         return false;
  304.     }
  305.     }
  306.  
  307.     /**
  308.      * Tests to see if this <code>Timestamp</code> object is
  309.      * equal to the given object.
  310.      *
  311.      * This version of the method <code>equals</code> has been added
  312.      * to fix the incorrect 
  313.      * signature of <code>Timestamp.equals(Timestamp)</code> and preserve backward 
  314.      * compatibility with existing class files.
  315.      *
  316.      * Note: This method is not symmetric with respect to the 
  317.      * <code>equals(Object)</code> method in the base class.
  318.      *
  319.      * @param ts the Object value to compare with
  320.      */
  321.     public boolean equals(java.lang.Object ts) {
  322.       if (ts instanceof Timestamp) {
  323.     return this.equals((Timestamp)ts);
  324.       } else {
  325.     return false;
  326.       }
  327.     }
  328.  
  329.     /**
  330.      * Indicates whether this <code>Timestamp</code> object is
  331.      * earlier than the given <code>Timestamp</code> object.
  332.      *
  333.      * @param ts the Timestamp value to compare with
  334.      * @return <code>true</code> if this <code>Timestamp</code> object is earlier;
  335.      *        <code>false</code> otherwise
  336.      */
  337.     public boolean before(Timestamp ts) {
  338.     if (super.before(ts)) {
  339.         return true;
  340.     } else {
  341.         if (super.equals(ts)) {
  342.         if (nanos < ts.nanos) {
  343.             return true;
  344.         } else {
  345.             return false;
  346.         }
  347.         } else {
  348.         return false;
  349.         }
  350.     }
  351.     }
  352.  
  353.     /**
  354.      * Indicates whether this <code>Timestamp</code> object is
  355.      * later than the given <code>Timestamp</code> object.
  356.      * Is this timestamp later than the timestamp argument?
  357.      *
  358.      * @param ts the Timestamp value to compare with
  359.      * @return <code>true</code> if this <code>Timestamp</code> object is later;
  360.      *        <code>false</code> otherwise
  361.      */
  362.     public boolean after(Timestamp ts) {
  363.     if (super.after(ts)) {
  364.         return true;
  365.     } else {
  366.         if (super.equals(ts)) {
  367.         if (nanos > ts.nanos) {
  368.             return true;
  369.         } else {
  370.             return false;
  371.         }
  372.         } else {
  373.         return false;
  374.         }
  375.     }
  376.     }
  377.  
  378.     static final long serialVersionUID = 2745179027874758501L;
  379.  
  380. }
  381.  
  382.