查找不与数据表发布重叠的范围内的最大TimeSpan

时间:2019-10-26 09:45:57

标签: c# asp.net

尝试在特定范围内找到非工作时间差异的最大内聚时间。

所查看的范围由以下项定义: sDate =范围开始 eDate =范围结束

在此定义的范围内,可能存在现有的配准(图像中的橙色块)。

有人可以给我一些有关如何解决此问题的意见。

enter image description here

此代码不会将现有帖子彼此进行比较。

 public TimeSpan TimeNightRest(DateTime WhatDay, int dayRange, DataTable TimeData)
    {
        DateTime DayRangeStart = new DateTime(WhatDay.Year, WhatDay.Month, WhatDay.Day, 0, 0, 0);
        DateTime DayRangeEnd = new DateTime(WhatDay.Year, WhatDay.Month, WhatDay.AddDays(dayRange).Day, 0, 0, 0);
        TimeSpan nightRest = new TimeSpan();


        foreach (DataRow drUnfiltered in TimeData.Rows)
        {
            DateTime sDate = DateTime.Parse(TimeData.Rows[0]["sDate"].ToString());
            DateTime eDate = DateTime.Parse(TimeData.Rows[0]["eDate"].ToString());

            //1. db-post cover range
            if (sDate < WhatDay && eDate > WhatDay.AddDays(dayRange))
            {
                nightRest = TimeSpan.FromHours(0);
                break;
            }
            //2. Post exists, start outside ends inside range
            if(sDate < WhatDay && eDate < WhatDay.AddDays(dayRange))
            {

               nightRest = (WhatDay.addDays(dayRange) - eDate)
               //More posts could exists that lower this value!!!
            }

            //3. Post exists, start inside ends outside range
            if ((sDate > WhatDay && sDate <WhatDay.AddDays(dayRange)) && eDate > WhatDay.AddDays(dayRange))
            {
                nightRest = (sDate - WhatDay);
                //More posts could exists that lower this value!!!
            }
        }
      return nightRest;
   }

我试图编写一个不同的版本,此代码将比较不同的帖子,以尝试找到它们之间的最大差异。但是,将无法找到重叠的帖子(无差异),也将无法找到正确的差异,而该差异必须在范围的外部开始,在范围之内并相反。

`

            ///<Alternative></Alternative>
            //1. - No Data Rest = 24h x DayRange
            if (timeData.Rows.Count == 0)
            {
                nightRest = TimeSpan.FromHours(24 * dayRange);
            }

            ///<Alternative></Alternative>
            //2. - One Post, Compare to day start/end time
            if (timeData.Rows.Count == 1)
            {
                DateTime sDate = Convert.ToDateTime(timeData.Rows[0]["sDate"].ToString());
                DateTime eDate = Convert.ToDateTime(timeData.Rows[0]["eDate"].ToString());

                TimeSpan range1 = (sDate - DayRangeStart);
                TimeSpan range2 = (DayRangeEnd - eDate);
                if (range1 > range2)
                {
                    nightRest = range1;
                }
                else
                {
                    nightRest = range2;
                }
            }

            ///<Alternative></Alternative>
            //3. - If DataTable containes more than 1 post, then loop through to calculate diffrence 
       between post and day start/end
            if (timeData.Rows.Count > 1)
            {
                int i = 1;
                int RowCount = timeData.Rows.Count;
                foreach (DataRow dr in timeData.Rows)
                {
                    DateTime sDate = Convert.ToDateTime(dr["sdate"]);
                    DateTime eDate = Convert.ToDateTime(dr["edate"]);

                    DateTime prevPostSdate = new DateTime();
                    DateTime nextPostSdate = new DateTime();

                    //Only 1st time in loop
                    if (i != 1)
                    {
                        //Prev row                       
                        DataRow lastRow = timeData.Rows[(i - 1) - 1];
                        prevPostSdate = Convert.ToDateTime(lastRow["edate"]);
                        //prevPostEdate = Convert.ToDateTime(lastRow["edate"]);
                    }
                    else
                    {
                        prevPostSdate = DayRangeStart;
                    }
                    //If we are on EOF-post then dont get next post value, get instead range end value
                    if (i != RowCount)
                    {
                        //Next row
                        DataRow nextRow = timeData.Rows[(i - 1) + 1];
                        nextPostSdate = Convert.ToDateTime(nextRow["sdate"]);
                    }
                    else
                    {
                        nextPostSdate = DayRangeEnd;
                    }
                    ///<Compare>Type #1 
                    ///Sdate inside && eDate inside
                    ///</ Compare >                    
                    if (DayRangeStart < sDate && DayRangeEnd > eDate)
                    {
                        //Compair Range with Post-sdate & Post
                        //1. Range with Post-sdate
                        TimeSpan value1 = (sDate - prevPostSdate);
                        //2. Post-eDate with NextPostSdate
                        TimeSpan value2 = (nextPostSdate - eDate);

                        if (value1 > nightRest) nightRest = value1;
                        if (value2 > nightRest) nightRest = value2;
                    }
                    ///<Compare>Type #2 
                    ///Sdate outside && eDate inside
                    ///</ Compare >                   
                    if (DayRangeStart >= sDate && DayRangeEnd > eDate)
                    {
                        //Compair Range with Post-sdate & Post
                        //1. Range with Post-sdate
                        TimeSpan value1 = (nextPostSdate - eDate);                           
                        if (value1 > nightRest) nightRest = value1;

                    }
                    ///<Compare>Type #3
                    ///Sdate indise && eDate outside                    
                    ///</ Compare >
                    if (DayRangeStart < sDate && DayRangeEnd <= eDate)
                    {
                        //Compare Range Post-sdate & Post
                        //1. Range with Post-sdate
                        TimeSpan value1 = (sDate - prevPostSdate);
                        //Console.WriteLine(value1);
                        if (value1 > nightRest) nightRest = value1;
                    }
                    ///<Compare>Type #4 
                    ///Sdate outside  && eDate outside                    
                    ///</ Compare >
                    if (DayRangeStart >= sDate && DayRangeEnd <= eDate)
                    {

                        nightRest = TimeSpan.FromHours(0);
                    }
                    i++;
                }
            }

`

1 个答案:

答案 0 :(得分:0)

我设法解决这个问题。可能有一些更好的代码,但这可以完成工作!

public DataTable FilterTable(DataTable table, DateTime startDate, DateTime endDate)
    {
        var filteredRows =
            from row in table.Rows.OfType<DataRow>()
            where (DateTime)row["sDate"] < endDate && startDate <= (DateTime)row["eDate"]
            select row;

        var filteredTable = table.Clone();
        filteredRows.ToList().ForEach(r => filteredTable.ImportRow(r));
        return filteredTable;
    }

public TimeSpan TimeNightRest(DateTime WhatDay, int dayRange, DataTable TimeData)
    {
        DateTime DayRangeStart = DateTime.Parse(WhatDay.ToShortDateString());
        DateTime DayRangeEnd = DateTime.Parse(DayRangeStart.AddDays(dayRange).ToShortDateString());
        TimeSpan nightRest = new TimeSpan();
        DataTable dtTime = FilterTable(TimeData, WhatDay, WhatDay.AddDays(dayRange));

        //1. - No posts
        if (dtTime.Rows.Count == 0)
        {
            nightRest = TimeSpan.FromHours(24 * dayRange);
        }

        //2. - One post Exists!
        if (dtTime.Rows.Count == 1)
        {
            DateTime sDate = Convert.ToDateTime(dtTime.Rows[0]["sDate"].ToString());
            DateTime eDate = Convert.ToDateTime(dtTime.Rows[0]["eDate"].ToString());

            if (sDate < DayRangeEnd && DayRangeStart <= eDate)
            {
                TimeSpan range1 = (sDate - DayRangeStart);
                TimeSpan range2 = (DayRangeEnd - eDate);
                if (range1 > range2)
                {
                    nightRest = range1;
                }
                else
                {
                    nightRest = range2;
                }
                //Negative TimeSpans is ==> Zero
                if(nightRest < TimeSpan.Zero)
                {
                    nightRest = TimeSpan.FromHours(0);
                }
            }
            else
            {
                nightRest = TimeSpan.FromHours(24 * dayRange);
            }
        }

        //3. More then 1 post i db
        if (dtTime.Rows.Count > 1)
        {
            int i = 1;
            int RowCount = dtTime.Rows.Count;
            foreach (DataRow dr in dtTime.Rows)
            {
                DateTime sDate = Convert.ToDateTime(dr["sdate"]);
                DateTime eDate = Convert.ToDateTime(dr["edate"]);


                if (sDate < DayRangeEnd && DayRangeStart <= eDate)
                {
                    DateTime prevPostSdate = new DateTime();
                    DateTime nextPostSdate = new DateTime();

                    //1st loop
                    if (i != 1)
                    {
                        //Prev row                       
                        DataRow lastRow = dtTime.Rows[(i - 1) - 1];
                        prevPostSdate = Convert.ToDateTime(lastRow["edate"]);
                    }
                    else
                    {
                        prevPostSdate = DayRangeStart;
                    }
                    //If we are on EOF-post then dont get next post value, get instead range end value
                    if (i != RowCount)
                    {
                        //Next row
                        DataRow nextRow = dtTime.Rows[(i - 1) + 1];
                        nextPostSdate = Convert.ToDateTime(nextRow["sdate"]);
                    }
                    else
                    {
                        nextPostSdate = DayRangeEnd;
                    }

                    if (DayRangeStart < sDate && DayRangeEnd > eDate)
                    {
                        TimeSpan value1 = (sDate - prevPostSdate);
                        TimeSpan value2 = (nextPostSdate - eDate);

                        if (value1 > nightRest) nightRest = value1;
                        if (value2 > nightRest) nightRest = value2;
                    }

                    if (DayRangeStart >= sDate && DayRangeEnd > eDate)
                    {
                        TimeSpan value1 = (nextPostSdate - eDate);
                        if (value1 > nightRest) nightRest = value1;
                    }

                    if (DayRangeStart < sDate && DayRangeEnd <= eDate)
                    {
                        TimeSpan value1 = (sDate - prevPostSdate);
                        if (value1 > nightRest) nightRest = value1;
                    }
                    if (DayRangeStart >= sDate && DayRangeEnd <= eDate)
                    {
                        nightRest = TimeSpan.FromHours(0);
                    }                       
                }
                else
                {
                    nightRest = TimeSpan.FromHours(24 * dayRange);
                }
                i++;
            }
        }
        return nightRest;
    }