Is there a way to compare two calendar objects, but ignore milliseconds?
I have written a test case that compared two calendar objects, but there is a problem. Although all of the day, month, minutes and hours match, the milliseconds doesn't matches. I get the expected date before getting the real date:
/**
* @return
*/
private Calendar getExpectedOneMonthDateFromCurrentDate() {
Calendar expectedOneMonth = Calendar.getInstance();
expectedOneMonth.add(Calendar.MONTH, -1);
return expectedOneMonth;
}
assertEquals(getExpectedOneMonthDateFromCurrentDate(),
DateRange.LAST_ONE_MONTH.getToDate());
For comparing the two dates, we have used the compareTo() method. If both dates are equal it prints Both dates are equal. If date1 is greater than date2, it prints Date 1 comes after Date 2. If date1 is smaller than date2, it prints Date 1 comes after Date 2.
The DateTime. Compare() method in C# is used for comparison of two DateTime instances. It returns an integer value, <0 − If date1 is earlier than date2.
Compare() Method in C# This method is used to compare two instances of DateTime and returns an integer that indicates whether the first instance is earlier than, the same as, or later than the second instance. Syntax: public static int Compare (DateTime t1, DateTime t2);
Remove milliseconds from your calendar
cal.set(Calendar.MILLISECOND, 0);
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.
The solution of setting the milliseconds to 0 has an issue: if the dates are 12:14:29.999 and 12:14:30.003, you will set the dates to 12:14:29 and 12:14:30 respectively and will detect a difference where you don't want to.
I have thought about a Comparator:
private static class SecondsComparator implements Comparator<Calendar>
{
public int compare(Calendar o1, Calendar o2)
{
final long difference = o1.getTimeInMillis() - o2.getTimeInMillis();
if (difference > -1000 && difference < 1000)
return 0;
else
return difference < 0 ? 1 : -1;
}
}
public static void main(String args[])
{
Calendar c1 = Calendar.getInstance();
Utils.waitMilliseconds(100);
Calendar c2 = Calendar.getInstance();
// will return 0
System.out.println(new SecondsComparator().compare(c1,c2));
}
However, it no a good solution neither, as this Comparator breaks the following rule:
The implementer must ensure that x.compareTo(y)==0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.
What leads to (x=y and y=z) => x=z
.
So I don't see any solution... But indeed, if you define some different dates, they are different, aren't they?
IMHO the easiest way is to use truncate() from Apache Commons DateUtils (Apache Commons DateUtils) to remove the milliseconds and compare the resulting dates.
If you are on Java 8, you can use the Java Time API, specifically Calendar::toInstant()
, followed by Instant::truncatedTo()
. Specify the granularity of truncation using ChronoUnit
enum.
myCalendar.toInstant().truncatedTo( ChronoUnit.SECONDS ) // Lop off any fractional second.
Example.
Calendar oneMonthIsh = Calendar.getInstance();
oneMonthIsh.add(Calendar.MONTH, -1);
oneMonthIsh.add(Calendar.MINUTE, 1);
assertNotEquals(oneMonthIsh.toInstant(), getExpectedOneMonthDateFromCurrentDate());
assertEquals(oneMonthIsh.toInstant().truncatedTo(ChronoUnit.DAYS),getExpectedOneMonthDateFromCurrentDate().toInstant()
.truncatedTo(ChronoUnit.DAYS));
One option is to call Calendar.set(Calendar.MILLISECOND, 0) to clear the milliseconds. Another is call getTimeInMillis() to get the time in milliseconds for both calendars. You could then divide these by 1000 before comparing to remove the milliseconds.
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