Reputation: 5102
I have a TreeMap of <DDate, Integer>
.
DDate just contains month and year (month is 0 indexed, like in Java, JAN = 0);
My compare is not returning the right thing:
@Override
public int compareTo(DDDate o) {
Calendar cal1 = Calendar.getInstance();
cal1.setTimeZone(TimeZone.getTimeZone("UTC"));
cal1.set(year, month, 1); // year is 2012, month is 1
Calendar cal2 = Calendar.getInstance();
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
cal2.set(o.getYear(), o.getMonth(), 1); // year is 2012, month is 1
Log.log("COMPARING: " + format.format(cal1.getTime())); // COMPARING: 20120101
Log.log("COMPARING: " + format.format(cal2.getTime())); // COMPARING: 20120101
Log.log((cal1.getTime().getTime())); // 1325413927678
Log.log((cal2.getTime().getTime())); // 1325413927679
Log.log("WILL RETURN: " + cal1.getTime().compareTo(cal2.getTime())); // WILL RETURN: -1
return cal1.getTime().compareTo(cal2.getTime());
}
Why is there descrepancy in the two Calendar objects for the same Date? (1325413927678 vs 1325413927679)
Thank you!
FYI: this method works for a while, and then at a certain point, stops working.
P.S. - I understand this is overkill, I can have a simpler compareTo, but please humor me.
EDIT- FIX
Use JodaTime's LocalDate.
Or do this:
Calendar cal1 = Calendar.getInstance();
cal1.setTimeZone(TimeZone.getTimeZone("UTC"));
cal1.clear();
cal1.set(year, month, 1); // year is 2012, month is 1
Upvotes: 0
Views: 889
Reputation: 338181
Jon Skeet's answer is correct.
Here is some example code showing how to use Joda-Time to do a comparison of dates. Much easier in Joda-Time rather than Java’s bundled Date/Calendar classes. Takes only 3 lines of code to both instantiate and compare.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// Joda-Time - The popular alternative to Sun/Oracle's notoriously bad date, time, and calendar classes bundled with Java 7 and earlier.
// http://www.joda.org/joda-time/
// Joda-Time will become outmoded by the JSR 310 Date and Time API introduced in Java 8.
// JSR 310 was inspired by Joda-Time but is not directly based on it.
// http://jcp.org/en/jsr/detail?id=310
// By default, Joda-Time produces strings in the standard ISO 8601 format.
// https://en.wikipedia.org/wiki/ISO_8601
// New DateTime instance with default time zone. For specific zone, call "withZone()" method.
org.joda.time.DateTime dateTimeX = new org.joda.time.DateTime();
org.joda.time.DateTime dateTimeY = new org.joda.time.DateTime(2012, 1, 1, 0, 0); // First of January.
// To compare the date only while ignoring the time, set identical time component on both.
// Call withTimeAtStartOfDay() to set same time value.
Boolean isSameDate = dateTimeX.withTimeAtStartOfDay().isEqual(dateTimeY.withTimeAtStartOfDay());
Upvotes: 0
Reputation: 76
Try using the clear() method before setting the date:
final Calendar cal1 = Calendar.getInstance();
cal1.clear();
cal1.setTimeZone(TimeZone.getTimeZone("UTC"));
cal1.set(2012, 1, 1); // year is 2012, month is 1
final Calendar cal2 = Calendar.getInstance();
cal2.clear();
cal2.setTimeZone(TimeZone.getTimeZone("UTC"));
cal2.set(2012, 1, 1); // year is 2012, month is 1
cal1.getTime().compareTo(cal2.getTime()); // Returns 0
Upvotes: 0
Reputation: 4602
You should initialize the calendar properly to "no time" (0 ticks), this should fix the issue.
cal1.setTime(new Date(0));
cal1.set(year, month, 1);
Upvotes: 0
Reputation: 6476
Because you are making them at two different times.
Calendar cal1 = Calendar.getInstance(); // time now
cal1.setTimeZone(TimeZone.getTimeZone("UTC")); // time ticking
cal1.set(year, month, 1); // year is 2012, month is 1 // time ticking
Calendar cal2 = Calendar.getInstance(); // time two ticks later
You have changed the day and month and year, however the hour minutes and seconds stayed and keep on moving and chaning.
As mentioned here
http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#set(int, int, int, int, int)
The other field values are retained and you should use clear() to set them to zero. Additionally as Jon recomended I would say use Joda time it is much better.
Upvotes: 2
Reputation: 1499800
You're setting the year, month and day - but that doesn't change the time of day. The internal clock must have ticked between the two calls to Calendar.getInstance
, so they have different "milliseconds since the Unix epoch" values.
Personally I'd recommend using Joda Time instead of java.util.Calendar
and java.util.Date
- that way you can represent what you're actually interested in, such as LocalDate
.
Upvotes: 6