11

Hello I have a code snippet like this:

Date d1 = new java.sql.Timestamp(new Date().getTime());
Thread.sleep(10);
Date d2 = new java.sql.Timestamp(new Date().getTime());
System.out.println("Date1: " + d1);
System.out.println("Date2: " + d2);
System.out.println("Comparing times d1.t < d2.t: " + (d1.getTime() < d2.getTime()));
System.out.println("Comparing dates d1.before(d2): " + (d1.before(d2)));

The output looks like this:

Date1: 2013-03-26 11:04:01.093
Date2: 2013-03-26 11:04:01.103
Comparing times d1.t < d2.t: true
Comparing dates d1.before(d2): false

What's wrong with this java.sql.Timestamp class?

Yes, I have seen this:

Note: This type is a composite of a java.util.Date and a separate nanoseconds value. Only integral seconds are stored in the java.util.Date component. The fractional seconds - the nanos - are separate. The Timestamp.equals(Object) method never returns true when passed a value of type java.util.Date because the nanos component of a date is unknown. As a result, the Timestamp.equals(Object) method is not symmetric with respect to the java.util.Date.equals(Object) method. Also, the hashcode method uses the underlying java.util.Date implementation and therefore does not include nanos in its computation.

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.

But it's for Date <-> Timestamp relation.

In my example I have Timestamps only, and still the behavior is unexpected..

UPDATE: ANSWER

The reason this happens is that before() method is overloaded, not overriden in java.sql.Timestamp. I was expecting an 'override' behavior. The correct way to compare timestamps is to have Timestamp variables, not Dates.

This is still a poor design decision in the Java core, since inheritance should mean Timestamp is-a Date, with no penalties and exceptions..

1
  • I believe I have found the problem in another post. Please review. The problem is that you are not supposed to treat a TimeStamp as a Date. Commented Mar 26, 2013 at 4:17

4 Answers 4

3

Try to use Timestamp instead of Date and it will work.

Timestamp d1 = new java.sql.Timestamp(new Date().getTime());

Timestamp and Date both have own implementation of method before. Check it.

Sign up to request clarification or add additional context in comments.

Comments

3

Well, it seems as an under-documented feature.

The beforeand after methods of Timestamp seem to be comparing up to the second, but not taking into account the milliseconds part. Try to run it until both TimeStamp fall into distinct seconds and the comparison works as expected (increment the sleep to 500 to make it easier).

By the way, the compareTo method is taking into account the milliseconds, so you could use that instead.

Comments

1

If you call the method Timestamp.before(Timestamp), you'll get the expected result.

But apparently using a Timestamp as a Date will be an all around mess up. You must use Timestamp as Timestamp statically.

Comments

0

As mentioned here

timestamp is a thin wrapper

A timestamp simply adds the ability to hold the SQL TIMESTAMP fractional seconds value(with precision of nanoseconds where the problem in your case is arising)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.