Monday, March 15, 2010

Lost Milliseconds using Date and Timestamp

While trouble shooting some date discrepancies in our application, we discovered we were losing milliseconds, when converting from java.sql.Timestamp, to java.util.Date. The following test isolated the problem:

DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");

try {
Date datea = dfm.parse("2009-05-13 11:11:03.113");
Date dateb = dfm.parse("2009-05-13 11:11:03.257 ");

assertTrue(dateb.after(datea));
} catch (Exception e) {

}

Timestamp ts1 = new Timestamp(2010, 3, 15, 9, 9, 9, 111000000);
Timestamp ts2 = new Timestamp(2010, 3, 15, 9, 9, 9, 222000000);
assertTrue(ts2.after(ts1));

Date datea = (Date)ts1;
Date dateb = (Date)ts2;
// NOTE this asserts false because it truncates the milliseconds in the cast.
assertFalse(dateb.after(datea));

I am surprised that Java did not handle this. They could have provided a constructor that would take a java.sql.Timestamp as an argument, so they could preserve the milliseconds. Another solution was they could have kept both the milliseconds field and the nanoseconds field updated, so that the cast could have worked. Either way, hopefully, this saves someone else the time of tracking this down.

No comments: