在列表中查找缺少的日期<日期时间>并在右侧索引中插入该日期

本文关键字:日期 索引 插入 查找 列表 时间 | 更新日期: 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