This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I as described in another post, I have two string objects. The original that I create and supposedly identical date that is returned from hibernate.
When I use java.util.Calendar to extract that year, month, day, hour, minute second, millisecond, ZONE_OFFSET, DST_OFFSET, AM_PM and HOUR (which is apparently different from hour) from each date object, these corresponding values are all equal. When I call java.util.Date.equals, this returns false. What other fields could be different that is causing java.util.Date.equals to return false?
As I suggested in that other thread, it could be that the classes of the two objects are different. Objects of two different classes will almost never be equal according to the equals() method of either object.
(Disclaimer: I have not looked at that other thread since I posted in it. However I think it's your responsibility to combine the answers when you start a new thread like this.)
This may return null, simply because the two constructors did not execute at exactly the same time. Or it may return true, because the execution times were close enough that they rounded to the same time in milliseconds. (A few years ago, most systems I worked on usually rounded to the nearest multiple of 10 milliseconds. I don't know how common that is now.)
Alberto Pareja-Lecaros wrote:If you want to compare the dates themselves, you have to check if the hour is the same, and the year is the same, and the second is the same, etc.
No. Just call equals(). A java.util.Date really has only one field, a long value equal to the number of milliseconds since the beginning of Jan 1, 1970, GMT. As Rob just showed. That's all that should need to be compared.
Alberto Pareja-Lecaros wrote:Otherwise get the milliseconds elapsed of each object and compare those values.
Exactly. So why waste time with the other field?
As Paul C said several times, the specific classes of the Date objects may be different. Often a database will return its own custom subclass of Date, which may not correctly obey the API set forth in java.util.Date.equals(). Or, another common situation is that one of your Date objects may have had its value rounded off at some point. For example, our Oracle system usually rounds dates to the nearest second. (Or truncates them; I forget.) I think that's standard behavior unless you declare the column as TIMESTAMP. So when you retrieve a value from the DB, the last three digits of getTime() are 000. If you want to compare dates that have been thus rounded, you can do some simple math to round both times accordingly.
Siegfried: I would suggest, next time you have two dates that you think shoudl be equal, but they're not: first use getClass() to identify what class each Date really is. Then print the value of getTime() for each date. You may well see that one or more millisecond values have been rounded off. Based on what you observe, you can round off both millisecond values, before comparing them.
Joined: Aug 11, 2000
On lines 88 and 90, why are not the dates d2 and d4 equal?
I get the green bar on these two tests. I don't understand why. For some reason, when I explicitly set all the fields in cal1, I get strange values.
Joined: Mar 05, 2008
Siegfried Heintze wrote:On lines 88 and 90, why are not the dates d2 and d4 equal?
I get the green bar on these two tests.
I don't understand. Lines 88 and 90 assert that the dates are equal. And you say you get a green bar for both tests. For most of us, a green bar means that the tests passed, and all assertions were true. So, why are you saying d2 and d4 are not equal? Did the tests pass, or not? Were you running some other code, different than what you've shown?
Can you print out the values of both cal1 and cal2? Calendar's toString() method prints out info on each separate field, and you can see exactly what value each field has.
You may find the issue to be in the hour. You set the hour of cal1 to 15 first. Then you copy that to cal2. Then you set the hour of cal1 to 10 PM. Of course d2 and d4 are not going to be the same.
Joined: Aug 11, 2000
Mike: I'm expecting d2 and d4 to be equal and they are not as you can see.
Thanks Rob. I think that specifying the timezone in the java.util.calendar.getinstance fixed that problem above. I think I am now having a different problem. The UT (unit tests) pass for about an hour and then the test bellow starts failing. Sounds like a time zone problem to me! What do you think?
Please scoll all the way down to the bottom of the last listing and examine line 35. It keeps failing here (after an hour) because the values for variable "h" keep changing! Its driving me nuts!
Here is my Make Gregorian class I use to insert and extract parameters into/outof java.util.dates. I'm setting as many of the fields as I know how.
Here is my main test class
Joined: Aug 11, 2000
I wonder if I have it working now!
Previously, in desperation, I printed out a bunch of fields and then defined the values as constants and started setting them as exemplified on line 89. If I comment out line 89 it passes.
Hmmm.... Well daylight savings time does not end until late october and I got the value of the offset from printing it out. Now when I print it out it is zero.
So I if I am setting the locale and timezone in the constructor, is it redundant to specify them on line 90? Should I comment out line 91 too? I guess so since I am using the 24 hour notation instead of AM/PM. But I'm setting HOUR_OF_DAY, now HOUR so why does it matter that am setting AM_PM? Well it does. Is this a bug?