0

I have the following function:

public bool IsAvailableForTimeslot(DateTime start, DateTime end)
    {
        bool startOK = true;
        bool endOK = true;
        foreach (var slot in ReservedSlots)
        {
            if (slot.Item2.AddHours(6) > start)
            {
                startOK = false;
            }
            if (slot.Item1 < end && start < slot.Item2)
            {
                endOK = false;
            }
        }
        if (startOK == true && endOK == true)
            return true;
        else
            return false;
    }

// List of Tuples with already reserved timeslots, Item1 being the start en 2 the end
    public List<Tuple<DateTime, DateTime>> ReservedSlots { get; set; }

When startdates and times within the "ReservedSlots" list are the same year as the parameters, the function returns everything as normal, but when the year differs the function marks startOK as false.

More information: Let's say I have 4 vehicles with a "ReservedSlots" list.

        demoVehicle0.ReservedSlots.Add(new Tuple<DateTime, DateTime>(new DateTime(2020, 1, 1, 12, 0, 0), new DateTime(2020, 1, 1, 20, 0, 0)));
        demoVehicle0.ReservedSlots.Add(new Tuple<DateTime, DateTime>(new DateTime(2020, 1, 2, 3, 0, 0), new DateTime(2020, 1, 2, 13, 0, 0)));
                // Works (returns false)

        demoVehicle2.ReservedSlots.Add(new Tuple<DateTime, DateTime>(new DateTime(2020, 1, 1, 12, 0, 0), new DateTime(2020, 1, 1, 20, 0, 0)));
        demoVehicle2.ReservedSlots.Add(new Tuple<DateTime, DateTime>(new DateTime(2020, 1, 2, 3, 0, 0), new DateTime(2020, 1, 2, 13, 0, 0)));
                // Works (returns false)

        demoVehicle3.ReservedSlots.Add(new Tuple<DateTime, DateTime>(new DateTime(2021, 1, 1, 1, 0, 0), new DateTime(2021, 1, 1, 5, 0, 0)));
                // Doesnt work (returns false) if I change the year to 2020, it will work however

        // timeslot is what is used in the parameters of the function above
        var timeslot = new Tuple<DateTime, DateTime>(new DateTime(2020, 1, 1, 20, 0, 0), new DateTime(2020, 1, 2, 0, 0, 0));
Robin GM
  • 185
  • 1
  • 8
  • 2
    `slot.Item2.AddHours(6) > start` will always evaluate to `true` if your slot's end time is after `start` even if it's in the next year/day/etc, i think you get it. Btw: you can just `return startOK && endOK;`. – Streamline Aug 06 '20 at 14:30

1 Answers1

1

You are returning false if either of the startOK or endOK variables are false at the end of the iteration, but this should only return false if both of these evaluate to false for the same slot.

You could restructure your method as such to achieve this.

public bool IsAvailableForTimeslot(DateTime start, DateTime end)
{
    foreach (var slot in ReservedSlots)
    {
        if (start < slot.Item2.AddHours(6) && slot.Item1 < end)
            return false;
    }

    return true;
}

Or without explicitly defining a loop...

using System.Linq;

public bool IsAvailableForTimeslot(DateTime start, DateTime end)
{
    return !ReservedSlots.Any(slot => start < slot.Item2.AddHours(6) && slot.Item1 < end);
}

Here's more information on detecting overlapping periods.

Creyke
  • 1,887
  • 2
  • 12
  • 16
  • 1
    Thanks! Messing with DateTime for too long has messed with my head. Didn't get your loop-less version to work though, but I'm not very familiar with the Any method. – Robin GM Aug 06 '20 at 14:51
  • You may need a `using System.Linq;` to do so. – Creyke Aug 06 '20 at 15:25