home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / JAVA_ALL / JDBC / JDBC_011 / JAVA / SQL / TIMESTAM.JAV < prev    next >
Encoding:
Text File  |  1996-11-10  |  9.3 KB  |  330 lines

  1. /*
  2.  * Copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software
  5.  * and its documentation for NON-COMMERCIAL purposes and without
  6.  * fee is hereby granted provided that this copyright notice
  7.  * appears in all copies. Please refer to the file "LICENSE"
  8.  * for further important copyright and licensing information.
  9.  *
  10.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  11.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  12.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  13.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  14.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  15.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  16.  * 
  17.  * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
  18.  * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
  19.  * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
  20.  * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
  21.  * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
  22.  * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
  23.  * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").  SUN
  24.  * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
  25.  * HIGH RISK ACTIVITIES.
  26.  */
  27.  
  28. package java.sql;
  29.  
  30. /**
  31.  * <P>This class is a thin wrapper around java.util.Date that allows
  32.  * JDBC to identify this as a SQL TIMESTAMP value. It adds the ability
  33.  * to hold the SQL TIMESTAMP nanos value and provides formatting and
  34.  * parsing operations to support the JDBC escape syntax for timestamp
  35.  * values.
  36.  *
  37.  * <P><B>Note:</B> This type is a composite of a java.util.Date and a
  38.  * separate nanos value. Only integral seconds are stored in the
  39.  * java.util.Date component. The fractional seconds - the nanos - are
  40.  * separate. The getTime method will only return integral seconds. If
  41.  * a time value that includes the fractional seconds is desired you
  42.  * must convert nanos to milliseconds (nanos/1000000) and add this to
  43.  * the getTime value. Also note that the hashcode() method uses the
  44.  * underlying java.util.Data implementation and therefore does not
  45.  * include nanos in its computation.  
  46.  */
  47. public class Timestamp extends java.util.Date {
  48.  
  49.     /**
  50.      * Construct a Timestamp Object
  51.      *
  52.      * @param year year-1900
  53.      * @param month 0 to 11 
  54.      * @param day 1 to 31
  55.      * @param hour 0 to 23
  56.      * @param minute 0 to 59
  57.      * @param second 0 to 59
  58.      * @param nano 0 to 999,999,999
  59.      */
  60.     public Timestamp(int year, int month, int date, 
  61.              int hour, int minute, int second, int nano) {
  62.     super(year, month, date, hour, minute, second);
  63.     if (nano > 999999999 || nano < 0) {
  64.         throw new IllegalArgumentException("nanos > 999999999 or < 0");
  65.     }
  66.     nanos = nano;
  67.     }
  68.  
  69.     /**
  70.      * Construct a Timestamp using a milliseconds time value. The
  71.      * integral seconds are stored in the underlying date value; the
  72.      * fractional seconds are stored in the nanos value.
  73.      *
  74.      * @param time milliseconds since January 1, 1970, 00:00:00 GMT 
  75.      */
  76.     public Timestamp(long time) {
  77.     super((time/1000)*1000);
  78.     nanos = (int)((time%1000) * 1000000);
  79.     if (nanos < 0) {
  80.         nanos = 1000000000 + nanos;
  81.         setTime(((time/1000)*1000)-1);
  82.     }
  83.     }
  84.  
  85.     private int nanos;
  86.  
  87.     /**
  88.      * Convert a string in JDBC timestamp escape format to a Timestamp value
  89.      *
  90.      * @param s timestamp in format "yyyy-mm-dd hh:mm:ss.fffffffff"
  91.      * @return corresponding Timestamp
  92.      */
  93.     public static Timestamp valueOf(String s) {
  94.     String date_s;
  95.     String time_s;
  96.     String nanos_s;
  97.     int year;
  98.     int month;
  99.     int day;
  100.     int hour;
  101.     int minute;
  102.     int second;
  103.     int a_nanos = 0;
  104.     int firstDash;
  105.     int secondDash;
  106.     int dividingSpace;
  107.     int firstColon = 0;
  108.     int secondColon = 0;
  109.     int period = 0;
  110.     String formatError = "Timestamp format must be yyyy-mm-dd hh:mm:ss.fffffffff";
  111.     String zeros = "000000000";
  112.  
  113.     if (s == null) throw new java.lang.IllegalArgumentException("null string");
  114.  
  115.     // Split the string into date and time components
  116.     s = s.trim();
  117.     dividingSpace = s.indexOf(' ');
  118.     if (dividingSpace > 0) {
  119.         date_s = s.substring(0,dividingSpace);
  120.         time_s = s.substring(dividingSpace+1);
  121.     } else {
  122.         throw new java.lang.IllegalArgumentException(formatError);
  123.     }
  124.  
  125.  
  126.     // Parse the date
  127.     firstDash = date_s.indexOf('-');
  128.     secondDash = date_s.indexOf('-', firstDash+1);
  129.  
  130.     // Parse the time
  131.     if (time_s == null) 
  132.         throw new java.lang.IllegalArgumentException(formatError);
  133.     firstColon = time_s.indexOf(':');
  134.     secondColon = time_s.indexOf(':', firstColon+1);
  135.     period = time_s.indexOf('.', secondColon+1);
  136.  
  137.     // Convert the date
  138.     if ((firstDash > 0) & (secondDash > 0) & 
  139.         (secondDash < date_s.length()-1)) {
  140.         year = Integer.parseInt(date_s.substring(0, firstDash)) - 1900;
  141.         month = 
  142.         Integer.parseInt(date_s.substring
  143.                  (firstDash+1, secondDash)) - 1;
  144.         day = Integer.parseInt(date_s.substring(secondDash+1));
  145.     } else {        
  146.         throw new java.lang.IllegalArgumentException(formatError);
  147.     }
  148.  
  149.     // Convert the time; default missing nanos
  150.     if ((firstColon > 0) & (secondColon > 0) & 
  151.         (secondColon < time_s.length()-1)) {
  152.         hour = Integer.parseInt(time_s.substring(0, firstColon));
  153.         minute = 
  154.         Integer.parseInt(time_s.substring(firstColon+1, secondColon));
  155.         if ((period > 0) & (period < time_s.length()-1)) {
  156.         second = 
  157.             Integer.parseInt(time_s.substring(secondColon+1, period));
  158.         nanos_s = time_s.substring(period+1);
  159.         if (nanos_s.length() > 9) 
  160.             throw new java.lang.IllegalArgumentException(formatError);
  161.         if (!Character.isDigit(nanos_s.charAt(0)))
  162.             throw new java.lang.IllegalArgumentException(formatError);
  163.         nanos_s = nanos_s + zeros.substring(0,9-nanos_s.length());
  164.         a_nanos = Integer.parseInt(nanos_s);
  165.         } else if (period > 0) {
  166.         throw new java.lang.IllegalArgumentException(formatError);
  167.         } else {
  168.         second = Integer.parseInt(time_s.substring(secondColon+1));
  169.         }
  170.     } else {
  171.         throw new java.lang.IllegalArgumentException();
  172.     }
  173.  
  174.     return new Timestamp(year, month, day, hour, minute, second, a_nanos);
  175.     }
  176.  
  177.     /**
  178.      * Format a timestamp in JDBC timestamp escape format
  179.      *
  180.      * @return a String in yyyy-mm-dd hh:mm:ss.fffffffff format
  181.      */
  182.     public String toString () {
  183.     int year = super.getYear() + 1900;
  184.     int month = super.getMonth() + 1;
  185.     int day = super.getDate();
  186.     int hour = super.getHours();
  187.     int minute = super.getMinutes();
  188.     int second = super.getSeconds();
  189.     String yearString;
  190.     String monthString;
  191.     String dayString;
  192.     String hourString;
  193.     String minuteString;
  194.     String secondString;
  195.     String nanosString;
  196.     String zeros = "000000000";
  197.  
  198.         
  199.     yearString = "" + year;
  200.     if (month < 10) {
  201.         monthString = "0" + month;
  202.     } else {        
  203.         monthString = Integer.toString(month);
  204.     }
  205.     if (day < 10) {
  206.         dayString = "0" + day;
  207.     } else {        
  208.         dayString = Integer.toString(day);
  209.     }
  210.     if (hour < 10) {
  211.         hourString = "0" + hour;
  212.     } else {        
  213.         hourString = Integer.toString(hour);
  214.     }
  215.     if (minute < 10) {
  216.         minuteString = "0" + minute;
  217.     } else {        
  218.         minuteString = Integer.toString(minute);
  219.     }
  220.     if (second < 10) {
  221.         secondString = "0" + second;
  222.     } else {        
  223.         secondString = Integer.toString(second);
  224.     }
  225.     if (nanos == 0) {
  226.         nanosString = "0";
  227.     } else {
  228.         nanosString = Integer.toString(nanos);
  229.  
  230.         // Add leading zeros
  231.         nanosString = zeros.substring(0,(9-nanosString.length())) + 
  232.         nanosString;
  233.         
  234.         // Truncate trailing zeros
  235.         char[] nanosChar = new char[nanosString.length()];
  236.         nanosString.getChars(0, nanosString.length(), nanosChar, 0);
  237.         int truncIndex = 8;        
  238.         while (nanosChar[truncIndex] == '0') {
  239.         truncIndex--;
  240.         }
  241.         nanosString = new String(nanosChar,0,truncIndex+1);
  242.     }
  243.     
  244.     return (yearString + "-" + monthString + "-" + dayString + " " + 
  245.         hourString + ":" + minuteString + ":" + secondString + "."
  246.                 + nanosString);
  247.     }
  248.  
  249.     /**
  250.      * Get the Timestamp's nanos value
  251.      *
  252.      * @return the Timestamp's fractional seconds component
  253.      */
  254.     public int getNanos() {
  255.     return nanos;
  256.     }
  257.  
  258.     /**
  259.      * Set the Timestamp's nanos value
  260.      *
  261.      * @param n the new fractional seconds component
  262.      */
  263.     public void setNanos(int n) {
  264.     if (n > 999999999 || n < 0) {
  265.         throw new IllegalArgumentException("nanos > 999999999 or < 0");
  266.     }
  267.     nanos = n;
  268.     }
  269.  
  270.     /**
  271.      * Test Timestamp values for equality
  272.      *
  273.      * @param ts the Timestamp value to compare with
  274.      */
  275.     public boolean equals(Timestamp ts) {
  276.     if (super.equals(ts)) {
  277.         if (nanos == ts.nanos) {
  278.         return true;
  279.         } else {
  280.         return false;
  281.         }
  282.     } else {
  283.         return false;
  284.     }
  285.     }
  286.  
  287.     /**
  288.      * Is this timestamp earlier than the timestamp argument?
  289.      *
  290.      * @param ts the Timestamp value to compare with
  291.      */
  292.     public boolean before(Timestamp ts) {
  293.     if (super.before(ts)) {
  294.         return true;
  295.     } else {
  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.     /**
  309.      * Is this timestamp later than the timestamp argument?
  310.      *
  311.      * @param ts the Timestamp value to compare with
  312.      */
  313.     public boolean after(Timestamp ts) {
  314.     if (super.after(ts)) {
  315.         return true;
  316.     } else {
  317.         if (super.equals(ts)) {
  318.         if (nanos > ts.nanos) {
  319.             return true;
  320.         } else {
  321.             return false;
  322.         }
  323.         } else {
  324.         return false;
  325.         }
  326.     }
  327.     }
  328. }
  329.  
  330.