Home > Software design >  How to check if a selected date range is within a date range
How to check if a selected date range is within a date range

Time:09-27

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);
        
  • Related