I'm trying to check if a selected dates range by the user is within a range of dates exist in database.
e.g.
User select :
Start date : 24/09/2022
End date : 30/09/2022
Date range in database is :
Start date : 28/09/2022
End date : 30/09/2022
Imagine you have a reservation car between 28/09 → 30/09, if a user wants to reserve this car between 24/09 --> 30/09, then the app should notify them that the car is reserved in that date because it's already reserved between 28--> 30.
My situation is similar to this: Check if a date range is within a date range. Only that question is about C#, and I am coding Java.
My code so far :
boolean isFound = DateHelper.isWithinRange2Dates(
/*ENTERED BY USER*/
string2Date("24/09/2022"),
string2Date("30/09/2022"),
/*IN DATABASE*/
string2Date("28/09/2022"),
string2Date("30/09/2022"));
ToastUtils.showLong(isFound ? "FOUND" : "NOT FOUND");
Methods used :
public static boolean isWithinRange(Date selectedDate, Date startDate, Date endDate) {
return selectedDate.after(startDate) && (selectedDate.before(endDate) || DateUtils.isSameDay(selectedDate, endDate));
}
public static boolean isWithinRange2Dates(Date selectedStartDate, Date selectedEndDate, Date startDate, Date endDate) {
return isWithinRange(selectedStartDate, startDate, endDate) && isWithinRange(selectedEndDate, startDate, endDate);
}
@SuppressLint("SimpleDateFormat")
public static Date string2Date(String dateStr) {
try {
return new SimpleDateFormat("dd/MM/yyyy").parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
Issue:
28/09 --> 30/09 is within the 24/09 --> 30/09 so the method should true
Question:
How I can check if a selected start and end date are within a date range or not?
CodePudding user response:
tl;dr
org.threeten.extra.LocalDateRange.of
(
LocalDate.of( … ) ,
LocalDate.of( … )
)
.encloses
(
LocalDateRange.of
(
startJavaSqlDate.toLocalDate() ,
stopJavaSqlDate.toLocalDate()
)
)
Avoid legacy date-time classes
You are using terrible date-time classes that were years ago supplanted by the modern java.time classes defined in JSR 310.
One of the many design flaws in the Date
class is that there are actually two Date
classes:
java.util.Date
java.sql.Date
The first represents a moment as seen in UTC. The second pretends to represent a date-only, without a time-of-day and without an offset or time zone. But actually, in a case of extremely poor judgement, the second class extends from the first… so it does indeed internally represent a moment in UTC. Messy? Yes, a terrible mess.
LocalDate
You neglect to mention in your Question which class you are using. So I'll go with the second one, java.sql.Date
.
When handed a java.sql.Date
object, immediately convert to the modern replacement: LocalDate
. Do so by calling the new conversion method added to the old class.
LocalDate ld = myJavaSqlDate.toLocalDate() ;
LocalDateRange
To compare date ranges, you could write the code yourself. But why bother? Add the ThreeTen-Extra library to your project. Doing so gives you access to the LocalDateRange
class. That class provides several handy methods such as contains
, abuts
, encloses
, etc.
LocalDateRange target =
LocalDateRange.of(
LocalDate.of( … ) ,
LocalDate.of( … )
)
;
… and:
LocalDateRange selected =
LocalDateRange.of(
startJavaSqlDate.toLocalDate() ,
stopJavaSqlDate.toLocalDate()
)
;
Compare.
boolean enclosed = target.encloses( selected ) ;
CodePudding user response:
Your isWithin range functions operator Precedence is wrong.Also checking isSameDate for both end and start dates are missing. In your code it return false if user startDate is simmilar to your dateRange start date or if user end date simmilar to datarange end date. Correct implementation as follows of isWithinRange function.
return (selectedDate.after(startDate) || DateUtils.isSameDay(selectedDate, startDate)) && (selectedDate.before(endDate) || DateUtils.isSameDay(selectedDate, endDate));
Use || operator not && for isWithinRange2Dates function as follows.
return isWithinRange(selectedStartDate, startDate, endDate) || isWithinRange(selectedEndDate, startDate, endDate);