2010-02-25 12 views
8

J'ai une liste qui contient Dates:C# - Calculer min Date/heure maximum à partir d'une liste

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" 

utilisant C# quel est le meilleur/plus court chemin pour trouver min Date/heure maximum de cette liste?

Répondre

17

J'aime la solution simple.

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

J'ai effectivement commencé à écrire la même méthode, je ne pense pas que l'on puisse faire beaucoup de choses pour battre le temps O (n) 'à moins de le mettre dans un type de structure de tas qui le résoudrait en' O (logN) ' temps mais alors vous échanger des cycles de processeur qui sont incroyablement bon marché pour doubler le stockage de la mémoire qui est moins cher comparativement. –

+1

@Jeffrey: Attention à la globalisation du format datetime pour les dates représentées comme des chaînes! – t0mm13b

+0

@ tommieb75 - Oui, j'ai pensé à ça, mais je ne l'ai pas inclus, parce que j'étais paresseux. Cette partie peut être tirée de la réponse de Mark Byers. Je vais lui donner un vote upvote pour le morceau ParseExact, et l'appeler fait. :-) –

2

Via Linq, vous pouvez faire:

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

La liste est une liste '' . Les chaînes min et max ne représentent pas nécessairement les dates min et max. – LukeH

17

utilisation 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)); 
24

les convertir en utilisant DateTime ParseExact (ou TryParseExact), puis utiliser LINQ pour obtenir le Min et Max: Notez que dans votre exemple, la liste était déjà triée par ordre croissant. Si vous pouvez garantir que cela sera toujours le cas et que vous voulez de meilleures performances, vous pouvez simplement prendre le premier et le dernier élément qui serait O (1) au lieu de O (n). Mais ce qui précède est plus sûr, même si votre liste sera probablement triée, vous ne devriez probablement pas faire cette optimisation à moins d'en avoir réellement besoin, juste au cas où la liste ne serait pas triée.

0

Ceci est similaire à la réponse @ Jeffrey, mais au lieu de l'analyse syntaxique chaque date, il commence par le min et les dates max comparant les valeurs de chaîne, puis il analyse les valeurs à la fin.

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

Ce 'FindMinAndMaxDates' a un' IList 'comme entrée. Comment représenteriez-vous un DateTime nul?Comme une chaîne nulle? Vous devez juste changer le WeirdComparer pour gérer les dates nulles, utiliser également une sémantique cohérente de comparaison de dates nulles, et enfin ignorer le ParseExact si la date min/max est nulle. – Fede

+0

Ne pas utiliser de chaîne, uniquement en utilisant *** DateTime nullable *** type – Kiquenet

+1

Dans ce cas, vous n'avez pas besoin de la fonction 'WeirdComparer'. Vous pouvez facilement vous en tirer en utilisant le comparateur par défaut pour 'DateTime?'. par exemple, si (Comparer .Default.Compare (nullableDate, min) <0) '. – Fede

0

Je sais que ce n'est pas une réponse directe à votre question, mais pourrait aider les autres s'ils viennent ici à la recherche de quelque chose de similaire.

J'ai rencontré ce problème aujourd'hui en essayant de trouver uniquement la date maximale à partir d'une liste d'objets. Parfois, il n'y aura pas de valeur dans la date pour les objets, donc j'ai dû comprendre comment utiliser une analyse try avec mon linq.

d'une combinaison de ce que Mark utilisé here je suis venu avec cela pour résoudre mon problème

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