【问题标题】:Comparing a DateTime Value to any value on a list of DateTimes in C#将 DateTime 值与 C# 中 DateTimes 列表中的任何值进行比较
【发布时间】:2020-08-06 18:41:06
【问题描述】:

我有一个约会安排应用程序,您可以在其中设置约会时间,当您设置该时间时,我想检查他们的约会是否与任何其他约会时间重叠,如果是,那么我想阻止他们安排约会. 我有 2 个包含约会开始和结束时间的列表:

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

如果开始时间介于这两个列表中的任何一个值之间,我希望他们无法安排约会,谢谢,我如何将时间与两个列表中的值进行比较?

【问题讨论】:

  • 你能再解释一下吗。如何连接开始时间和结束时间?按列表索引?
  • 它们是存储在 MySQL 数据库中的不同字段中的不同时间,我有一个 Windows 窗体应用程序有 2 个 DateTimePickers,它们允许您选择开始时间和日期,以及当他们单击我想要的添加约会按钮时比较开始时间的值,看看他们选择的开始时间是否在 AppointmentStartTimes 列表中的任何位置。
  • 那么,您要检查该值是否已经存在?
  • 是的,我想检查开始时间是否介于 StartTimes 列表中的任何时间和 EndTimes 列表中的任何值之间。
  • 所以AppointmentStartTimes[0]AppointmentEndTimes[0] 描述一个 约会然后AppointmentStartTimes[1]AppointmentEndTimes[1] 描述另一个?为什么没有 Appointment 具有 start 和 end 属性的类,然后只有 one 列表? -- 但基本上,每个索引都需要:var start = AppointmentStartTimes[index]; var end = AppointmentEndTimes[index]; if ((start &lt;= newStart &amp;&amp; end &gt;= newStart) || (start &lt;= newEnd &amp;&amp; end &gt;= newEnd)) { [handle overlap] } else { [handle not an overlap for THIS index] }.

标签: c# mysql asp.net-mvc winforms


【解决方案1】:

创建一个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));

【讨论】:

    【解决方案2】:

    我的建议是创建一个类 Appointment,它具有 a.o.一个时间框架。 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多