Сравнение значения DateTime с любым значением в списке DateTimes в C# - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть приложение для планирования встреч, где вы устанавливаете время встречи, и когда вы устанавливаете это время, я хочу проверить и посмотреть, не совпадает ли их назначение с другими временами встреч, и если да, то я хочу, чтобы они не планировали встречу , У меня есть 2 списка, содержащие время начала и окончания встречи:

public List<DateTime> AppointmentStartTimes = new List<DateTime>();
public List<DateTime> AppointmentEndTimes = new List<DateTime>();

Я хочу, чтобы они не могли планировать встречу, если время начала находится между любыми значениями в любом из этих списков, Как я бы сравнил время со значениями в обоих списках, спасибо?

Ответы [ 2 ]

2 голосов
/ 23 апреля 2020

Вместо того, чтобы использовать два списка, более чистый / более расширяемый подход будет состоять в создании Appointment класса:

class Appointment
{
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }

    public bool ConflictsWith(Appointment proposed)
    {
        return StartTime < proposed.EndTime && proposed.StartTime < EndTime;
    }
}

Тогда у вас может быть один список встреч:

public List<Appointment> Appointments = new List<Appointment>();

И вы можете проверить наличие конфликтов следующим образом:

Appointment proposed = //...
bool conflicts = Appointments.Any(appointment => appointment.ConflictsWith(proposed));
0 голосов
/ 23 апреля 2020

Мой совет - создать класс Appointment, который имеет TimeFrame. TimeFrame имеет StartTime / EndTime / Duration:

interface ITimeFrame
{
    DateTime StartTime {get;}
    DateTime EndTime {get;}
    TimeSpan Duration {get;}
}

Возможные реализации:

class TimeFrame : ITimeFrame
{
    public DateTime StartTime {get; set;}
    public DateTime EndTime {get; set;}
    public TimeSpan Duration => EndTime - StartTime;
}

Но вы также можете выбрать реализацию, где EndTime => StartTime + Duration

interface AppointMent
{
    int Id {get; }
    IReadOnlyCollection<Person> Attendees {get;}

    ITimeFrame TimeFrame {get; }
}

Вы хотите знать, перекрываются ли два Назначения. Я создаю его как методы расширения ITimeFrame и IAppointment:

public static bool Overlaps(this ITimeFrame timeFrameA, ITimeFrame timeFrameB)
{
    // assuming startTime of a TimeFrame is always smaller than EndTime
    // there is an overlap if
    // frameA starts before frameB ends AND frameA ends after frameB starts
    return timeFrameA.StartTime < timeFrameB.EndTime
        && timeFrameA.EndTime > timeFrame.StartTime;
}

public static bool Overlaps(this IAppointment appointmentA, IAppontment appointmentB)
{
    return appointmentA.TimeFrame.Overlaps(appointmentB.TimeFrame);
}

Использование:

IAppointment a = ...
IAppointment b = ...
bool overlaps = a.Overlaps(b);

Для LINQ мы делаем то же самое с последовательностями:

public static bool Overlaps(
    this IEnumerable<IAppointment> appointments,
    IAppointment otherAppointment)
{
    return appointments.Where(appointment => appointment.Overlaps(otherAppointment)).Any();
}

Использование :

IEnumerable<IAppointment> existingAppointment = ...
IAppointment requestedAppointment = ...

var hasOverlappingAppointments = existingAppointment
    .Overlaps(requestedAppointment)
    .Any();
if (hasOverlappingAppointments)
{
    WriteMessage("Can't make this appointment, it overlaps with existing appointments");
}
else
{
    AcceptAppointment(requestedAppointment);
}
...