linq 检查日期范围中在c#中连续的日期数?

zwghvu4y  于 2022-12-06  发布在  C#
关注(0)|答案(5)|浏览(221)

我正在尝试创建一个函数,该函数返回日期范围中从特定日期开始的连续日期数。

范例:

开始日期:2022年9月1日
日期范围:2022年9月1日、2022年9月2日、2022年9月3日、2022年9月4日、2022年9月7日
在这种情况下,我所寻找的函数将返回4。
假设日期可以是无序的,并且可以滚动到下一个月,因此对于StartDate 9/29/2022:
2022年9月29日、2022年9月30日、2022年10月1日、2022年10月4日将返回3。
我知道我可以从特定的日期开始遍历日期,并检查连续的天数,但我想知道是否有一种干净的方法可以用Linq完成这一任务。

kninwzqo

kninwzqo1#

这是我能想到的最干净的解决方案...

var startDate = new DateTime(2022, 9, 1);

var days = new List<DateTime>()
{
    new(2022, 8, 28),
    new(2022, 9, 1),
    new(2022, 9, 2),
    new(2022, 9, 3),
    new(2022, 9, 4),
    new(2022, 9, 7)
};

var consecutiveDays = GetConsecutiveDays(startDate, days);

foreach (var day in consecutiveDays)
{
    Console.WriteLine(day);
}

Console.ReadKey();

static IEnumerable<DateTime> GetConsecutiveDays(DateTime startDate, IEnumerable<DateTime> days)
{
    var wantedDate = startDate;
    foreach (var day in days.Where(d => d >= startDate).OrderBy(d => d))
    {
        if (day == wantedDate)
        {
            yield return day;
            wantedDate = wantedDate.AddDays(1);
        }
        else
        {
            yield break;
        }
    }
}

输出为:2022年9月1日0:00:00 2022年9月2日0:00:00 2022年9月3日0:00:00 2022年9月4日0:00:00
如果你想要计数,你可以调用.Count()对结果或者只是修改方法......应该很容易。

jq6vz3qz

jq6vz3qz2#

要计算日期范围内连续日期的数量:

class Program
{
    private static void Main(string[] args)
    {
        string dateRange = "10/4/2022, 9/29/2022, 10/1/2022, 9/30/2022";
        List<DateTime> dates = new List<DateTime>();

        foreach (var dateStr in dateRange.Split(", "))
        {
            // split date string to individual parts
            var dateData = dateStr.Split("/");
            
            // parse to DateTime
            int month = int.Parse(dateData[0]);
            int day = int.Parse(dateData[1]);
            int year = int.Parse(dateData[2]);
            var date = new DateTime(year, month, day);
            
            // add date to list
            dates.Add(date);
        }
        
        // order the dates
        dates = dates.OrderBy(x => x).ToList();
        
        // count for consecutive days in the date range
        var consecutiveDatesCounter = 1; // 1 to count for start date
        dates.Aggregate((last, next) =>
        {
            if (last.AddDays(1) == next)
                consecutiveDatesCounter++;
            else
                return last; // to prevent counting later consecutive dates
            return next;
        });
        
        // Display result
        Console.WriteLine(consecutiveDatesCounter);
    }
}

输出量:

3
u4vypkhs

u4vypkhs3#

使用循环可能是最简洁的方法。我会使用如下代码:

List<DateTime> GetConsecutiveDates(IEnumerable<DateTime> range, DateTime startDate)
{
    var orderedRange = range.OrderBy(d => d).ToList();
    int startDateIndex = orderedRange.IndexOf(startDate);
    if (startDateIndex == -1) return null;

    var consecutiveDates = new List<DateTime> { orderedRange[startDateIndex] };
    for (int i = startDateIndex + 1; i < orderedRange.Count; i++)
    {
        if (orderedRange[i] != orderedRange[i - 1].AddDays(1)) break;

        consecutiveDates.Add(orderedRange[i]);
    }
    return consecutiveDates;
}
ej83mcc0

ej83mcc04#

另一种使用循环的方法。(我同意其他人的说法,循环比使用Linq完成此任务更干净。)

public static int NumConsecutiveDays(IEnumerable<DateTime> dates)
{
    var previous = DateTime.MinValue;
    var oneDay   = TimeSpan.FromDays(1);
    int result   = 0;

    foreach (var current in dates.OrderBy(d => d))
    {
        if (current.Date - previous.Date == oneDay)
            ++result;

        previous = current;
    }

    return result > 0 ? result + 1 : 0;  // Need to add 1 to result if it is not zero.
}
agyaoht7

agyaoht75#

var dates = new List<DateTime>() {new DateTime(2014,1,1), new DateTime(2014, 1, 2), new DateTime(2014, 1, 3) , new DateTime(2014, 1, 5), new DateTime(2014, 1, 6), new DateTime(2014, 1, 8) };

  var startDate = new DateTime(2014,1,2);

  var EarliestContiguousDates = dates.Where(x => x>=startDate).OrderBy(x => x)
    .Select((x, i) => new { date = x, RangeStartDate = x.AddDays(-i) })
    .TakeWhile(x => x.RangeStartDate == dates.Where(y => y >= startDate).Min()).Count();

相关问题