How to Determine If a Date Is Between Two Dates in Java

How can I determine if a date is between two dates in Java?

If you don't know the order of the min/max values

Date a, b;   // assume these are set to something
Date d; // the date in question

return a.compareTo(d) * d.compareTo(b) > 0;

If you want the range to be inclusive

return a.compareTo(d) * d.compareTo(b) >= 0;

You can treat null as unconstrained with

if (a == null) {
return b == null || d.compareTo(b) < 0;
} else if (b == null) {
return a.compareTo(d) < 0;
} else {
return a.compareTo(d) * d.compareTo(b) > 0;
}

How do I check if a date is within a certain range?

boolean isWithinRange(Date testDate) {
return !(testDate.before(startDate) || testDate.after(endDate));
}

Doesn't seem that awkward to me. Note that I wrote it that way instead of

return testDate.after(startDate) && testDate.before(endDate);

so it would work even if testDate was exactly equal to one of the end cases.

How to check if date is between interval in java?

Just do a quick range check with the calendar:

Note: Make sure to import java.util.GregorianCalendar;

public static boolean isDateInRange(int month, int day,
int monthFrom, int dayFrom,
int monthUntil, int dayUntil) {
int yearRoll = 0;
int currentRoll = 0;
if (monthUntil < monthFrom) yearRoll = -1; // Ensures date is calculated correctly.
if (month >= monthFrom && yearRoll < 0) currentRoll = -1;

GregorianCalendar testDate = new GregorianCalendar(currentRoll, month, day);
GregorianCalendar startDate = new GregorianCalendar(yearRoll, monthFrom, dayFrom);
GregorianCalendar endDate = new GregorianCalendar(0, monthUntil, dayUntil);

// This makes it pass if its between OR EQUAL to the interval.
// Remove if you only want to pass dates explicitly BETWEEN intervals.
if (testDate.compareTo(startDate) == 0 || testDate.compareTo(endDate) == 0) {
return true;
}

return !(testDate.before(startDate) || testDate.after(endDate));
}

This will also take into account the fact that say February is between November and March. Since November is a part of the previous year, it will move the from date back a year to ensure passing.

What it doesn't take into account however, is the fact that February has an extra day on leap-years. To add extra-precision, you need integers for the years. You can do the following:

public static boolean isDateInRange(int year, int month, int day,
int yearFrom, int monthFrom, int dayFrom,
int yearUntil, int monthUntil, int dayUntil) {

GregorianCalendar testDate = new GregorianCalendar(year, month, day);
GregorianCalendar startDate = new GregorianCalendar(yearFrom, monthFrom, dayFrom);
GregorianCalendar endDate = new GregorianCalendar(yearUntil, monthUntil, dayUntil);

return !(testDate.before(startDate) || testDate.after(endDate));
}

And here is an implementation with the date values you gave plus a few more:

public static void main(String[] args) {
System.out.println(isDateInRange(1, 2,
11, 24,
3, 3));
System.out.println(isDateInRange(11, 25,
11, 24,
3, 3));
System.out.println(isDateInRange(1, 2,
1, 1,
3, 3));
System.out.println(isDateInRange(1, 22,
1, 21,
1, 25));
}

And the results are:

true
true
true
true

Will also work with @Marvin's tests.

check given date is between two dates in List

 Date minDate, maxDate;   // assume these are set to something
Date date; // the date in question

return date.after(minDate) && date.before(maxDate);

You can do something like this

    Date a = new Date("21/03/2000");
Date b = new Date("21/03/2006");
Date c = new Date("18/09/2008");

List<Date> dateList = new ArrayList<Date>();

Date date = new Date("18/09/2005");

dateList.add(a);
dateList.add(b);
dateList.add(c);

for (Date minDate : dateList) {
for (Date maxDate : dateList) {
//System.out.println("After " + date.after(minDate));
//System.out.println("Before " + date.before(maxDate));
System.out.println("Date " + date + " is After " + minDate + " and Before " + maxDate + " : " + String.valueOf(date.after(minDate) && date.before(maxDate)));
}
}

Determine Whether Two Date Ranges Overlap

(StartA <= EndB) and (EndA >= StartB)

Proof:

Let ConditionA Mean that DateRange A Completely After DateRange B

_                        |---- DateRange A ------|
|---Date Range B -----| _

(True if StartA > EndB)

Let ConditionB Mean that DateRange A is Completely Before DateRange B

|---- DateRange A -----|                        _ 
_ |---Date Range B ----|

(True if EndA < StartB)

Then Overlap exists if Neither A Nor B is true -

(If one range is neither completely after the other,

nor completely before the other,
then they must overlap.)

Now one of De Morgan's laws says that:

Not (A Or B) <=> Not A And Not B

Which translates to: (StartA <= EndB) and (EndA >= StartB)


NOTE: This includes conditions where the edges overlap exactly. If you wish to exclude that,

change the >= operators to >, and <= to <


NOTE2. Thanks to @Baodad, see this blog, the actual overlap is least of:

{ endA-startA, endA - startB, endB-startA, endB - startB }

(StartA <= EndB) and (EndA >= StartB)
(StartA <= EndB) and (StartB <= EndA)


NOTE3. Thanks to @tomosius, a shorter version reads:

DateRangesOverlap = max(start1, start2) < min(end1, end2)

This is actually a syntactical shortcut for what is a longer implementation, which includes extra checks to verify that the start dates are on or before the endDates. Deriving this from above:

If start and end dates can be out of order, i.e., if it is possible that startA > endA or startB > endB, then you also have to check that they are in order, so that means you have to add two additional validity rules:

(StartA <= EndB) and (StartB <= EndA) and (StartA <= EndA) and (StartB <= EndB)
or:

(StartA <= EndB) and (StartA <= EndA) and (StartB <= EndA) and (StartB <= EndB)
or,

(StartA <= Min(EndA, EndB) and (StartB <= Min(EndA, EndB))
or:

(Max(StartA, StartB) <= Min(EndA, EndB)

But to implement Min() and Max(), you have to code, (using C ternary for terseness),:

((StartA > StartB) ? StartA : StartB) <= ((EndA < EndB) ? EndA : EndB)

Calculating the difference between two Java date instances

The JDK Date API is horribly broken unfortunately. I recommend using Joda Time library.

Joda Time has a concept of time Interval:

Interval interval = new Interval(oldTime, new Instant());

EDIT: By the way, Joda has two concepts: Interval for representing an interval of time between two time instants (represent time between 8am and 10am), and a Duration that represents a length of time without the actual time boundaries (e.g. represent two hours!)

If you only care about time comparisions, most Date implementations (including the JDK one) implements Comparable interface which allows you to use the Comparable.compareTo()



Related Topics



Leave a reply



Submit