views:

1044

answers:

5

I have a List which contains Dates :

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"

Using C# what is the best/shortest way to find out min date / max date from this list ?

Using LINQ is not an option!

Thanks!

A: 

Via Linq, you can do:

from row in StringDates
group row by true into r 
select new { 
    min = r.Min(z => z), 
    max = r.Max(z => z) 
}
Scott Stafford
The list is a `List<string>`. The min and max strings won't necessarily represent the min and max dates.
LukeH
A: 

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));
Ryan Ferretti
+2  A: 

Convert them to DateTime using ParseExact (or TryParseExact) and then use Linq to get the Min and Max:

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

Note that in your example the list was already sorted in ascending order. If you can guarantee that this will always be the case and you want better performance, you could just take the first and last element which would be O(1) instead of O(n). But the above is safer so even if your listed probably will always be sorted, you probably shouldn't make this optimization unless you actually need it, just in case one day the list doesn't come in sorted order.

Mark Byers
+2  A: 

I like the simple solution.

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;
}
Jeffrey L Whitledge
I actually started writing the same method, I don't think much could be done to beat `O(n)` time unless you put it into some type of heap structure that would let you solve it in `O(logN)` time but then you'd trade processor cycles which are amazingly cheap for double the memory storage which is less cheap comparatively.
Chris Marisic
@Jeffrey: Be careful of the globalization of the datetime format for the dates represented as strings!
tommieb75
@tommieb75 - Yes, I thought of that, but didn't include it, because I was being lazy. That part can be taken from Mark Byers's answer. I'll give him upvote for the ParseExact piece, and call it done. :-)
Jeffrey L Whitledge
@Jeffrey: okey doke! :D
tommieb75
@Chris, you can't beat the O(n) time, because you have to read all the input to find out min and max values. I assume that in a real scenario the values are unsorted, because if not, this wouldn't make sense.
Fede
@Fede true you would need to iterate through the whole list to add it to a different collection, so the only way to beat `O(N)` would be to start with some type of heap structure.
Chris Marisic
A: 

This is similar to @Jeffrey's answer, but instead of parsing each date, it first finds the min and max dates comparing its string values, and then it parses the values at the end.

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