C# - вычислить минимальную дату / максимальную дату из списка

У меня есть список, который содержит даты :

List<string> StringDates;

    [0]: "04.03.2010"
    [1]: "09.03.2010"
    [2]: "11.03.2010"
    [3]: "12.03.2010"
    [4]: "16.03.2010"
    [5]: "18.03.2010"
    [6]: "19.03.2010"
    [7]: "23.03.2010"
    [8]: "25.03.2010"
    [9]: "26.03.2010"

использование C# каков наилучший / самый короткий способ узнать минимальную дату / максимальную дату из этого списка ?

6 ответов


Мне нравится простое решение.

DateTime minDate = DateTime.MaxValue;
DateTime maxDate = DateTime.MinValue;
foreach (string dateString in StringDates)
{
    DateTime date = DateTime.Parse(dateString);
    if (date < minDate)
        minDate = date;
    if (date > maxDate)
        maxDate = date;
}

преобразовать их в DateTime используя ParseExact (или TryParseExact), а затем используйте Linq для получения Min и Max:

List<DateTime> dates = StringDates
   .Select(x => DateTime.ParseExact(x, "dd.MM.yyyy", null))
   .ToList();
DateTime minDate = dates.Min();
DateTime maxDate = dates.Max();

обратите внимание, что в вашем примере список уже отсортирован по возрастанию. Если вы можете гарантировать, что это всегда будет так, и вы хотите лучшую производительность, вы можете просто взять первый и последний элемент, который будет O(1) вместо O(n). Но вышесказанное безопаснее, поэтому, даже если ваш список, вероятно, всегда будет отсортирован, вы, вероятно, не должны этого делать оптимизация, если вам это не нужно, просто на случай, если однажды список не придет в отсортированном порядке.


используйте linq!:

    var list = new List<DateTime>();
    list.Add(new DateTime(2010, 1, 1));
    list.Add(new DateTime(2008, 1, 1));
    list.Add(new DateTime(2009, 1, 1));
    Console.WriteLine(list.Max(date => date));
    Console.WriteLine(list.Min(date => date));

через Linq вы можете сделать:

from row in StringDates
group row by true into r 
select new { 
    min = r.Min(z => z), 
    max = r.Max(z => z) 
}

это похоже на ответ @Jeffrey, но вместо разбора каждой даты он сначала находит даты min и max, сравнивая их строковые значения, а затем анализирует значения в конце.

// This method handles the date comparisons
private int WeirdComparer(string strDate1, string strDate2)
{
    int res = string.Compare(strDate1, 6, strDate2, 6, 4);
    if (res == 0)
        res = string.Compare(strDate1, 3, strDate2, 3, 2);
    if (res == 0)
        res = string.Compare(strDate1, 0, strDate2, 0, 2);
    return res;
}

public void FindMinAndMaxDates(IList<string> strDates, out DateTime minDate, out DateTime maxDate)
{
    string min = "99.99.9999";
    string max = "00.00.0000";
    foreach (string strDate in strDates)
    {
        if (WeirdComparer(strDate, min) < 0)
            min = strDate;
        if (WeirdComparer(strDate, max) > 0)
            max = strDate;
    }
    minDate = DateTime.ParseExact(min, "dd.MM.yyyy", null);
    maxDate = DateTime.ParseExact(max, "dd.MM.yyyy", null);
}

Я знаю, что это не прямой ответ на ваш вопрос, но может помочь другим, если они придут сюда в поисках чего-то подобного.

я столкнулся с этой проблемой сегодня, пытаясь найти только максимальную дату из списка объектов. Иногда в дате для объектов не будет значения, поэтому мне пришлось выяснить, как использовать try parse с моим linq.

из комбинации того, что использовал Марк здесь Я придумал это, чтобы решить мою проблема

        List<string> stringDates = new List<string>();
        stringDates.Add("Not a date");
        stringDates.Add("2015-01-01");
        stringDates.Add("2015-10-10");
        stringDates.Add("2015-9-10");
        stringDates.Add("123");

        DateTime sapInvoiceDate;
        DateTime tempDate = DateTime.MinValue;
        sapInvoiceDate = stringDates.Select(x => DateTime.TryParse(x, out tempDate)).Select(x => tempDate).Max();