/*
* Copyright ( c ) 1996 , 2020 , Oracle and / or its affiliates . All rights reserved .
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation . Oracle designates this
* particular file as subject to the " Classpath " exception as provided
* by Oracle in the LICENSE file that accompanied this code .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*/
package java.sql;
import java.time.Instant;
import java.time.LocalDateTime;
/**
* < P > A thin wrapper around { @ code java . util . Date } that allows
* the JDBC API to identify this as an SQL { @ code TIMESTAMP } value .
* It adds the ability
* to hold the SQL { @ code TIMESTAMP } fractional seconds value , by allowing
* the specification of fractional seconds to a precision of nanoseconds .
* A Timestamp also provides formatting and
* parsing operations to support the JDBC escape syntax for timestamp values .
*
* < p > The precision of a Timestamp object is calculated to be either :
* < ul >
* < li > { @ code 19 } , which is the number of characters in yyyy - mm - dd hh : mm : ss
* < li > { @ code 20 + s } , which is the number
* of characters in the yyyy - mm - dd hh : mm : ss . [ fff . . . ] and { @ code s } represents the scale of the given Timestamp ,
* its fractional seconds precision .
* < / ul >
*
* < P > < B > Note : < / B > This type is a composite of a { @ code java . util . Date } and a
* separate nanoseconds value . Only integral seconds are stored in the
* { @ code java . util . Date } component . The fractional seconds - the nanos - are
* separate . The { @ code Timestamp . equals ( Object ) } method never returns
* { @ code true } when passed an object
* that isn ' t an instance of { @ code java . sql . Timestamp } ,
* because the nanos component of a date is unknown .
* As a result , the { @ code Timestamp . equals ( Object ) }
* method is not symmetric with respect to the
* { @ code java . util . Date . equals ( Object ) }
* method . Also , the { @ code hashCode } method uses the underlying
* { @ code java . util . Date }
* implementation and therefore does not include nanos in its computation .
* < P >
* Due to the differences between the { @ code Timestamp } class
* and the { @ code java . util . Date }
* class mentioned above , it is recommended that code not view
* { @ code Timestamp } values generically as an instance of
* { @ code java . util . Date } . The
* inheritance relationship between { @ code Timestamp }
* and { @ code java . util . Date } really
* denotes implementation inheritance , and not type inheritance .
*
* @ since 1 . 1
*/
public class Timestamp extends java.util.Date {
/**
* Constructs a { @ code Timestamp } object initialized
* with the given values .
*
* @ param year the year minus 1900
* @ param month 0 to 11
* @ param date 1 to 31
* @ param hour 0 to 23
* @ param minute 0 to 59
* @ param second 0 to 59
* @ param nano 0 to 999 , 999 , 999
* @ deprecated instead use the constructor { @ code Timestamp ( long millis ) }
* @ throws IllegalArgumentException if the nano argument is out of bounds
*/
@Deprecated(since="1.2" )
public Timestamp(int year, int month, int date,
int hour, int minute, int second, int nano) {
super (year, month, date, hour, minute, second);
if (nano > 999999999 || nano < 0 ) {
throw new IllegalArgumentException("nanos > 999999999 or < 0" );
}
nanos = nano;
}
/**
* Constructs a { @ code Timestamp } object
* using a milliseconds time value . The
* integral seconds are stored in the underlying date value ; the
* fractional seconds are stored in the { @ code nanos } field of
* the { @ code Timestamp } object .
*
* @ param time milliseconds since January 1 , 1970 , 00 : 00 : 00 GMT .
* A negative number is the number of milliseconds before
* January 1 , 1970 , 00 : 00 : 00 GMT .
* @ see java . util . Calendar
*/
public Timestamp(long time) {
super ((time/1000 )*1000 );
nanos = (int )((time%1000 ) * 1000000 );
if (nanos < 0 ) {
nanos = 1000000000 + nanos;
super .setTime(((time/1000 )-1 )*1000 );
}
}
/**
* Sets this { @ code Timestamp } object to represent a point in time that is
* { @ code time } milliseconds after January 1 , 1970 00 : 00 : 00 GMT .
*
* @ param time the number of milliseconds .
* @ see # getTime
* @ see # Timestamp ( long time )
* @ see java . util . Calendar
*/
public void setTime(long time) {
super .setTime((time/1000 )*1000 );
nanos = (int )((time%1000 ) * 1000000 );
if (nanos < 0 ) {
nanos = 1000000000 + nanos;
super .setTime(((time/1000 )-1 )*1000 );
}
}
/**
* Returns the number of milliseconds since January 1 , 1970 , 00 : 00 : 00 GMT
* represented by this { @ code Timestamp } object .
*
* @ return the number of milliseconds since January 1 , 1970 , 00 : 00 : 00 GMT
* represented by this date .
* @ see # setTime
*/
public long getTime() {
long time = super .getTime();
return (time + (nanos / 1000000 ));
}
/**
* @ serial
*/
private int nanos;
/**
* Converts a { @ code String } object in JDBC timestamp escape format to a
* { @ code Timestamp } value .
*
* @ param s timestamp in format { @ code yyyy - [ m ] m - [ d ] d hh : mm : ss [ . f . . . ] } . The
* fractional seconds may be omitted . The leading zero for { @ code mm }
* and { @ code dd } may also be omitted .
*
* @ return corresponding { @ code Timestamp } value
* @ throws java . lang . IllegalArgumentException if the given argument
* does not have the format { @ code yyyy - [ m ] m - [ d ] d hh : mm : ss [ . f . . . ] }
*/
public static Timestamp valueOf(String s) {
final int YEAR_LENGTH = 4 ;
final int MONTH_LENGTH = 2 ;
final int DAY_LENGTH = 2 ;
final int MAX_MONTH = 12 ;
final int MAX_DAY = 31 ;
int year = 0 ;
int month = 0 ;
int day = 0 ;
int hour;
int minute;
int second;
int a_nanos = 0 ;
int firstDash;
int secondDash;
int dividingSpace;
int firstColon;
int secondColon;
int period;
String formatError = "Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]" ;
if (s == null ) throw new java.lang.IllegalArgumentException("null string" );
// Split the string into date and time components
s = s.trim();
dividingSpace = s.indexOf(' ' );
if (dividingSpace < 0 ) {
throw new java.lang.IllegalArgumentException(formatError);
}
// Parse the date
firstDash = s.indexOf('-' );
secondDash = s.indexOf('-' , firstDash+1 );
// Parse the time
firstColon = s.indexOf(':' , dividingSpace + 1 );
secondColon = s.indexOf(':' , firstColon + 1 );
period = s.indexOf('.' , secondColon + 1 );
// Convert the date
boolean parsedDate = false ;
if (firstDash > 0 && secondDash > 0 && secondDash < dividingSpace - 1 ) {
if (firstDash == YEAR_LENGTH &&
(secondDash - firstDash > 1 && secondDash - firstDash <= MONTH_LENGTH + 1 ) &&
(dividingSpace - secondDash > 1 && dividingSpace - secondDash <= DAY_LENGTH + 1 )) {
year = Integer.parseInt(s, 0 , firstDash, 10 );
month = Integer.parseInt(s, firstDash + 1 , secondDash, 10 );
day = Integer.parseInt(s, secondDash + 1 , dividingSpace, 10 );
if ((month >= 1 && month <= MAX_MONTH) && (day >= 1 && day <= MAX_DAY)) {
parsedDate = true ;
}
}
}
if (! parsedDate) {
throw new java.lang.IllegalArgumentException(formatError);
}
// Convert the time; default missing nanos
int len = s.length();
if (firstColon > 0 && secondColon > 0 && secondColon < len - 1 ) {
hour = Integer.parseInt(s, dividingSpace + 1 , firstColon, 10 );
minute = Integer.parseInt(s, firstColon + 1 , secondColon, 10 );
if (period > 0 && period < len - 1 ) {
second = Integer.parseInt(s, secondColon + 1 , period, 10 );
int nanoPrecision = len - (period + 1 );
if (nanoPrecision > 9 )
throw new java.lang.IllegalArgumentException(formatError);
if (!Character.isDigit(s.charAt(period + 1 )))
throw new java.lang.IllegalArgumentException(formatError);
int tmpNanos = Integer.parseInt(s, period + 1 , len, 10 );
while (nanoPrecision < 9 ) {
tmpNanos *= 10 ;
nanoPrecision++;
}
a_nanos = tmpNanos;
} else if (period > 0 ) {
throw new java.lang.IllegalArgumentException(formatError);
} else {
second = Integer.parseInt(s, secondColon + 1 , len, 10 );
}
} else {
throw new java.lang.IllegalArgumentException(formatError);
}
return new Timestamp(year - 1900 , month - 1 , day, hour, minute, second, a_nanos);
}
/**
* Formats a timestamp in JDBC timestamp escape format .
* { @ code yyyy - mm - dd hh : mm : ss . fffffffff } ,
* where { @ code fffffffff } indicates nanoseconds .
*
* @ return a { @ code String } object in
* { @ code yyyy - mm - dd hh : mm : ss . fffffffff } format
*/
@SuppressWarnings("deprecation" )
public String toString() {
int year = super .getYear() + 1900 ;
int month = super .getMonth() + 1 ;
int day = super .getDate();
int hour = super .getHours();
int minute = super .getMinutes();
int second = super .getSeconds();
int trailingZeros = 0 ;
int tmpNanos = nanos;
if (tmpNanos == 0 ) {
trailingZeros = 8 ;
} else {
while (tmpNanos % 10 == 0 ) {
tmpNanos /= 10 ;
trailingZeros++;
}
}
// 8058429: To comply with current JCK tests, we need to deal with year
// being any number between 0 and 292278995
int count = 10000 ;
int yearSize = 4 ;
do {
if (year < count) {
break ;
}
yearSize++;
count *= 10 ;
} while (count < 1000000000 );
char [] buf = new char [25 + yearSize - trailingZeros];
Date.formatDecimalInt(year, buf, 0 , yearSize);
buf[yearSize] = '-' ;
Date.formatDecimalInt(month, buf, yearSize + 1 , 2 );
buf[yearSize + 3 ] = '-' ;
Date.formatDecimalInt(day, buf, yearSize + 4 , 2 );
buf[yearSize + 6 ] = ' ' ;
Date.formatDecimalInt(hour, buf, yearSize + 7 , 2 );
buf[yearSize + 9 ] = ':' ;
Date.formatDecimalInt(minute, buf, yearSize + 10 , 2 );
buf[yearSize + 12 ] = ':' ;
Date.formatDecimalInt(second, buf, yearSize + 13 , 2 );
buf[yearSize + 15 ] = '.' ;
Date.formatDecimalInt(tmpNanos, buf, yearSize + 16 , 9 - trailingZeros);
return new String(buf);
}
/**
* Gets this { @ code Timestamp } object ' s { @ code nanos } value .
*
* @ return this { @ code Timestamp } object ' s fractional seconds component
* @ see # setNanos
*/
public int getNanos() {
return nanos;
}
/**
* Sets this { @ code Timestamp } object ' s { @ code nanos } field
* to the given value .
*
* @ param n the new fractional seconds component
* @ throws java . lang . IllegalArgumentException if the given argument
* is greater than 999999999 or less than 0
* @ see # getNanos
*/
public void setNanos(int n) {
if (n > 999999999 || n < 0 ) {
throw new IllegalArgumentException("nanos > 999999999 or < 0" );
}
nanos = n;
}
/**
* Tests to see if this { @ code Timestamp } object is
* equal to the given { @ code Timestamp } object .
*
* @ param ts the { @ code Timestamp } value to compare with
* @ return { @ code true } if the given { @ code Timestamp }
* object is equal to this { @ code Timestamp } object ;
* { @ code false } otherwise
*/
public boolean equals(Timestamp ts) {
if (super .equals(ts)) {
if (nanos == ts.nanos) {
return true ;
} else {
return false ;
}
} else {
return false ;
}
}
/**
* Tests to see if this { @ code Timestamp } object is
* equal to the given object .
*
* This version of the method { @ code equals } has been added
* to fix the incorrect
* signature of { @ code Timestamp . equals ( Timestamp ) } and to preserve backward
* compatibility with existing class files .
*
* Note : This method is not symmetric with respect to the
* { @ code equals ( Object ) } method in the base class .
*
* @ param ts the { @ code Object } value to compare with
* @ return { @ code true } if the given { @ code Object } is an instance
* of a { @ code Timestamp } that
* is equal to this { @ code Timestamp } object ;
* { @ code false } otherwise
*/
public boolean equals(java.lang.Object ts) {
if (ts instanceof Timestamp) {
return this .equals((Timestamp)ts);
} else {
return false ;
}
}
/**
* Indicates whether this { @ code Timestamp } object is
* earlier than the given { @ code Timestamp } object .
*
* @ param ts the { @ code Timestamp } value to compare with
* @ return { @ code true } if this { @ code Timestamp } object is earlier ;
* { @ code false } otherwise
*/
public boolean before(Timestamp ts) {
return compareTo(ts) < 0 ;
}
/**
* Indicates whether this { @ code Timestamp } object is
* later than the given { @ code Timestamp } object .
*
* @ param ts the { @ code Timestamp } value to compare with
* @ return { @ code true } if this { @ code Timestamp } object is later ;
* { @ code false } otherwise
*/
public boolean after(Timestamp ts) {
return compareTo(ts) > 0 ;
}
/**
* Compares this { @ code Timestamp } object to the given
* { @ code Timestamp } object .
*
* @ param ts the { @ code Timestamp } object to be compared to
* this { @ code Timestamp } object
* @ return the value { @ code 0 } if the two { @ code Timestamp }
* objects are equal ; a value less than { @ code 0 } if this
* { @ code Timestamp } object is before the given argument ;
* and a value greater than { @ code 0 } if this
* { @ code Timestamp } object is after the given argument .
* @ since 1 . 4
*/
public int compareTo(Timestamp ts) {
long thisTime = this .getTime();
long anotherTime = ts.getTime();
int i = (thisTime<anotherTime ? -1 :(thisTime==anotherTime?0 :1 ));
if (i == 0 ) {
if (nanos > ts.nanos) {
return 1 ;
} else if (nanos < ts.nanos) {
return -1 ;
}
}
return i;
}
/**
* Compares this { @ code Timestamp } object to the given
* { @ code Date } object .
*
* @ param o the { @ code Date } to be compared to
* this { @ code Timestamp } object
* @ return the value { @ code 0 } if this { @ code Timestamp } object
* and the given object are equal ; a value less than { @ code 0 }
* if this { @ code Timestamp } object is before the given argument ;
* and a value greater than { @ code 0 } if this
* { @ code Timestamp } object is after the given argument .
*
* @ since 1 . 5
*/
public int compareTo(java.util.Date o) {
if (o instanceof Timestamp) {
// When Timestamp instance compare it with a Timestamp
// Hence it is basically calling this.compareTo((Timestamp))o);
// Note typecasting is safe because o is instance of Timestamp
return compareTo((Timestamp)o);
} else {
// When Date doing a o.compareTo(this)
// will give wrong results.
Timestamp ts = new Timestamp(o.getTime());
return this .compareTo(ts);
}
}
/**
* { @ inheritDoc }
*
* The { @ code hashCode } method uses the underlying { @ code java . util . Date }
* implementation and therefore does not include nanos in its computation .
*
*/
@Override
public int hashCode() {
return super .hashCode();
}
static final long serialVersionUID = 2745179027874758501 L;
private static final int MILLIS_PER_SECOND = 1000 ;
/**
* Obtains an instance of { @ code Timestamp } from a { @ code LocalDateTime }
* object , with the same year , month , day of month , hours , minutes ,
* seconds and nanos date - time value as the provided { @ code LocalDateTime } .
* < p >
* The provided { @ code LocalDateTime } is interpreted as the local
* date - time in the local time zone .
*
* @ param dateTime a { @ code LocalDateTime } to convert
* @ return a { @ code Timestamp } object
* @ throws NullPointerException if { @ code dateTime } is null .
* @ since 1 . 8
*/
@SuppressWarnings("deprecation" )
public static Timestamp valueOf(LocalDateTime dateTime) {
return new Timestamp(dateTime.getYear() - 1900 ,
dateTime.getMonthValue() - 1 ,
dateTime.getDayOfMonth(),
dateTime.getHour(),
dateTime.getMinute(),
dateTime.getSecond(),
dateTime.getNano());
}
/**
* Converts this { @ code Timestamp } object to a { @ code LocalDateTime } .
* < p >
* The conversion creates a { @ code LocalDateTime } that represents the
* same year , month , day of month , hours , minutes , seconds and nanos
* date - time value as this { @ code Timestamp } in the local time zone .
*
* @ return a { @ code LocalDateTime } object representing the same date - time value
* @ since 1 . 8
*/
@SuppressWarnings("deprecation" )
public LocalDateTime toLocalDateTime() {
return LocalDateTime.of(getYear() + 1900 ,
getMonth() + 1 ,
getDate(),
getHours(),
getMinutes(),
getSeconds(),
getNanos());
}
/**
* Obtains an instance of { @ code Timestamp } from an { @ link Instant } object .
* < p >
* { @ code Instant } can store points on the time - line further in the future
* and further in the past than { @ code Date } . In this scenario , this method
* will throw an exception .
*
* @ param instant the instant to convert
* @ return an { @ code Timestamp } representing the same point on the time - line as
* the provided instant
* @ throws NullPointerException if { @ code instant } is null .
* @ throws IllegalArgumentException if the instant is too large to
* represent as a { @ code Timestamp }
* @ since 1 . 8
*/
public static Timestamp from(Instant instant) {
try {
Timestamp stamp = new Timestamp(instant.getEpochSecond() * MILLIS_PER_SECOND);
stamp.nanos = instant.getNano();
return stamp;
} catch (ArithmeticException ex) {
throw new IllegalArgumentException(ex);
}
}
/**
* Converts this { @ code Timestamp } object to an { @ code Instant } .
* < p >
* The conversion creates an { @ code Instant } that represents the same
* point on the time - line as this { @ code Timestamp } .
*
* @ return an instant representing the same point on the time - line
* @ since 1 . 8
*/
@Override
public Instant toInstant() {
return Instant.ofEpochSecond(super .getTime() / MILLIS_PER_SECOND, nanos);
}
}
Messung V0.5 in Prozent C=98 H=78 G=88
¤ Dauer der Verarbeitung: 0.16 Sekunden
¤
*© Formatika GbR, Deutschland