簡體   English   中英

查找給定范圍的缺失日期

[英]Find missing dates for a given range

我正在嘗試在DateTimes集合的兩個DateTime變量之間找到缺少的日期。

例如。

Collection
2010-01-01
2010-01-02
2010-01-03
2010-01-05

DateRange
2010-01-01 -> 2010-01-06

會給我一個List<DateTime>

2010-01-04
2010-01-06

我可以想到一些是實現這一點,但沒有什么干凈和簡單

有任何想法嗎?

我可以想到很多實現這個的方法,例如:

DateTime[] col = { new DateTime(2010, 1, 1),
                   new DateTime(2010, 1, 2),
                   new DateTime(2010, 1, 3),
                   new DateTime(2010, 1, 5)};

var start = new DateTime(2010, 1, 1);
var end = new DateTime(2010, 1, 6);

var range = Enumerable.Range(0, (int)(end - start).TotalDays + 1)
                      .Select(i => start.AddDays(i));

var missing = range.Except(col);

你可以將范圍內容放入擴展方法中

public static class extensions
{
    public static IEnumerable<DateTime> Range(this DateTime startDate, DateTime endDate)
    {
        return Enumerable.Range(0, (int)(endDate - startDate).TotalDays + 1)
                         .Select(i => startDate.AddDays(i));
    }
}

那就簡單了

DateTime[] col = { new DateTime(2010, 1, 1),
                   new DateTime(2010, 1, 2),
                   new DateTime(2010, 1, 3),
                   new DateTime(2010, 1, 5)};

var start = new DateTime(2010, 1, 1);
var end = new DateTime(2010, 1, 6);
var missing = start.Range(end).Except(col);

但也許這不是一個高性能解決方案:-)

在.NET 2.0中:)

    static void Main(string[] args)
    {
        List<DateTime> dates = new List<DateTime>();
        dates.Add(new DateTime(2010, 01, 27));
        dates.Add(new DateTime(2010, 01, 30));
        dates.Add(new DateTime(2010, 01, 31));
        dates.Add(new DateTime(2010, 02, 01));


        DateTime startDate = new DateTime(2010, 01, 25);
        DateTime endDate = new DateTime(2010, 02, 02);

        List<DateTime> missingDates = new List<DateTime>(GetMissingDates(dates, startDate, endDate));

    }

    private static IEnumerable<DateTime> GetMissingDates(IList<DateTime> dates, DateTime startDate, DateTime endDate)
    {
        TimeSpan _timeStamp = endDate - startDate;
        DateTime _tempDateTime = startDate;
        IList<DateTime> _dateTimeRange = new List<DateTime>();
        IList<DateTime> _missingDates = new List<DateTime>();

        for (int i = 0; i <= _timeStamp.Days; i++)
        {
            _dateTimeRange.Add(_tempDateTime);
            _tempDateTime = _tempDateTime.AddDays(1);
        }

        foreach (DateTime dt in _dateTimeRange)
        {
            if (!dates.Contains(dt))
                yield return dt;
        }
    }

具體取決於您要查找的內容以及數據集的大小。 一種簡單的方法是將日期加載到集合中,然后使用簡單的循環。 我將在一秒鍾內添加一個代碼示例。

DateTime currentDate = new DateTime(2010, 1, 1);
DateTime endDate = new DateTime(2010, 1, 6);
List<DateTime> existingDates = new List<DateTime>; //You fill with values
List<DateTime> missingDates = new List<DateTime>;

while(currentDate <= endDate)
{
    if(existingDates.contains(currentDate))
        missingDates.Add(currentDate);

    //Increment date
    currentDate = currentDate.AddDays(1);
}

使用此示例,您只需要使用正確的值加載“existingDates”,然后“missingDates”列表將顯示您的結果

var dates = new List<DateTime>
                {
                    new DateTime( 2010, 01, 01 ), 
                    new DateTime( 2010, 01, 02 ), 
                    new DateTime( 2010, 01, 03 ), 
                    new DateTime( 2010, 01, 05 )
                };

var targetDate = new DateTime( 2010, 01, 01 );

var missingDates = new List<DateTime>();
while ( targetDate <= new DateTime( 2010, 01, 06 ) )
{
    if ( !dates.Contains( targetDate ) )
        missingDates.Add( targetDate );

    targetDate = targetDate.AddDays( 1 );
}

foreach ( var date in missingDates )
    Debug.WriteLine( date.ToString() );

如果您正在考慮解決這個問題,那么除非您還有最小和最大日期之間的所有日期列表,否則我認為不可能。 在SQL中,這相當於一個日歷表,其中包含給定時間段內的所有日期。

這是一個LINQ解決方案,我創建上面提到的日歷列表,然后查詢缺少的日期:

var dates = new List<DateTime>
                {
                    new DateTime( 2010, 01, 01 ), 
                    new DateTime( 2010, 01, 02 ), 
                    new DateTime( 2010, 01, 03 ), 
                    new DateTime( 2010, 01, 05 )
                };
var calendar = new List<DateTime>();
var targetDate = new DateTime( 2010, 01, 01 );
while ( targetDate <= new DateTime( 2010, 01, 06 ) )
{
    calendar.Add( targetDate );
    targetDate = targetDate.AddDays( 1 );
}

var missingDates = ( from date in calendar
              where !dates.Contains( date )
              select date ).ToList();

foreach ( var date in missingDates )
    Debug.WriteLine( date.ToString() );

延遲評估的輔助方法有助於生成要與之比較的日期列表。 可能希望為大型集合執行此方法的性能配置文件。

void Main()
{
    var dates = new[] {new DateTime(2000,1,1), new DateTime(2000,1,5)};
    DateHelper.Range(new DateTime(2000,1,1), new DateTime(2000,1,5)).Except(dates).Dump();
}

// Define other methods and classes here
public static class DateHelper {
    public static IEnumerable<DateTime> Range(DateTime start, DateTime end) {
        var days = end.Subtract(start).Days;
        var next = start;
        for(var i = 0; i<days; i++) {
            next = next.AddDays(1);
            yield return next;
        }
    }
}

暫無
暫無

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

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