I need to find the number of days between two dates: one is from a report and one is the current date. My snippet:
int age=calculateDiffer
Based on @Mad_Troll's answer, I developed this method.
I've run about 30 test cases against it, is the only method that handles sub day time fragments correctly.
Example: If you pass now & now + 1 millisecond that is still the same day.
Doing 1-1-13 23:59:59.098
to 1-1-13 23:59:59.099
returns 0 days, correctly; allot of the other methods posted here will not do this correctly.
Worth noting it does not care about which way you put them in, If your end date is before your start date it will count backwards.
/**
* 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;
}
You can remove the @NotNull
annotations, these are used by Intellij to do code analysis on the fly