I know java Date was poor designed, but I don't know how until today.
I saved a date to DB and when I get it from DB and compare to original date, it told me it's different!
And I wrote a test which looks strange but it PASSED!
@Test
public void date_equals() {
Date now = new Date();
Timestamp timestamp = new Timestamp(now.getTime());
assertFalse(timestamp.equals(now));
assertTrue(now.equals(timestamp));
assertTrue(timestamp.compareTo(now) == 0);
assertFalse(now.compareTo(timestamp) == 0);
assertTrue(timestamp.getTime() == now.getTime());
assertTrue(now.getTime() == timestamp.getTime());
}
I noticed that java.sql.Timestamp has a little different than Date about nanoseconds which I don't care.
Can anyone told me how to compare this two in best practice? I don't want to compare date use getTime() everywhere, is there any common library or other ways to do this?
BTW I'm using JDK 6
originalInstant.equals(
org.threeten.bp.DateTimeUtils.toInstant( mySqlTimestamp )
)
The old date-time classes bundled with the earliest versions of Java are an awful mess, with poor designs and awkward hacks. One of those bad hacks is making java.sql.Timestamp
a subclass of java.util.Date
while telling you to ignore that fact of inheritance.
To quote the class doc (emphasis mine):
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.
You were told to pretend they are not related classes. So your attempt to compare objects of each type is inappropriate.
The Timestamp
has a resolution up to nanoseconds. The java.util.Date
class is limited to milliseconds. So the two will not compare as equal.
Instead, use the java.time classes. Much of their functionality is available as a back-port to Java 6 – see below.
When you get your Timestamp
, immediately convert to the java.time types. In Java 8 and later you could call the new methods added to those old classes for conversion. In the ThreeTen-Backport library for Java 6 & 7, use org.threeten.bp.DateTimeUtils.toInstant( Timestamp )
An Instant
is a moment on the timeline in UTC with a resolution of nanoseconds.
Instant instant = DateTimeUtils.toInstant( mySqlTimestamp ) ;
Now compare to your original Instant
.
boolean isOriginal = originalInstant.equals( instant ) ;
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
You have Timestamp::compareTo(java.util.Date o)
in java.sql.TimeStamp
class. Use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With