I have a series of ranges with start dates and end dates. I want to check to see if a date is within that range.
Date.before() and Date.after() seem to be a little a
public class TestDate {
public static void main(String[] args) {
// TODO Auto-generated method stub
String fromDate = "18-FEB-2018";
String toDate = "20-FEB-2018";
String requestDate = "19/02/2018";
System.out.println(checkBetween(requestDate,fromDate, toDate));
}
public static boolean checkBetween(String dateToCheck, String startDate, String endDate) {
boolean res = false;
SimpleDateFormat fmt1 = new SimpleDateFormat("dd-MMM-yyyy"); //22-05-2013
SimpleDateFormat fmt2 = new SimpleDateFormat("dd/MM/yyyy"); //22-05-2013
try {
Date requestDate = fmt2.parse(dateToCheck);
Date fromDate = fmt1.parse(startDate);
Date toDate = fmt1.parse(endDate);
res = requestDate.compareTo(fromDate) >= 0 && requestDate.compareTo(toDate) <=0;
}catch(ParseException pex){
pex.printStackTrace();
}
return res;
}
}
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.
For covering my case -> I've got a range start & end date, and dates list that can be as partly in provided range, as fully (overlapping).
Solution covered with tests:
/**
* Check has any of quote work days in provided range.
*
* @param startDate inclusively
* @param endDate inclusively
*
* @return true if any in provided range inclusively
*/
public boolean hasAnyWorkdaysInRange(LocalDate startDate, LocalDate endDate) {
if (CollectionUtils.isEmpty(workdays)) {
return false;
}
LocalDate firstWorkDay = getFirstWorkDay().getDate();
LocalDate lastWorkDay = getLastWorkDay().getDate();
return (firstWorkDay.isBefore(endDate) || firstWorkDay.equals(endDate))
&& (lastWorkDay.isAfter(startDate) || lastWorkDay.equals(startDate));
}
That's the correct way. Calendars work the same way. The best I could offer you (based on your example) is this:
boolean isWithinRange(Date testDate) {
return testDate.getTime() >= startDate.getTime() &&
testDate.getTime() <= endDate.getTime();
}
Date.getTime() returns the number of milliseconds since 1/1/1970 00:00:00 GMT, and is a long so it's easily comparable.
This was clearer to me,
// declare calendar outside the scope of isWithinRange() so that we initialize it only once
private Calendar calendar = Calendar.getInstance();
public boolean isWithinRange(Date date, Date startDate, Date endDate) {
calendar.setTime(startDate);
int startDayOfYear = calendar.get(Calendar.DAY_OF_YEAR); // first day is 1, last day is 365
int startYear = calendar.get(Calendar.YEAR);
calendar.setTime(endDate);
int endDayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
int endYear = calendar.get(Calendar.YEAR);
calendar.setTime(date);
int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
int year = calendar.get(Calendar.YEAR);
return (year > startYear && year < endYear) // year is within the range
|| (year == startYear && dayOfYear >= startDayOfYear) // year is same as start year, check day as well
|| (year == endYear && dayOfYear < endDayOfYear); // year is same as end year, check day as well
}
An easy way is to convert the dates into milliseconds after January 1, 1970 (use Date.getTime()) and then compare these values.