Основываясь на ответе @ Mad_Troll, я разработал этот метод.
Я провел около 30 тестов для проверки, это единственный метод, который правильно обрабатывает фрагменты дневного времени.
Пример: Если вы пройдете сейчас и сейчас + 1 миллисекунду, это все тот же день.Выполнение 1-1-13 23:59:59.098
до 1-1-13 23:59:59.099
возвращает 0 дней, правильно;другие методы, опубликованные здесь, не будут делать это правильно.
Стоит отметить, что не важно, каким образом вы их вводите. Если ваша дата окончания предшествует дате начала, она будет отсчитываться в обратном направлении.
/**
* This is not quick but if only doing a few days backwards/forwards then it is very accurate.
*
* @param startDate from
* @param endDate to
* @return day count between the two dates, this can be negative if startDate is after endDate
*/
public static long daysBetween(@NotNull final Calendar startDate, @NotNull final Calendar endDate) {
//Forwards or backwards?
final boolean forward = startDate.before(endDate);
// Which direction are we going
final int multiplier = forward ? 1 : -1;
// The date we are going to move.
final Calendar date = (Calendar) startDate.clone();
// Result
long daysBetween = 0;
// Start at millis (then bump up until we go back a day)
int fieldAccuracy = 4;
int field;
int dayBefore, dayAfter;
while (forward && date.before(endDate) || !forward && endDate.before(date)) {
// We start moving slowly if no change then we decrease accuracy.
switch (fieldAccuracy) {
case 4:
field = Calendar.MILLISECOND;
break;
case 3:
field = Calendar.SECOND;
break;
case 2:
field = Calendar.MINUTE;
break;
case 1:
field = Calendar.HOUR_OF_DAY;
break;
default:
case 0:
field = Calendar.DAY_OF_MONTH;
break;
}
// Get the day before we move the time, Change, then get the day after.
dayBefore = date.get(Calendar.DAY_OF_MONTH);
date.add(field, multiplier);
dayAfter = date.get(Calendar.DAY_OF_MONTH);
// This shifts lining up the dates, one field at a time.
if (dayBefore == dayAfter && date.get(field) == endDate.get(field))
fieldAccuracy--;
// If day has changed after moving at any accuracy level we bump the day counter.
if (dayBefore != dayAfter) {
daysBetween += multiplier;
}
}
return daysBetween;
}
Вы можете удалить аннотации @NotNull
, которые используются Intellij для анализа кода на лету