Comparing dates ignoring milliseconds?

Is there a way to compare two calendar objects, but ignore milliseconds?

I wrote a test case that compared two calendar objects, but there is a problem. Although all day, month, minutes, and hours are the same, milliseconds are not the same. 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()); 
+8
source share
10 answers

Removing milliseconds from your calendar

 cal.set(Calendar.MILLISECOND, 0); 
+15
source

You need to use

 cal.set(Calendar.MILLISECOND, 0); 

and possibly also

 cal.set(Calendar.SECOND, 0); 

if you only need minutes to fit.

+3
source

The decision to set milliseconds to 0 has a problem: 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 find a difference that you do not want.

I thought of 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, this is not a good solution, as this comparator violates the following rule:

The developer must ensure that x.compareTo (y) == 0 means that sgn (x.compareTo (z)) == sgn (y.compareTo (z)) for all z.

Which leads to (x=y and y=z) => x=z .

So, I see no solution ... But really, if you define several different dates, they are different, right?

+3
source

IMHO the easiest way is to use truncate () from Apache Commons DateUtils ( Apache Commons DateUtils ) to remove milliseconds and compare received dates.

+2
source

One option is to call Calendar.set (Calendar.MILLISECOND, 0) to clear the milliseconds. Another is calling getTimeInMillis () to get the time in milliseconds for both calendars. You can then divide them by 1000 before comparing them to removing milliseconds.

+1
source

If you use Java 8, you can use the Java Time API, specifically Calendar::toInstant() , and then Instant::truncatedTo() . Specify truncation granularity using the 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)); 
+1
source

I would recommend using Joda Time if you are doing anything other than basic date manipulations. In your case, you can trim the dates like this and then compare:

 DateTime dateTime = new DateTime().millisOfDay().roundFloorCopy(); 
0
source
 clearMilis(date1).compareTo(clearMilis(date2)) /** * @param date date * * @return truncated miliseconds */ @Nonnull public static Date clearMillis(final @Nonnull Date date) { DateTime result = new DateTime(date); return result.minusMillis(result.getMillisOfSecond()).toDate(); } 
0
source
 public static String getFromatDateTime(Date date) { SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S"); final GregorianCalendar gc = new GregorianCalendar(); gc.setTime( date ); //gc.set( Calendar.HOUR_OF_DAY, 0 ); //gc.set( Calendar.MINUTE, 0 ); //gc.set( Calendar.SECOND, 0 ); //block ignore millisecond gc.set( Calendar.MILLISECOND, 0 ); String strDate = sdfDate.format(gc.getTime()); return strDate; } public static void main(String[] args) throws ParseException { SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S"); Date now = new Date(); String currentDate = Testing.getFromatDateTime(now); String fullDate = "2015-12-07 14:53:39.30"; String effDateStr = Testing.getFromatDateTime(sdfDate.parse(fullDate)); System.out.println("Currennt Date: " + currentDate); System.out.println("Effective Date: " + effDateStr); System.out.println(currentDate.compareTo(effDateStr)==0); } 
0
source

If you use jodaTime, the setCopy ("0") method returns a DateTime object with milliseconds set to 0 to simplify the comparison:

 DateTime dateTimeZerodMillis = new DateTime().millisOfSecond ().setCopy("0") 
0
source

All Articles