java.util.Timestamp's public constructor Timestamp(long date) fails to initialize the "nanos" field correctly. This leads to Timestamp#toString() producing an incorrectly formatted value. Even if the "nanos" field *were* initialized by the above constructor correctly, toString() would still be wrong, because it fails to left-pad the value of "nanos" with zeros. For instance, if "nanos" is 1, the returned String is something like "2004-11-09 06:33:19.1" rather than the correct "2004-11-09 06:33:19.000000001". The following test illustrates the problem: | $ cat TStampTest.java | import java.sql.Timestamp; | | /** | * http://tinyurl.com/67s3k | **/ | public class TStampTest { | | public final static void main(String[] args) { | Timestamp ts = new Timestamp(1099999999333L); | log(ts, "333 milliseconds:"); | ts.setNanos(42); | log(ts, "42 nanoseconds"); | } | | private static void log(String msg) { | System.out.println(msg); | } | private static void log(Timestamp ts, String msg) { | log(msg); | log(" ts: " + ts); | log(" ts.getTime(): " + ts.getTime()); | log(" ts.getNanos(): " + ts.getNanos()); | } | } With Sun's JDK 1.4, I get: | $ java -cp . TStampTest | 333 milliseconds: | ts: 2004-11-09 06:33:19.333 | ts.getTime(): 1099999999333 | ts.getNanos(): 333000000 | 42 nanoseconds | ts: 2004-11-09 06:33:19.000000042 | ts.getTime(): 1099999999000 | ts.getNanos(): 42 (Note that JDK 1.3 yields a different result. Not shown here.) With libgcj, I get: | $ gij TStampTest | 333 milliseconds: | ts: 2004-11-09 06:33:19.0 | ts.getTime(): 1099999999333 | ts.getNanos(): 0 | 42 nanoseconds | ts: 2004-11-09 06:33:19.42 | ts.getTime(): 1099999999333 | ts.getNanos(): 42 The above is for http://savannah.gnu.org/cgi-bin/viewcvs/gcc/gcc/libjava/java/sql/Timestamp.java?rev=1.9 As a philosophical aside, part of the problem is that Timestamp is a mess from the API perspective, and always has been. Note that Sun's Javadoc admits the following: http://java.sun.com/j2se/1.3/docs/api/java/sql/Timestamp.html http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Timestamp.html Due to the differences between the Timestamp class and the java.util.Date class mentioned above, it is recommended that code not view Timestamp values generically as an instance of java.util.Date. The inheritance relationship between Timestamp and java.util.Date really denotes implementation inheritance, and not type inheritance.
Confirmed.
Subject: Bug 16574 CVSROOT: /cvs/gcc Module name: gcc Changes by: bryce@gcc.gnu.org 2004-07-15 22:14:45 Modified files: libjava : ChangeLog libjava/java/sql: Timestamp.java Log message: 2004-07-15 Bryce McKinlay <mckinlay@redhat.com> PR libgcj/16574 * java/sql/Timestamp.java (dateFormat): Renamed from sdf. (decimalFormat): New static variable. (sbuf): Likewise. (getTime): New. Override Date.getTime(). (toString): Synchronize. Use decimalFormat to format nanos value correctly. Truncate extra zeros. (before): Compare getNanos() only if getTime() is equal. (after): Likewise. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/ChangeLog.diff?cvsroot=gcc&r1=1.2935&r2=1.2936 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/java/sql/Timestamp.java.diff?cvsroot=gcc&r1=1.9&r2=1.10
Fix checked in to HEAD.