比较忽略毫秒的日期?

时间:2012-08-07 10:58:55

标签: java datetime calendar

有没有办法比较两个日历对象,但忽略毫秒?

我编写了一个比较两个日历对象的测试用例,但是存在问题。虽然所有日,月,分和小时都匹配,但毫秒不匹配。我在获得真实日期之前得到预期日期:

/**
 * @return
 */
private Calendar getExpectedOneMonthDateFromCurrentDate() {
    Calendar expectedOneMonth = Calendar.getInstance();
    expectedOneMonth.add(Calendar.MONTH, -1);
    return expectedOneMonth;
}

assertEquals(getExpectedOneMonthDateFromCurrentDate(),
             DateRange.LAST_ONE_MONTH.getToDate());

10 个答案:

答案 0 :(得分:15)

从日历中删除毫秒

cal.set(Calendar.MILLISECOND, 0);

答案 1 :(得分:3)

您需要使用

cal.set(Calendar.MILLISECOND, 0);

也可能

cal.set(Calendar.SECOND, 0);

如果你只需要分钟来匹配。

答案 2 :(得分:3)

将毫秒设置为0的解决方案有一个问题:如果日期为12:14:29.999和12:14:30.003,则将日期分别设置为12:14:29和12:14:30将检测到您不想要的差异。

我考虑过比较器:

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));
}

然而,这也不是一个好的解决方案,因为这个比较器打破了以下规则:

实现者必须确保x.compareTo(y)== 0表示对于所有z,sgn(x.compareTo(z))== sgn(y.compareTo(z))。

导致(x=y and y=z) => x=z

的原因

所以我没有看到任何解决方案......但实际上,如果你定义了一些不同的日期,它们 是不同的,不是吗?

答案 3 :(得分:2)

IMHO最简单的方法是使用Apache Commons DateUtils(Apache Commons DateUtils)中的truncate()来删除毫秒并比较结果日期。

答案 4 :(得分:2)

如果您使用的是Java 8,则可以使用Java Time API,特别是Calendar::toInstant(),然后使用Instant::truncatedTo()。使用ChronoUnit枚举指定截断的粒度。

myCalendar.toInstant().truncatedTo( ChronoUnit.SECONDS )  // Lop off any fractional second.

示例。

    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));

答案 5 :(得分:1)

一个选项是调用Calendar.set(Calendar.MILLISECOND,0)来清除毫秒。另一个是调用getTimeInMillis()来获取两个日历的时间(以毫秒为单位)。然后,您可以在比较之前将它们除以1000,然后删除毫秒。

答案 6 :(得分:0)

如果您在基本日期操作旁边执行任何操作,我建议您使用Joda Time。在您的情况下,您可以截断日期,然后比较:

DateTime dateTime = new DateTime().millisOfDay().roundFloorCopy();

答案 7 :(得分:0)

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();
}

答案 8 :(得分:0)

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);
}

答案 9 :(得分:0)

如果使用jodaTime,setCopy(“0”)方法返回一个DateTime对象,其毫秒设置为0,以便于比较:

DT_JMPREL