1

I'm trying to build a function that will tell me whether or not 2 time range are overlapping. All the existing solutions I have found so far are all about detecting overlapping but over the same day which is no good to me.

I thought something like that would work but it doesn't handle all scenarios:

var current = new Day()
{
    Start = TimeSpan.Parse("23:00"),
    End = TimeSpan.Parse("02:00")
};

var next = new Day()
{
    Start = TimeSpan.Parse("22:45"),
    End = TimeSpan.Parse("23:30")
};

current.End = (current.Start > current.End) ? 
               current.End.Add(new TimeSpan(24, 0, 0)) : 
               current.End;

next.End = (next.Start > next.End) ? 
            next.End.Add(new TimeSpan(24, 0, 0)) : 
            next.End;

bool overlap = (current.Start < next.End && next.Start < current.End);

Debug.WriteLine(overlap);

The provide scenario work as expected but if I try the following it does not work:

var current = new Day()
{
    Start = TimeSpan.Parse("23:00"),
    End = TimeSpan.Parse("02:00")
};

var next = new Day()
{
    Start = TimeSpan.Parse("01:00"),
    End = TimeSpan.Parse("04:00")
};

Any suggestions on what I can use to handle all scenarios. It needs to handle overlapping but it also need to handle that anytime a end time is smaller than a start time, it will assume that it is over the next day and the overlapping calculation should take this into account.

Thanks.

Thierry
  • 6,142
  • 13
  • 66
  • 117
  • 1
    A timespan has no date. You created a `Day` class whose `End` is smaller than its `Start`. You'll have to adjust your comparison code accordingly to handle this case. A quick&dirty solution would be to add 1 day to `End` when this happens and use the new `end` during comparison. What happens if `Start` and `End` are equal though? Does that mean a duration of 0 or 24 hours? – Panagiotis Kanavos Feb 05 '19 at 08:50
  • 4
    A TimeSpan represents a *period of time*, not a *time of day*. Those are different concepts and will usually have separate types (If they both have types) – Damien_The_Unbeliever Feb 05 '19 at 08:50
  • 2
    @Damien_The_Unbeliever: Unfortunately there's no time-of-day type in the BCL, and `DateTime` *does* use `TimeSpan` for time-of-day. Just another reason to use NodaTime :) – Jon Skeet Feb 05 '19 at 08:55
  • @PanagiotisKanavos I am adding 24 hours to the end timespan if it is larger than the start. Based on the example that doesn't work, the start is 23:00 and the end is 1.02:00 and if I subtract one from another, I do get 3 hours. Isn't that enough to know you're dealing with the next day? – Thierry Feb 05 '19 at 08:56
  • 1
    I don't get your `Day` class. If you are using it to represent a period of time (3 hours), you should be using a single `TimeSpan` (since this is exactly what it does). If you are looking for a specific period of time, (between 23:00 and 01:00), you should have the start as a `DateTime`, even if it's not meant to be on a particular date - you still need the concept of date to represent it correctly. – Zohar Peled Feb 05 '19 at 09:03
  • @ZoharPeled Day is just a bad class name. Sorry. It should have been called Range instead. I'm currently changing my code to start using DateTime and I'll see how I get on. – Thierry Feb 05 '19 at 09:04
  • Then read Damien's comment to Henk's answer. This would still fail with the same problem. Unless you are using one day later on the `next` Start - because on the same day these ranges do not overlap. – Zohar Peled Feb 05 '19 at 09:06
  • *Subtract* one day from `Start` instead of adding one day to `End`. Right now the two spans have different origins, one in the current day, one in the next one. By subtracting 1 day from the start you force them to use the same origin – Panagiotis Kanavos Feb 05 '19 at 09:12
  • That's what you'd do if you were using angles and radians instead of time and hours. The two are equivalent though which means you can use the same calculations – Panagiotis Kanavos Feb 05 '19 at 09:15
  • @PanagiotisKanavos interesting... I'll try this now. – Thierry Feb 05 '19 at 09:19
  • @Thierry it won't work for your update, but converting time to angles will still work. – Panagiotis Kanavos Feb 05 '19 at 09:23
  • @PanagiotisKanavos ah, ok. Thanks for letting me know. I don't know if I want to start dealing with angles/radians when I'm dealing with date/time to be honest. There has to be a way to achieve this using date & time. – Thierry Feb 05 '19 at 09:36
  • @Thierry check [check if two segments on the same circle overlap / intersect](https://stackoverflow.com/questions/11775473/check-if-two-segments-on-the-same-circle-overlap-intersect). The process is the same as what you're trying to do - *normalize* all angles (times in your case) by adding 1 rotation (360 degrees/24 hours) where appropriate and then calculate the modulo. After that, compare the results – Panagiotis Kanavos Feb 05 '19 at 09:39
  • @Thierry Timespan doesn't have a modulo operator so you'll have to convert it to hours or milliseconds first – Panagiotis Kanavos Feb 05 '19 at 09:40

0 Answers0