尝试在特定范围内找到非工作时间差异的最大内聚时间。
所查看的范围由以下项定义: sDate =范围开始 eDate =范围结束
在此定义的范围内,可能存在现有的配准(图像中的橙色块)。
有人可以给我一些有关如何解决此问题的意见。
此代码不会将现有帖子彼此进行比较。
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++;
}
}
`
答案 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;
}