有没有办法比较两个日历对象,但忽略毫秒?
我编写了一个比较两个日历对象的测试用例,但是存在问题。虽然所有日,月,分和小时都匹配,但毫秒不匹配。我在获得真实日期之前得到预期日期:
/**
* @return
*/
private Calendar getExpectedOneMonthDateFromCurrentDate() {
Calendar expectedOneMonth = Calendar.getInstance();
expectedOneMonth.add(Calendar.MONTH, -1);
return expectedOneMonth;
}
assertEquals(getExpectedOneMonthDateFromCurrentDate(),
DateRange.LAST_ONE_MONTH.getToDate());
答案 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