【问题标题】:Getting Overlapping Start and End Date获取重叠的开始日期和结束日期
【发布时间】:2011-02-24 11:29:43
【问题描述】:

给定一个 DateRange,我需要返回与给定时间段重叠的 StartDates 和 EndDates 列表。

最好的方法是什么?提前感谢您的时间。

        static void Main(string[] args)
          {
             //Period 1stMarch to 20th April
             var startDate = new DateTime(2011, 03, 1);
             var endDate = new DateTime(2011, 4, 20); 

             List<BookedPeriod> bookedPeriods=new List<BookedPeriod>();
             bookedPeriods.Add(new BookedPeriod {StartDate = new DateTime(2011, 02, 5), EndDate = new DateTime(2011, 3, 15)});
             bookedPeriods.Add(new BookedPeriod { StartDate = new DateTime(2011, 03, 20), EndDate = new DateTime(2011, 4, 10) });
             bookedPeriods.Add(new BookedPeriod { StartDate = new DateTime(2011, 04, 01), EndDate = new DateTime(2011, 4, 15) });

             List<OverlappedPeriod> myOverllappedPeriods = GetOverllapedPeriods(startDate, endDate, bookedPeriods);
          }

          public static List<OverlappedPeriod>GetOverllapedPeriods(DateTime startDate,DateTime endDate,List<BookedPeriod>bookedPeriods)
          {
             List<OverlappedPeriod>overlappedPeriods=new List<OverlappedPeriod>();

             // Given a DateRange I need to return a list of Start and EndDates that overlaps
             //??how I do i


             return overlappedPeriods;
          }
       }

       public class BookedPeriod
       {
          public DateTime StartDate { get; set; }
          public DateTime EndDate { get; set; }
       }

        public class OverlappedPeriod
       {
          public DateTime StartDate { get; set; }
          public DateTime EndDate { get; set; }
       }

已编辑

我决定进行编辑,希望能澄清并帮助那些必须帮助我的人。 我对重叠与相交感到困惑。 一个场景可能会有所帮助

我已经预订了健身房,从 2011 年 3 月 1 日到 2011 年 4 月 20 日进行

我在 2011 年 2 月 5 日到 2011 年 3 月 15 日期间去度假

我需要知道我的订阅有效时的开始和结束日期,我不会去健身房 我应该得到的结果是 StartDate=1 March 2011 EndDate =15 March 2011

我的尝试: 静态无效主要() { //节假日 var startDate = new DateTime(2011, 02, 5); var endDate = new DateTime(2011, 3, 15);

             List<BookedPeriod> bookedPeriods = new List<BookedPeriod>();
             bookedPeriods.Add(new BookedPeriod { StartDate = new DateTime(2011, 02, 5), EndDate = new DateTime(2011, 4, 20) });

             List<OverlappedPeriod> overlappedPeriods=new List<OverlappedPeriod>();

             foreach (var bookedPeriod in bookedPeriods)
             {
                DateTime newStartDate = new DateTime();
                DateTime newEndDate = new DateTime();
                OverlappedPeriod overlappedPeriod=new OverlappedPeriod();
                overlappedPeriod.StartDate = newStartDate;
                overlappedPeriod.EndDate = newEndDate;

                GetDateRange(bookedPeriod.StartDate, bookedPeriod.EndDate, out newStartDate, out newEndDate);
                overlappedPeriods.Add(overlappedPeriod);

             }
             //do something with it

          }
           private static void GetDateRange(DateTime startDate,DateTime endDate,out DateTime newStartDate,out DateTime newEndDate)
           {
              /*
               * I need to get the start and end date when my subscription is valid that I will NOT BE GOING TO THE GYM
                   The result I should get back is StartDate=1 March 2011 EndDate =15 March 2011

               */
           }

【问题讨论】:

    标签: c# datetime


    【解决方案1】:

    您是在寻找完全在提供的时间段内的日期,还是部分日期?

    完全在范围内:

    var overlapped = 
        from period in bookedPeriods
        where period.StartDate >= startDate && period.EndDate <= endDate
        select new OverlappedPeriod { StartDate = period.StartDate, EndDate = period.EndDate };
    overlappedPeriods = overlapped.ToList();    
    

    部分重叠:

    var overlapped = 
        from period in bookedPeriods
        where (period.StartDate >= startDate && period.EndDate <= endDate)
            || (period.EndDate >= startDate && period.EndDate <= endDate)
            || (period.StartDate <= startDate && period.EndDate >= startDate)
            || (period.StartDate <= startDate && period.EndDate >= endDate)
        select new OverlappedPeriod 
        {
            StartDate = new DateTime(Math.Max(period.StartDate.Ticks, startDate.Ticks)),
            EndDate = new DateTime(Math.Min(period.EndDate.Ticks, endDate.Ticks))
        };
    
    overlappedPeriods = overlapped.ToList();    
    

    【讨论】:

    • 抱歉错误。我只需要获取重叠期间的开始和日期。但我似乎得到了错误的结果
    • 啊,我明白了。编辑了我的答案。现在返回与指定范围重叠的预订期间的部分。
    • 我似乎得到了错误的日期。我以为我会在 3 月 1 日 -3 月 15 日获得第一个。那是重叠的时期吗?
    • 不,真的不想滥用你的帮助。我已经编辑了这个问题,希望我能澄清我需要得到什么。你有空闲几分钟
    • 我检查了您的编辑。我的答案中的第二个代码示例和pastebin.com/VqALkcai 中的代码示例正是这样做的。 耸耸肩
    【解决方案2】:

    这段 LINQ 可能会有所帮助:

    var overlappedPeriods = bookedPeriods.Where(p=>p.EndDate > startDate && p.StartDate < endDate);
    

    然后将结果相应地转换为您的 OverlappedPeriod 类

    【讨论】:

      【解决方案3】:

      类似这样的东西(抱歉,未测试):

      return bookedPeriods.Where(
          b => (b.StartDate > startDate && b.StartDate < endDate) ||
           (b.EndDate> startDate && b.EndDate < endDate) ||
           (b.StartDate < startDate && b.EndDate > endDate)
      ).ToList()
      

      【讨论】:

      • 我认为你应该测试过,这错过了一大堆案例。
      • 与你的相比,我少了一行,但严格的差异很小
      【解决方案4】:

      一种方法是使用 Rectangle 类来计算相交。因此,程序是为每个日期范围创建一个矩形,然后使用 Rectangle.Intersect( ) 方法。

      【讨论】:

      • 这将是严重的矩形滥用 :-)
      • 哦!好主意,但相当复杂。如果您可以提供示例代码,我会投一票。
      • 哈哈哈哈!我知道,有空我会发布一些代码..!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-21
      • 2012-08-19
      • 2016-10-19
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      相关资源
      最近更新 更多