101892781
101892781

Reputation: 79

Check if datetime is within range

I'm trying to see if a datetime is within a range of another datetime.

Essentially, I have two lists. One containing times of potential events, and one containing times when people are unavailable. I want to cross reference them to check that the event(s) will not run when people are unavailable.

I have this function at the minute, but having some trouble actually the configuration of the if statements working, as I'm getting them wrong and having dates wrongly removed.

def check_times(event_times, unavailable_times):

    for event_time in event_times:
        for unavailable_time in unavailable_times:
            if (event_time[0] >= unavailable_time[1]) and (event_time[1] >= unavailable_time[2])
                event_times.remove(event_time)
                break

With regard to below, unavailable_times[1] refers to the beginning of the time where the person is unavailable and unavailable_times[2] is when that time ends. event_times[0] is the beginning of the event and event_times[1] is the end time of the event.

Essentially, say I want a meeting to run from 13:30 - 15:00, but person X is busy from 14:15 - 14:40. I then would want to disregard the 13:30 - 15:00 period. I'm just having a bit of a hard time configuring the if statements to reflect this.

Upvotes: 0

Views: 801

Answers (2)

Ken
Ken

Reputation: 463

First, I noticed a couple typos in your code. You are referring to event_times and unavailable_times in your if conditional statement when you should be referring to event_time and unavailable_time (no trailing s).

Second, the algorithm doesn't capture all of the cases in which the event_time overlaps the given unavailable_time. They are best visualized as follows, where E--E represents the event interval and U--U represents the unavailable interval.

# Case 1:
   E---------E
        U---------U
# Case 2:
               E---------E
        U---------U
# Case 3:
   E---------------------E
        U---------U
# Case 4:
           E---E
        U---------U

These cases are fully captured by the following conditional statements:

  1. (event_time[0] < unavailable_time[1]) and (event_time[1] > unavailable_time[1])
  2. (event_time[0] > unavailable_time[1]) and (event_time[0] < unavailable_time[2])

Edit: So your final function could be:

def check_times(event_times, unavailable_times):

    for event_time in event_times:
        for unavailable_time in unavailable_times:
            if ((event_time[0] < unavailable_time[1]) and (event_time[1] > unavailable_time[1])) or\
               ((event_time[0] > unavailable_time[1]) and (event_time[0] < unavailable_time[2])):
                event_times.remove(event_time)
                break

Upvotes: 3

Doragon
Doragon

Reputation: 367

I think the easiest way to go about it is to assume that for the event to overlap with an unavailable time, then the end of the event must be after the start of the unavailable time. then you only have to check that the start of the event isn't after the unavailable time. Something like this:

def check_times(event_times, unavailable_times):

    for event_time in event_times:
        for unavailable_time in unavailable_times:
            if (event_time[1] >= unavailable_time[1]) and !(event_time[0] >= unavailable_time[2])
                event_times.remove(event_time)
                break

Upvotes: 0

Related Questions