1

I have a c# class named Slot which only accept values from 0:00:00 to 1.00:00:00 for all its TimeSpan properties.

public class Slot
{
    public TimeSpan StartTime { get; set; }

    public TimeSpan EndTime { get; set; }

}

I have these values as my active Intervals which don't overlap each other:

var activeIntervals= new List<Slot>
{
    new Slot
    {
        StartTime = new TimeSpan(10,0,0),
        EndTime = new TimeSpan(12,0,0),
    },
    new Slot
    {
        StartTime = new TimeSpan(12,0,0),
        EndTime = new TimeSpan(13,0,0),
    },
    new Slot
    {
        StartTime = new TimeSpan(16,0,0),
        EndTime = new TimeSpan(22,0,0),
    }
};

Is there any logic to get the other intervals of the day as inactiveIntervals?

In this case i want this result: 0:00:00 to 10:00:00, 13:00:00 to 16:00:00 and 22:00:00 to 1.00:00:00

FCin
  • 3,804
  • 4
  • 20
  • 49
Farshan
  • 437
  • 5
  • 14

3 Answers3

2

Try below logic. It will work for you.

You can test it here

var activeIntervals = new List<Slot>
{
    new Slot
    {
        StartTime = new TimeSpan(10,0,0),
        EndTime = new TimeSpan(12,0,0),
    },
    new Slot
    {
        StartTime = new TimeSpan(12,0,0),
        EndTime = new TimeSpan(13,0,0),
    },
    new Slot
    {
        StartTime = new TimeSpan(16,0,0),
        EndTime = new TimeSpan(22,0,0),
    }
};


activeIntervals = activeIntervals.OrderBy(x => x.StartTime).ToList();

var inActiveIntervals = new List<Slot>();
TimeSpan start =  new TimeSpan(0,0,0);
TimeSpan end =  new TimeSpan(24,0,0);

for (int i = 0; i < activeIntervals.Count(); i++)
{
    if (start < activeIntervals[i].StartTime) 
    {
        inActiveIntervals.Add(new Slot { StartTime = start, EndTime = activeIntervals[i].StartTime });
    }
    start = activeIntervals[i].EndTime;
}            
if (start < end) 
{
    inActiveIntervals.Add(new Slot { StartTime = start, EndTime = end });
    start = end;
}
for (int i = 0; i < inActiveIntervals.Count(); i++)
{
     Console.WriteLine(inActiveIntervals[i].StartTime.ToString() + " - " + inActiveIntervals[i].EndTime.ToString());
}
Karan
  • 12,059
  • 3
  • 24
  • 40
1

One idea with linq:

var inactiveIntervals = activeIntervals
    .Zip(activeIntervals.Skip(1), (first, second) => {
        if (second.StartTime - first.EndTime != TimeSpan.Zero) // Get rid of regions that don't have 'gap', e.g. 12:00:00 to 12:00:00
            return new Slot { StartTime = first.EndTime, EndTime = second.StartTime };
        return null;
    }).Where(a => a != null).ToList(); // Filter out nulls

// Insert range from start to first date
inactiveIntervals.Insert(0, new Slot { StartTime = TimeSpan.Zero, EndTime = activeIntervals[0].StartTime });
// Insert range from last date to end
inactiveIntervals.Add(new Slot { StartTime = activeIntervals.Last().EndTime, EndTime = new TimeSpan(1, 0, 0, 0) });

This uses a trick with .Zip where you take a list and then zip it with the same list moved by 1. Then you can compare EndTime from one element with StartTime from next element.

Filtering regions without gaps is kind of ugly. You have to check edge cases.

FCin
  • 3,804
  • 4
  • 20
  • 49
1

You need to create new instance of List<Slot> and then add intervals of day that does not exist in activeIntervals list using iteration of the list elements.

public static class SlotExtensions
{
    public static List<Slot> GetInactive(this List<Slot> slots)
    {
        Slot day = new Slot
        {
            StartTime = new TimeSpan(0,0,0),
            EndTime = new TimeSpan(24,0,0)
        }
        List<Slot> inactive = new List<Slot>();
        Slot tmp;
        foreach(Slot slot in slots)
        {
            if(day.StartTime < slot.StartTime)
            {
                tmp = new Slot
                {
                    StartTime = day.StartTime;
                    EndTime = slot.StartTime;
                };
                inactive.Add(tmp);
            };
            day.StartTime = slot.EndTime;
        }
        if(day.StartTime < day.EndTime)
        {
            inactive.Add(day);
        }
        return inactive;
    }
}

The extension method uses day, that is an instanse of Slot class and fits full day. Then we add difference between starts of the day and iterated slot to a new list and then shift start of the day to end of iterated slot. When loop is over the metod adds remainig interval to the list.

Alexander
  • 4,420
  • 7
  • 27
  • 42