1

Let's say, I have two date intervals, 09:00 - 16:00 and 13:00 - 18:00. I want to check, if the two intervals have any common time. The above example has, the 13:00-16:00.

Data structure of intervals is something like this:

{
    "begin": 324872,
    "end": 532424
}

So there is a shift, and I want to check if a person was working on that shift, or not:

if(shift.Begin <= personWorkBegin && shift.End >= personWorkBegin) 

But this is not a solution, since it has to be inside that interval, and I just want to check common parts.

Hienz
  • 688
  • 7
  • 21
  • 1
    So what have you tried to do in order to achieve this? – Gilad Green Feb 20 '19 at 15:14
  • Just do a bunch of between-ness operations once you convert them to DateTimes. Get out your favorite internet search tool and look for "overlapping ranges". A solution for integers will work for DateTimes with minimal changes. Your clarification greatly limits the scope of your original question, by the way – Flydog57 Feb 20 '19 at 15:15
  • What do you mean under bunch of between? – Hienz Feb 20 '19 at 15:18
  • If you have two intervals, A (from a1 to a2) and B (from b1 to b2), is a1 between b1 and b2, is a2 between b1 and b2, and so on (it's a "bunch of _between-ness_ operations") – Flydog57 Feb 20 '19 at 15:20
  • How are the times being stored in the data structure? – Tom Dee Feb 20 '19 at 15:25
  • As I mentioned in the post, it's stored as long. – Hienz Feb 20 '19 at 15:26
  • This might have already been answered here -> https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap – nimbleDonut Feb 20 '19 at 15:28
  • This might have already been answered here -> https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap – nimbleDonut Feb 20 '19 at 15:30
  • What if the person clocks in before the shift starts, and clocks out after the shift ends? This seems like a reasonably thorough handling: https://stackoverflow.com/questions/13513932/algorithm-to-detect-overlapping-periods – Nanhydrin Feb 20 '19 at 15:39
  • 2
    Possible duplicate of [Determine Whether Two Date Ranges Overlap](https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap) – canton7 Feb 20 '19 at 15:41

2 Answers2

2

Maybe not the most neat solution, but should do the trick:

if (personWorkBegin >= shift.Begin && personWorkBegin <= shift.End ||
    personWorkEnd >= shift.Begin && personWorkEnd <= shift.End ||
    personWorkBegin <= shift.Begin && personWorkEnd >= shift.End) 

EDIT: The fourth check was redundant, as pointed out by canton7, and has been removed.

Nanna
  • 515
  • 1
  • 9
  • 25
  • I think that last part of the statement is unnecessary? If either `personWorkBegin` or `personWorkEnd` is between `shift.Begin` and `shift.End`, then that's sufficient: you don't need to check that both are. – canton7 Feb 20 '19 at 15:28
  • I' checking whether either the personWork period contains shift, or the other way around. Or do we know for certain that they only overlap partly? – Nanna Feb 20 '19 at 15:31
  • But you don't need to, is my point. If `personWorkBegin` is between `shift.Begin` and `shift.End`, then the person worked in the shift - you can't care whether they stopped working before or after `shift.End`. – canton7 Feb 20 '19 at 15:33
  • 1
    In fact, you can simplify it further, according to the [duplicate answer here](https://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap): `personWorkBegin <= shift.End && personWorkEnd >= shift.Start`. – canton7 Feb 20 '19 at 15:35
  • I like the simplified answer, although it makes the code a bit harder to read. But if you go for the method I wrote, I still think that you need all four cases. The first checks whether the person started within the shift, the second whether they ended within the shift, the third whether the person´s shift started before and ended after the other shift, and the last whether the other shift started and ended before the person´s shift. – Nanna Feb 20 '19 at 15:45
  • 2
    No, that case is already covered by the others. See a well-commented example here: https://dotnetfiddle.net/P8iMBW . Your 4th case tests whether the person began working after the shift started and ended before the shift finished. However you've already got a test that they started during the shift (1st case), and that's sufficient to say they worked during the shift - you don't need to check when they finished *as well*. Likewise you already test whether they ended during the shift (2nd case) – canton7 Feb 20 '19 at 16:02
  • Sorry I see what you mean now, have edited accordingly. – Nanna Feb 21 '19 at 08:28
0

You can just do the end of the first interval subtract the start of the second interval. If it is less than 0 then there is no overlap. If is greater than 0 then the overlap interval will be the end of the first interval add the difference.

Tom Dee
  • 2,516
  • 4
  • 17
  • 25
  • I think it's not working if we have an internal overlapping midnight. E.g: 06:00-14:00 and 05:00-20:00 – Hienz Feb 20 '19 at 15:23