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
How to Ensure Hashcode() Is Consistent with Equals()
Comparing Float/Double Values Using == Operator
Where Is the Javabean Property Naming Convention Defined
How to Change a Jbutton Color on Mouse Pressed
Issues with Swingworker and Jprogressbar
Jtable with Titled Rows and Columns
Java Error - Actual and Formal Argument Lists Differ in Length
Can One Do a for Each Loop in Java in Reverse Order
Adding in Clause List to a JPA Query
Check If a String Contains a Special Character
Java Regex to Extract Text Between Tags
How to Load a Large Xlsx File with Apache Poi
Java Properties Utf-8 Encoding in Eclipse
What Is @Joincolumn and How It Is Used in Hibernate
Does Calling Clone() on an Array Also Clone Its Contents
How Does Java's System.Exit() Work with Try/Catch/Finally Blocks