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 p
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.
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 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));
If you use jodaTime, the setCopy("0") method returns a DateTime object with milliseconds set to 0 to make it easy to compare:
DateTime dateTimeZerodMillis = new DateTime().millisOfSecond ().setCopy("0")