簡體   English   中英

檢查 C# 中連續的日期范圍內的日期數?

[英]Check number of Dates in Date Range that are sequential in c#?

我正在嘗試創建一個函數,該函數返回從特定日期開始的日期范圍內的連續日期數。

例子:

開始日期:2022 年 9 月 1 日

日期范圍:9/1/2022、9/2/2022、9/3/2022、9/4/2022、9/7/2022

在這種情況下,我正在尋找的函數將返回 4。

假設日期可以是無序的,並且它們可以滾動到下個月,因此 StartDate 9/29/2022:

9/29/2022、9/30/2022、10/1/2022、10/4/2022 將返回 3。

我知道我可以遍歷從特定日期開始的日期並檢查連續天數,但我想知道是否有一種干凈的方法可以使用 Linq 來完成。

這是我能想到的最干凈的解決方案......

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;
        }
    }
}

輸出是:01.09.2022 0:00:00 02.09.2022 0:00:00 03.09.2022 0:00:00 04.09.2022 0:00:00

如果你想要計數,你可以在結果上調用 .Count() 或者只修改方法......應該很容易。

計算給定日期范圍內連續日期的數量。

  1. 首先從字符串中解析日期並按升序排列。
  2. 然后,使用TakeWhile方法從列表的開頭獲取一系列連續的日期。
  3. 最后統計返回序列中的元素個數並顯示結果。
public class Program
{
    private static void Main(string[] args)
    {
        var dateRange = "9/29/2022, 9/30/2022, 10/1/2022, 10/4/2022";
        var dates = dateRange
            .Split(", ")
            .Select(dateStr =>
            {
                var dateData = dateStr.Split("/");
                var month = int.Parse(dateData[0]);
                var day = int.Parse(dateData[1]);
                var year = int.Parse(dateData[2]);
                return new DateTime(year, month, day);
            })
            .OrderBy(x => x)
            .ToList();

        var consecutiveDatesCounter = dates
            .TakeWhile((date, i) => i == 0 || dates[i - 1].AddDays(1) == date)
            .Count();

        Console.WriteLine(consecutiveDatesCounter);
    }
}

輸出: 3

演示: https ://dotnetfiddle.net/tYdWvz

使用循環可能是最干凈的方法。 我會使用類似下面的東西:

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;
}

另一種使用循環的方法。 (我同意其他人的說法,循環比使用 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.
}
  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();

您要么對日期進行排序並找到連續的日期,要么不對其進行排序並重復遍歷該集合以尋找匹配項。

這是后一種愚蠢的方法,將其保持未排序並重復調用“IndexOf”:

  public static int CountConsecutiveDays(DateTime startingFrom, List<DateTime> data) 
  {
    int count = 0;
    int index = data.IndexOf(startingFrom);
    while(index != -1) {
      count++;
      startingFrom = startingFrom.AddDays(1);
      index = data.IndexOf(startingFrom);
    }
    return count;
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM