/*
 * Timestamp.java
 *
 * Created on Tue Dec 09 15:22:55 EST 2003
 *
 * Copyright (c) 2003 Spallation Neutron Source
 * Oak Ridge National Laboratory
 * Oak Ridge, TN 37830
 */

package xal.ca;


import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.text.DecimalFormat;
import java.util.Date;


/**
 * Timestamp
 * @author  tap
 */
public class Timestamp implements Comparable {
	/** date formatter */
    static final SimpleDateFormat TIME_FORMATTER;
	
	/** format an integer to have nine digits including leading zeros as necessary   */
	static final DecimalFormat NANOSECOND_FORMATTER;
	
	/** constant for 1000 */
	static final BigDecimal THOUSAND = new BigDecimal( 1000 );
	
	/** the timestamp information */
	protected BigDecimal _timestamp;
	
    
	// static initializer
    static {
        TIME_FORMATTER = new SimpleDateFormat( "MMM d, yyyy HH:mm:ss" );
		NANOSECOND_FORMATTER = new DecimalFormat( "000000000" );
    }
	
	
	/**
	 * Primary constructor from the full precision seconds since the Java epoch.
	 * @param timestamp the number of seconds since the Java epoch
	 */
	public Timestamp( final BigDecimal timestamp ) {
		_timestamp = timestamp;
	}
	
	
	/**
	 * Construct a Timestamp from a java.sql.Timestamp
	 * @param timestamp an SQL timestamp
	 */
	public Timestamp( final java.sql.Timestamp timestamp ) {
		this( toBigDecimal( timestamp ) );
	}
    
    
    /**
     * Get the times tamp as a Java Date.
     * Some precision is lost since the Date class only supports millisecond resolution.
     * @return The time stamp as a Date.
     */
    public Date getDate() {
        return new Date( getTime() );
    }
    
    
    /**
     * Get the timestamp in milliseconds relative to the Java epoch.
     * @return The time in milliseconds since the Java epoch.
     */
    public long getTime() {
        return ( _timestamp.multiply(THOUSAND) ).longValue();        
    }
	
	
	/**
	 * Get the time in seconds since the Java epoch.
	 * @return the time in seconds since the Java epoch.
	 */
	public double getSeconds() {
		return _timestamp.doubleValue();
	}
	
	
	/**
	 * Get the time in seconds with full precision since the Java epoch.
	 * @return the time in seconds since the Java epoch.
	 */
	public BigDecimal getFullSeconds() {
		return _timestamp;
	}
	
	
	/**
	 * Get the SQL Timestamp equivalent of this instance.
	 * @return the SQL Timestamp equivalent of this instance.
	 */
	public java.sql.Timestamp getSQLTimestamp() {
		java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp( getTime() );
		int nanoseconds = _timestamp.subtract( _timestamp.setScale(0, BigDecimal.ROUND_DOWN) ).movePointRight(9).intValue();
		sqlTimestamp.setNanos(nanoseconds);
		
		return sqlTimestamp;
	}
	
	
	/**
	 * Convert a java.sql.Timestamp to BigDecimal time.
	 * @param timestamp The timestamp as a java.sql.Timestamp
	 * @return the timestamp as a BigDecimal in seconds since the Java epoch
	 */
	static private BigDecimal toBigDecimal(java.sql.Timestamp timestamp) {
		BigDecimal seconds = new BigDecimal( timestamp.getTime() / 1000 );
		BigDecimal nanoSeconds = new BigDecimal( timestamp.getNanos() );
		return seconds.add( nanoSeconds.movePointLeft(9) ).setScale( 9, BigDecimal.ROUND_HALF_UP );
	}
	
	
	/**
	 * Get a string representation of the Timestamp.
	 * @return a string representation of the Timestamp
	 */
	public String toString() {
		final long nanoseconds = _timestamp.subtract( _timestamp.setScale( 0, BigDecimal.ROUND_DOWN ) ).movePointRight(9).longValue();
		return TIME_FORMATTER.format( getDate() ) + "." + NANOSECOND_FORMATTER.format( nanoseconds );
	}
	
	
	/**
	 * Determine if the specified timestamp equals this one.
	 * @return true if they are equals and false if not
	 */
	public boolean equals( final Object timestamp ) {
		if ( timestamp != null && timestamp instanceof Timestamp ) {
			return ((Timestamp)timestamp)._timestamp.equals( _timestamp );
		}
		else {
			return false;
		}
	}
	
	
	/**
	 * Compare this timestamp with another timestamp.
	 * @param otherTimestamp The timestamp with which to compare this one
	 * @return 0 if the timestamps are the same, negative if this is earlier than the supplied one and positive otherwise
	 */
	public int compareTo(Object otherTimestamp) {
		return _timestamp.compareTo(((Timestamp)otherTimestamp)._timestamp);
	}
}


@@ -236,22 +236,16 @@
 va.text.
-Simple
 DateForm
@@ -272,32 +272,67 @@
 .DecimalFormat;%0A
+import java.text.SimpleDateFormat;%0A
 import java.util
@@ -3274,24 +3274,25 @@
 %09%0A%09%0A%09/**
-%0A%09 * Get
+ Generate
  a strin
@@ -3313,27 +3313,28 @@
 on of th
-e T
+is t
 imestamp
 .%0A%09 * @r
@@ -3329,92 +3329,182 @@
 tamp
-.%0A%09 * @return a string representation of the Timestamp%0A%09 */%0A%09public String toString(
+ using the specified time format for the time format up to seconds. Subsecond time is appended using a decimal point. */%0A%09public String toString( final DateFormat timeFormat 
 ) %7B%0A
@@ -3641,30 +3641,26 @@
 %09return 
-TIME_FORMATTER
+timeFormat
 .format(
@@ -3732,24 +3732,209 @@
 %09%7D%0A%09%0A%09%0A%09/**%0A
+%09 * Get a string representation of the Timestamp.%0A%09 * @return a string representation of the Timestamp%0A%09 */%0A%09public String toString() %7B%0A%09%09return toString( TIME_FORMATTER );%0A%09%7D%0A%09%0A%09%0A%09/**%0A
 %09 * Determin

Add a method to get the timestamp's string representation using a custom date format.