Compare Date objects with different levels of precision

前端 未结 19 1984
日久生厌
日久生厌 2020-12-08 13:01

I have a JUnit test that fails because the milliseconds are different. In this case I don\'t care about the milliseconds. How can I change the precision of the assert to i

相关标签:
19条回答
  • 2020-12-08 13:18

    You could do something like this:

    assertTrue((date1.getTime()/1000) == (date2.getTime()/1000));
    

    No String comparisons needed.

    0 讨论(0)
  • 2020-12-08 13:18

    If you were using Joda you could use Fest Joda Time.

    0 讨论(0)
  • 2020-12-08 13:21

    Just compare the date parts you're interested in comparing:

    Date dateOne = new Date();
    dateOne.setTime(61202516585000L);
    Date dateTwo = new Date();
    dateTwo.setTime(61202516585123L);
    
    assertEquals(dateOne.getMonth(), dateTwo.getMonth());
    assertEquals(dateOne.getDate(), dateTwo.getDate());
    assertEquals(dateOne.getYear(), dateTwo.getYear());
    
    // alternative to testing with deprecated methods in Date class
    Calendar calOne = Calendar.getInstance();
    Calendar calTwo = Calendar.getInstance();
    calOne.setTime(dateOne);
    calTwo.setTime(dateTwo);
    
    assertEquals(calOne.get(Calendar.MONTH), calTwo.get(Calendar.MONTH));
    assertEquals(calOne.get(Calendar.DATE), calTwo.get(Calendar.DATE));
    assertEquals(calOne.get(Calendar.YEAR), calTwo.get(Calendar.YEAR));
    
    0 讨论(0)
  • 2020-12-08 13:23

    This is actually a harder problem than it appears because of the boundary cases where the variance that you don't care about crosses a threshold for a value you are checking. e.g. the millisecond difference is less than a second but the two timestamps cross the second threshold, or the minute threshold, or the hour threshold. This makes any DateFormat approach inherently error-prone.

    Instead, I would suggest comparing the actual millisecond timestamps and provide a variance delta indicating what you consider an acceptable difference between the two date objects. An overly verbose example follows:

    public static void assertDateSimilar(Date expected, Date actual, long allowableVariance)
    {
        long variance = Math.abs(allowableVariance);
    
        long millis = expected.getTime();
        long lowerBound = millis - allowableVariance;
        long upperBound = millis + allowableVariance;
    
        DateFormat df = DateFormat.getDateTimeInstance();
    
        boolean within = lowerBound <= actual.getTime() && actual.getTime() <= upperBound;
        assertTrue(MessageFormat.format("Expected {0} with variance of {1} but received {2}", df.format(expected), allowableVariance, df.format(actual)), within);
    }
    
    0 讨论(0)
  • 2020-12-08 13:26

    You can chose which precision level you want when comparing dates, e.g.:

    LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS);
    // e.g. in MySQL db "timestamp" is without fractional seconds precision (just up to seconds precision)
    assertEquals(myTimestamp, now);
    
    0 讨论(0)
  • 2020-12-08 13:26

    i cast the objects to java.util.Date and compare

    assertEquals((Date)timestamp1,(Date)timestamp2);
    
    0 讨论(0)
提交回复
热议问题