0

I have two calendar objects, they seems to contain same dates but the compareTo() method is returning -1 as result, Can any one explain the reason behind this.

On debugging the two Calendar objects, the result is shown as :

2014-06-01T00:00:00.000Z

for both calendar objects but the compareTo() is returning -1. Even the long time in millis for both dates are different.

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
Hitesh
  • 703
  • 1
  • 9
  • 14

4 Answers4

3

Well, have a look at the Calendar code (this is from JDK 1.7.0-13):

public int compareTo(Calendar anotherCalendar) {
    return compareTo(getMillisOf(anotherCalendar));
}

private int compareTo(long t) {
    long thisTime = getMillisOf(this);
    return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1;
}

It should be obvious that if the two Calendar's have different millis, then they're different as per the second method.

In any case, the millis in your example should not both represent 2014-06-01T00:00:00.000Z so there's another problem in your code. Try this:

Timestamp ts1 = new Timestamp( 1401561000000L );
Timestamp ts2 = new Timestamp( 1401595200000L );
System.err.println( ts1 );
System.err.println( ts2 );

Outputs:

2014-05-31 20:30:00.0
2014-06-01 06:00:00.0

Cheers,

Anders R. Bystrup
  • 15,729
  • 10
  • 59
  • 55
1

If you want to just compare the minutes and ignore the milliseconds or seconds do this:

You need to use

cal.set(Calendar.MILLISECOND, 0);

and possibly as well

cal.set(Calendar.SECOND, 0);

if you just need the minutes to match.


Quick explanation of what is going on:

The JavaDoc for Calendar states:

Compares the time values (millisecond offsets from the Epoch) represented by two Calendar objects.

So you acknowledge that ".. long time in millis for both dates are different .."

@JonSkeet says in this question:

Calendar.setTime takes a java.util.Date, which is just a wrapper around a long indicating the number of milliseconds since midnight Jan 1st 1970, UTC. It's not "in the format MM/dd/yyy" - that's a string representation, not a java.util.Date. If it happens to print something out in the format MM/dd/yyyy, that's just what Date.toString is doing for you - it's not inherently part of the format.

This should answer your question about what is going on.

Note: java.util.Date has the same problem.

PS. A lot of people say use Joda Time, which I have heard is going to be in Java 8, but I have not personally tried it. If you are going to be using a lot of date code, I'd recommend you use it.

Engineer2021
  • 3,288
  • 6
  • 29
  • 51
  • Overly underrated answer! I was facing the same issue in unit tests and after setting millisecond to 0, dates came to be equal. Thank you! – Rajesh Surana May 03 '23 at 06:15
0

The milliseconds number is the "offical" time in Java. However, for a variety or reasons, there are numbers with the same date/time which have different numbers of milliseconds. Then normal reason is clock adjustments. E.g. Sometimes you have to add a second or two to account for irregularities in the earth's orbit. The other big source is when regions were first brought into the UTC, then some time zones moved hours.

THere is also the common source for these things: DST. This will happen twice a year when you move to daylight saving time, on the one hand there are date/times which do not exists, as they were "skipped", and there are other times which happened twice, as the clock gets reset at midnight, so 11pm-midnight happens twice on the same day.

phil_20686
  • 4,000
  • 21
  • 38
0

I invoked compareTo on Date instead of Calendar and got the correct result. It might be because of the fact that Calendar stores Timezone information but Date object does not.

Thanks

Hitesh
  • 703
  • 1
  • 9
  • 14