tags:

views:

272

answers:

7

Hello,

I have a C# list collection that I'm trying to sort. The strings that I'm trying to sort are dates "10/19/2009","10/20/2009"...etc. The sort method on my list will sort the dates but the problem is when a day has one digit, like "10/2/2009". When this happens the order is off. It will go "10/19/2009","10/20/2009","11/10/2009","11/2/2009","11/21/2009"..etc. This is ordering them wrong because it sees the two as greater than the 1 in 10. How can I correct this?

thanks

+1  A: 

write a compare method to convert "10/2/2009" to a date then compare

Henry Gao
Or use or convert to 2009/10/10 (YYYY/MM/DD)
Erik
A: 

You need to either use a sort specific for dates, or use something like Natural Sort.

John Fisher
+3  A: 

Assuming all your strings will parse:

MyList.OrderBy(d => DateTime.Parse(d));

Otherwise, you might need to use ParseExact() or something a little more complicated.

Joel Coehoorn
+15  A: 

The problem is they're strings, but you want to sort them by dates. Use a comparison function that converts them to dates before comparing. Something like this:

List<string> strings = new List<string>();

// TODO: fill the list

strings.Sort((x, y) => DateTime.Parse(x).CompareTo(DateTime.Parse(y)));
Chris Hynes
A: 

Parse the strings to DateTime objects and use DateTime.Compare.

Chris beat me to it!

Bob Nadler
A: 

If you care about performance and if that is possible for you, you would preferably sort your dates before you generate the strings. You would then use the date objects directly for the sort.

You would then save time manipulating strings back and forth.

decasteljau
+1  A: 

I wanted to see how well I could outperform Chris's solution with my own IComparer. The difference was negligible. To sort the same list of one million dates, my solution took 63.2 seconds, and Chris's took 66.2 seconds.

/// <summary>
/// Date strings must be in the format [M]M/[D]D/YYYY
/// </summary>
class DateStringComparer : IComparer<string>
{
   private static char[] slash = { '/' };

   public int Compare(string Date1, string Date2)
   {
      // get date component strings
      string[] strings1 = Date1.Split(slash);
      string[] strings2 = Date2.Split(slash);

      // get date component numbers
      int[] values1 = { Convert.ToInt32(strings1[0]),
                         Convert.ToInt32(strings1[1]),
                         Convert.ToInt32(strings1[2]) };
      int[] values2 = { Convert.ToInt32(strings2[0]),
                         Convert.ToInt32(strings2[1]),
                         Convert.ToInt32(strings2[2]) };

      // compare year, month, day
      if (values1[2] == values2[2])
         if (values1[0] == values2[0])
            return values1[1].CompareTo(values2[1]);
         else
            return values1[0].CompareTo(values2[0]);
      else
         return values1[2].CompareTo(values2[2]);
   }
}

As for sorting the dates as pre-existing DateTime instances, that took 252 milliseconds.

David Gannon