在列表中查找缺少的日期<日期时间>并在右侧索引中插入该日期
本文关键字:日期 索引 插入 查找 列表 时间 | 更新日期: 2023-09-27 18:32:20
>假设我有一个包含以下日期的列表。
List<DateTime> dateList = new List<DateTime>();
dateList.Add(new DateTime(2002, 01, 01));
dateList.Add(new DateTime(2002, 01, 02));
dateList.Add(new DateTime(2002, 01, 03));
dateList.Add(new DateTime(2002, 01, 04));
dateList.Add(new DateTime(2002, 01, 06));
dateList.Add(new DateTime(2002, 01, 08));
如何遍历日期列表,查找缺少的日期时间(2002-01-05 和 2002-01-07),然后创建这些日期时间并将它们添加到正确索引上的日期列表中?
您可以使用以下方法确定最小日期和最大日期以及时间跨度差异,然后生成列表:
DateTime min = dateList.Min();
DateTime max = dateList.Max();
TimeSpan diff = max - min;
dateList = Enumerable.Range(0, diff.Days + 1).Select(d => min.AddDays(d)).ToList();
您需要使用diff.Days + 1
来包含结束日期。
如果由于某种原因无法使用 LINQ,则可以使用 for 循环和List.Insert
,但是如果您不确定列表是否排序,则必须事先使用List.Sort
:
dateList.Sort();
if (dateList.Count > 1)
{
for (int i = 0; i < dateList.Count - 1; i++)
{
DateTime currrent = dateList[i].Date;
DateTime next = dateList[i + 1].Date;
DateTime expected = currrent.AddDays(1);
if (next != expected)
{
dateList.Insert(++i, expected);
}
}
}
您会看到 LINQ 版本的可读性要高得多。
这里的想法是循环并查找缺少的日期,并将其添加到新列表中。最后,加入两个列表并按日期重新排序。不是最好的性能,而是易于理解/维护。
var dates = new List<DateTime>();
dates.Add(new DateTime(2002, 01, 01));
dates.Add(new DateTime(2002, 01, 02));
dates.Add(new DateTime(2002, 01, 03));
dates.Add(new DateTime(2002, 01, 04));
dates.Add(new DateTime(2002, 01, 06));
dates.Add(new DateTime(2002, 01, 08));
// algo works only if dates are in order
dates = dates.OrderBy(date => date).ToList();
var missingDates = new List<DateTime>();
for (int i = 0; i + 1 < dates.Count; i++)
{
var diff = (dates[i + 1] - dates[i]).TotalDays;
for(int iToComplete = 1; iToComplete < diff; iToComplete++)
{
missingDates.Add(dates[i].AddDays(iToComplete));
}
}
dates.AddRange(missingDates);
dates = dates.OrderBy(date => date).ToList();
当您有开始和结束日期时,您可以生成所有日期的列表。然后使用Except
查找原始列表中缺少的日期:
var startDate = dateList.Min();
var endDate = dateList.Max();
var allDates = Enumerable.Range(0, (endDate - startDate).Days)
.Select(i => startDate.AddDays(i));
var missingDates = allDates.Except(dateList);
缺少日期:
2002
/1/5 2002/1/7