0

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?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • 1
    Inclusive? Are 28–29/9 and 29–30/9 both within 28–30/9? – Ole V.V. Sep 24 '22 at 20:13
  • 2
    I strongly recommend you don’t use `Date`. That class is poorly designed and long outdated. Instead use `LocalDate` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Sep 24 '22 at 20:14
  • Massive thanks for your help guys, @OleV.V. my apologies I didn't include the `string2Date` method – Mouaad Abdelghafour AITALI Sep 24 '22 at 20:22
  • @OleV.V. please check my updated post – Mouaad Abdelghafour AITALI Sep 24 '22 at 20:24
  • Does the below answer worked for you? – YJR Sep 24 '22 at 20:25
  • `java.util.Date` or `java.sql.Date`? – Basil Bourque Sep 24 '22 at 23:59
  • I seem to get from your comments (that I also pasted into your question) that you want to decline the reservation if there is *an overlap* between the two intervals in question. If the car is already reserved 27–29/9 and the user wants to book it 28–30/9, it should be declined, am I right? Is your situation really more similar to this one? [Determine Whether Two Date Ranges Overlap](https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap) – Ole V.V. Sep 25 '22 at 06:26
  • 1
    You are really making it unnecessarily complicated for yourself and for us by using the poorly designed and obsolete `Date` class. Now I get *DateUtils cannot be resolved* at `DateUtils.isSameDay(selectedDate, endDate)`. I was curious to debug your code and discover what went wrong, but I am giving up now. – Ole V.V. Sep 25 '22 at 06:34

2 Answers2

3

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, overlaps, etc.

LocalDateRange target = 
    LocalDateRange.of(
        LocalDate.of( … ) ,
        LocalDate.of( … )
    ) 
;

… and:

LocalDateRange selected = 
    LocalDateRange.of(
        startJavaSqlDate.toLocalDate() ,
        stopJavaSqlDate.toLocalDate()
    ) 
;

Compare.

boolean enclosed = target.encloses( selected ) ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
1

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);
        
YJR
  • 1,099
  • 3
  • 13
  • thank you so much for your answer, but unfortunately, it does not work – Mouaad Abdelghafour AITALI Sep 24 '22 at 20:26
  • 1
    If the user date range and db date range same what should return? – YJR Sep 24 '22 at 20:28
  • now check it should work – YJR Sep 24 '22 at 20:31
  • Thank you so much for your help, the issue here is I need to check if date range **(selectedStartDate-->SelectedEndDate)** is within the **(startDate-->EndDate)** and vice versa for example 28/09 --> 30/09 is within the 24/09 --> 30/09 so the method should return true – Mouaad Abdelghafour AITALI Sep 24 '22 at 20:35
  • 1
    in your code I can see you are adding db date range before selected date range. It not match with your explaination.I confused about it mate. – YJR Sep 24 '22 at 20:47
  • 2
    Imagine you have a reservation car between 28/09 → 30/09, if a user want 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, I hope I made my question clear, and thank you again for your help – Mouaad Abdelghafour AITALI Sep 24 '22 at 20:51
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/248326/discussion-between-yjr-and-mouaad-abdelghafour-aitali). – YJR Sep 24 '22 at 20:53