简体   繁体   中英

24 hour ranges intersection logic

I have schedules which can go from 21:00 to 04:00.
Mostly these schedules will be such that they might pass the 00:00 hour mark.
Now i also have to add normal schedules spanning from 00:00 to 23:59.
I would like to calculate an intersection for the same.
currently i am using

if(((mytime1.start_time <= mytime2.end_time) && (mytime2.start_time <= mytime1.end_time))).

I still don't have a valid fool proof logic for the intersection when the trans day schedules are taken into account please help.

bool DoIntervalsOverlap(int s0, int e0, int s1, int e1)
{
    return s0 - e0 <= (unsigned int) s0 - e1 || s1 - e1 <= (unsigned int) s1 - e0;
}

First, note that, in essence, all of the arithmetic is unsigned. In s0 - e0 <= (unsigned int) s0 - e1 , e1 is converted to unsigned int to match s0 , and s0 - e0 is converted to unsigned int to match (unsigned int) s0 - e1 . Below, I assume all arithmetic is unsigned.

In retrospect, I wish I had written the terms in reverse order. Let's fix that now. s0 - e0 <= s0 - e1 is equivalent to e0 - s0 >= e1 - s0 . (This is true even in unsigned arithmetic.) Now we can think of e0 - s0 and e1 - s0 as the times e0 and e1 translated to a reference frame in which s0 is at the origin. In this frame, any times that are earlier in the day than the original s0 have been wrapped to large positive numbers. So, the wrapping around midnight is gone. We have only non-negative times measured from s0 . Then we see that e0 - s0 >= e1 - s0 is asking “Is e1 , measured from s0 , less than or equal to e0 ?” That question is equivalent to ”Is e1 inside [ s0 , e0 ]?”

Thus, the two conditions ask “Is e1 inside [ s0 , e0 ] or is e0 inside [ s1 , e1 ]?” If either interval ends inside the other, the intervals overlap. If neither ends inside the other, they do not overlap.

Consider each instant of time in the first interval in order. If none of these instants coincides with the start of the second interval then the two intervals do not intersect, unless the intervals were already intersecting from the start, in which case the first instant in the first interval will occur in a similar pass along the second interval. So if the starts and ends are (l1, r1) for the first interval and (l2, r2) for the second, we can check by looking to see if l1 is included in the range [l2, r2] and if l2 is included in the range [l1, r1]. If lx is numerically no larger than rx then this is the simple check to see if eg (l1 >= l2) && (l1 <= r2). If lx is larger than rx then it is a wraparound interval and you could check if (l2 >= l1) || (l2 <= r1).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM