根据数据 table 中的一组日期范围检查日期范围
Checking date range against set of date ranges in a data table
我需要根据数据 table 中的一组开始日期和结束日期检查用户输入的开始日期和结束日期,以确保没有重叠。
用户使用开始日期和结束日期组合请求休假。我想确保这个开始和结束日期不包含在我从数据库读取到数据 table.
的一组日期中
我使用了以下但不确定这是否正确。这里 "table" 包含用户现有的从数据库中获取的休假请求,startDate 和 endDate 是 s/he 请求的。数据 table 有 "StartDate" 和 "EndDate" 列。
private DataTable FilterTable(DataTable table, DateTime startDate, DateTime endDate)
{
var filteredRows =
from row in table.Rows.OfType<DataRow>()
where (DateTime)row["StartDate"] >= startDate
where (DateTime)row["StartDate"] <= endDate
select row;
var filteredTable = table.Clone();
filteredRows.ToList().ForEach(r => filteredTable.ImportRow(r));
return filteredTable;
}
如果返回的数据table没有行,否则有重叠。
使用扩展方法检查日期是否介于两个日期之间,
public static class DateTimeExt {
public static bool Between(this DateTime aDate, DateTime start, DateTime end) => start <= aDate && aDate <= end;
}
您可以编写一个 Overlaps 方法来确定两个范围是否重叠:
public static bool Overlaps(DateTime aPeriodStart, DateTime aPeriodEnd, DateTime bPeriodStart, DateTime bPeriodEnd)
=> aPeriodStart.Between(bPeriodStart, bPeriodEnd) ||
aPeriodEnd.Between(bPeriodStart, bPeriodEnd) ||
bPeriodStart.Between(aPeriodStart, aPeriodEnd);
现在使用另一种扩展方法将 IEnumerable<DataRow>
转换为包含行的 DataTable
:
public static class IEnumerableExt {
public static DataTable ToDataTable(this IEnumerable<DataRow> src) {
var ans = src.First().Table.Clone();
foreach (var r in src)
ans.ImportRow(r);
return ans;
}
}
你的最终方法很简单:
DataTable FilterTable(DataTable timeTable, DateTime startDate, DateTime endDate) =>
timeTable.AsEnumerable().Where(period => Overlaps(period.Field<DateTime>("StartDate"), period.Field<DateTime>("EndDate"), startDate, endDate)).ToDataTable();
注意:如果您不需要回答 DataTable
任何事情,将 .ToDataTable()
替换为 .Any()
并只使用 [=30= 方法会更有效] a bool
指示是否存在任何重叠。
我需要根据数据 table 中的一组开始日期和结束日期检查用户输入的开始日期和结束日期,以确保没有重叠。
用户使用开始日期和结束日期组合请求休假。我想确保这个开始和结束日期不包含在我从数据库读取到数据 table.
的一组日期中我使用了以下但不确定这是否正确。这里 "table" 包含用户现有的从数据库中获取的休假请求,startDate 和 endDate 是 s/he 请求的。数据 table 有 "StartDate" 和 "EndDate" 列。
private DataTable FilterTable(DataTable table, DateTime startDate, DateTime endDate)
{
var filteredRows =
from row in table.Rows.OfType<DataRow>()
where (DateTime)row["StartDate"] >= startDate
where (DateTime)row["StartDate"] <= endDate
select row;
var filteredTable = table.Clone();
filteredRows.ToList().ForEach(r => filteredTable.ImportRow(r));
return filteredTable;
}
如果返回的数据table没有行,否则有重叠。
使用扩展方法检查日期是否介于两个日期之间,
public static class DateTimeExt {
public static bool Between(this DateTime aDate, DateTime start, DateTime end) => start <= aDate && aDate <= end;
}
您可以编写一个 Overlaps 方法来确定两个范围是否重叠:
public static bool Overlaps(DateTime aPeriodStart, DateTime aPeriodEnd, DateTime bPeriodStart, DateTime bPeriodEnd)
=> aPeriodStart.Between(bPeriodStart, bPeriodEnd) ||
aPeriodEnd.Between(bPeriodStart, bPeriodEnd) ||
bPeriodStart.Between(aPeriodStart, aPeriodEnd);
现在使用另一种扩展方法将 IEnumerable<DataRow>
转换为包含行的 DataTable
:
public static class IEnumerableExt {
public static DataTable ToDataTable(this IEnumerable<DataRow> src) {
var ans = src.First().Table.Clone();
foreach (var r in src)
ans.ImportRow(r);
return ans;
}
}
你的最终方法很简单:
DataTable FilterTable(DataTable timeTable, DateTime startDate, DateTime endDate) =>
timeTable.AsEnumerable().Where(period => Overlaps(period.Field<DateTime>("StartDate"), period.Field<DateTime>("EndDate"), startDate, endDate)).ToDataTable();
注意:如果您不需要回答 DataTable
任何事情,将 .ToDataTable()
替换为 .Any()
并只使用 [=30= 方法会更有效] a bool
指示是否存在任何重叠。