Pergunta

Eu tenho uma lista que contém datas:

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"

Usando C #, qual é a maneira melhor/mais curta de descobrir a data mínima/data máxima desta lista?

Foi útil?

Solução

Eu gosto da solução simples.

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

Outras dicas

Converte -os em DateTime Usando parseexacto (ou TryParseExact) e use o LINQ para obter o min e o máximo:

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

Observe que, no seu exemplo, a lista já estava classificada em ordem crescente. Se você puder garantir que este sempre seja o caso e você deseja melhor desempenho, você poderá usar o primeiro e o último elemento que seria O (1) em vez de O (n). Mas o acima é mais seguro, portanto, mesmo que o seu listado provavelmente sempre seja classificado, você provavelmente não deve fazer essa otimização, a menos que realmente precise, apenas para o caso de um dia a lista não ocorrer em ordem classificada.

use 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));

Via Linq, você pode fazer:

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

Isso é semelhante à resposta de @Jeffrey, mas, em vez de analisar cada data, primeiro encontra as datas MIN e Max comparando seus valores de string e depois analisa os valores no final.

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

Sei que essa não é uma resposta direta para sua pergunta, mas poderia ajudar os outros se eles viessem aqui procurando algo semelhante.

Hoje encontrei esse problema enquanto tentava encontrar apenas a data máxima de uma lista de objetos. Às vezes, não haverá um valor na data dos objetos, então eu tive que descobrir como usar uma análise de experimento com meu LINQ.

De uma combinação do que Mark usou aqui Eu vim com isso para resolver meu problema

        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();  
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top