2

If I have a list of rooms and a specific room called room1 which is booked between 2018-12-12 and 2018-12-20.

And another user wants to book that room between 2018-12-15 and 2018-12-25. I tried to use date.after(checkInDate) and date.after(checkOutDate) but it didn't work. How can it be fixed?

 Date tempStart = checkinDate;
 Date tempEnd = checkoutDate;

 LinkedList<Integer> roomNbrs = new LinkedList<>();

 for (Booking b: books) {

     if (tempStart.equals(b.getCheckinDate()) && tempEnd.equals(b.getCheckoutDate()) && !roomNbrs.contains(roomNbr) ||
                (tempStart.after(b.getCheckinDate())) && ((tempEnd.before(b.getCheckoutDate()) || tempEnd.equals(b.getCheckoutDate()))
                        && !roomNbrs.contains(roomNbr)) ||
                ((tempStart.before(b.getCheckinDate()) || tempStart.equals(b.getCheckinDate()))
                        && tempEnd.before(b.getCheckoutDate()) && !roomNbrs.contains(roomNbr))){

             roomNbrs.add(b.getRoomNbr());
     }
}
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Red Dot
  • 59
  • 8

5 Answers5

2

I managed to fix the problem and here is the solution:

private void viewAvailableRoomDate(Date tempStart, Date tempEnd) {

    LinkedList<Integer> roomNbrs = new LinkedList<>();

    for (Booking b : books) {

        if ((!(tempStart.after(b.getCheckinDate()) && tempEnd.after(b.getCheckinDate())) ||
                (tempStart.before(b.getCheckoutDate()) && tempEnd.after(b.getCheckoutDate())) ||
                (tempStart.before(b.getCheckinDate()) && tempEnd.after(b.getCheckoutDate()))) ||
                (tempStart.after(b.getCheckinDate()) && tempEnd.before(b.getCheckoutDate()))){
            roomNbrs.add(b.getRoomNbr());
        }
    }

}

Red Dot
  • 59
  • 8
  • I don’t think is correct either. At least you’ve got your brackets wrong. It also doesn’t seem to take into account the case when `tempStart` is equal to `b.getCheckinDate()` and/or `tempEnd` is equal to `b.getCheckoutDate()`. – Ole V.V. Dec 08 '18 at 04:17
  • I checked all the possible scenarios and with the help of the solution above, it seems that it is working quite good. Even the scenario that you mentioned is working. @OleV.V. – Red Dot Dec 09 '18 at 09:37
  • I too tested your `if` statement for you. [Link to where it runs online](https://ideone.com/QmaaCz). Not in all cases did it behave the way I thought it should. – Ole V.V. Dec 09 '18 at 10:14
1

the scheduling checkoutDate should before room1.checkinDate or scheduling checkinDate after room1.checkoutDate


rephrase: the new meeting's end date should before the room1's start date, or the new meeting's start date should after the room1's end date.

exudong
  • 366
  • 3
  • 13
1

As far as I can see, your overall logic is flawed. You cannot look at a single booking and determine whether the room of that booking is available for the period wanted (between 2018-12-15 and 2018-12-25).

Imagine:

  • Room 1 is booked between 2018-12-12 and 2018-12-20.
  • Room 2 is booked between 2018-12-20 and 2018-12-30 and again between 2019-01-10 and 2019-01-17.
  • There are no bookings at all for room 3.

Now rooms 1 and 2 are both unavailable for the wanted period, but room 3 available.

When you iterate through your bookings:

  • You look at the booking of room 1, it overlaps with the wanted, so you don’t add 1 to your list.
  • You look at the first booking of room 2, it overlaps, you do nothing.
  • Now you look at the second booking of room 2. It doesn’t overlap, so you add room 2 to your list of room numbers.

There are no more bookings, so we’re done. Now your list incorrectly contains room number 2. Instead it should contain room number 3, but it doesn’t.

So in addition to your bookings you also need a list of rooms.

BTW checking whether a particular booking overlaps with a wanted period is simple. I give you pseudocode:

    if (tempEnd is before booking start) {
        // no overlap
    } else if (tempStart is after booking end) {
        // also no overlap
    } else {
        // overlap
    }

This is also what exudong’s answer already says.

Finally: The Date class you are using has design problems and is long outdated. It is also (despite its name) unsuited for representing a date, it is a point in time. Instead I warmly recommend you use LocalDate from java.time, the modern Java date and time API.

Link: Oracle tutorial: Date Time explaining how to use java.time.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

I cannot do it in the same if statement, but if you can compromise to have two...:

for (Booking b : books) {
    if (roomNbrs.contains(b.getRoomNbr()) {

        continue;
    }
    if (tempStart.after(b.getCheckoutDate()) && tempEnd.before(b.getCheckinDate()) {
        roomNbrs.add(b.getRoomNbr());
    }
}
Perdi Estaquel
  • 819
  • 1
  • 6
  • 21
  • This seems incorrect, it will only return true if b.getCheckoutDate() is before b.getCheckinDate() or tempStart is after tempEnd – Lasse Sviland Dec 06 '18 at 03:21
0

In the if statement you have tree conditions:

  1. Both chekin dates and both checkout dates are equal
  2. tempStart is after b.getCheckinDate() and tempEnd is before or equals to b.getCheckoutDate()
  3. tempStart is before or equals to b.getCheckinDate(), and tempEnd is before b.getCheckoutDate()

None of these 3 covers dates where tempStart is before b.getCheckinDate() and tempEnd is after b.getCheckoutDate()

If what you want is to see if the room is available in the period, I think it is easier to test if the temp dates are before or after the booking. Then you will have these two conditions:

  1. tempStart is before b.getCheckinDate() and tempEnd is before or equal to b.getCheckinDate()
  2. tempStart is after or equal to b.getCheckoutDate()

The code for the conditions will be somthing like this:

tempIsBeforeBooking = tempStart.before(b.getCheckinDate()) 
                          && (tempEnd.before(b.getCheckoutDate()) 
                              || tempEnd.equals(b.getCheckinDate());


tempIsAfterBooking = tempStart.after(b.getCheckoutDate()) 
                         || tempStart.equals(b.getCheckoutDate());
Lasse Sviland
  • 1,479
  • 11
  • 23