3

I have a list of string lists that contains DateTime values converted to strings. There are other values in the list, so I can't make the list a full DateTime list.

I have a line of code that sorts the list, but it sorts the dates by their string value, not DateTime value (which is what I want). How can I modify my code to correctly sort by the DateTime?

//This sorts the parent list by the 2nd column of the child list
List.Sort((a, b) => -1 * a[1].CompareTo(b[1]));

edit:

Sample List Contents:
Value1, 2010-06-28 10:30:00.000
Value2, 2010-06-27 10:30:00.000
Value2, 2010-06-26 10:30:00.000

3
  • can you post some content of your list? Commented Jun 28, 2010 at 15:36
  • I added some sample list contents to the original post Commented Jun 28, 2010 at 15:39
  • Is your list contents a string? You're accessing it like it's an array of strings. Commented Jun 28, 2010 at 15:52

6 Answers 6

7

Try the folloting

List.Sort((a,b) => -1 * DateTime.Parse(a[1]).CompareTo(DateTime.Parse(b[1])));

Or if you have LINQ handy and don't need an inplace sort

var sorted = myList.OrderBy(x => DateTime.Parse(x[1]));
Sign up to request clarification or add additional context in comments.

4 Comments

DateTime.Parse throws the following error: String was not recognized as a valid DateTime. Do I need to reconvert the DateTime to a string?
@Soo then the strings in your collection are not actually date times as your question specified (or they are in a unrecognized format). How did these strings get into this data structure? Can you show us some code?
The data format is coming from a LINQ query that grabs results from an SQL database. Shouldn't C# be able to recognize the date format anyway? I'm confused ...
@JaredPar: Did you mean to use OrderBy instead of Sort for the LINQ suggestion?
2

You should create your own custom comparer.

class Program
{
    static void Main(string[] args)
    {
        List<string> list = new List<string>
                                {
                                    "Value1, 2010-06-28 10:30:00.000",
                                    "Value2, 2010-06-27 10:30:00.000",
                                    "Value3, 2010-06-26 10:30:00.000"
                                };

        list.Sort(new MyComparer());
    }
}

internal class MyComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        var xItems = x.Split(new []{','});
        var yItems = y.Split(new []{','});
        var xDateTime = DateTime.Parse(xItems[1]);
        var yDateTime = DateTime.Parse(yItems[1]);
        return xDateTime.CompareTo(yDateTime);
    }
}

Comments

0

You first parse the string into a DateTime. Assuming the second columns is always a well-formed date/time string. The code below uses Linq to create a separate sorted list:

sortedList = yourList.OrderBy( item => DateTime.Parse( item[1] ) ).ToList();

If you need to sort in place, you can do so using:

List.Sort((a,b)=>return DateTime.Parse(b[1]).CompareTo(DateTime.Parse(a[1]) );

Depending on how your dates are repsented, you may want to consider using DateTime.ParseExact().

1 Comment

Considering how my dates are formatted: yyyy-mm-dd hh:mm:ss.mmm How would I use ParseExact() to make this work properly?
0

You need to convert a[1] to date time before comparing it.

List.Sort((a, b) => -1 * DateTime.Parse(a[1]).CompareTo(DateTime.Parse(b[1])))

EDIT:

If your LINQ query that fills the list is filling it as a list of strings, then you need to get a substring of the item that represents the date portion of the string. DateTime.Parse won't just magically pick out the part of the string that has a date value in it.

If this is the case and you're considering using string.Split, be sure you know the format your date will be coming, since some formats allow commas.

1 Comment

Let me see if I understand this correctly. a[1] and b[1] represent the second value in each child list, which should be DateTime items themselves. Shouldn't DateTime.Parse in that case work (it isn't). I'm not sure why DateTime.Parse isn't working because (from my understanding) a[1] and b[1] are already date strings.
0

Maybe something like

List<string> list = new List<string>
{
"Value1, 2010-06-28 10:30:00.000",
"Value2, 2010-06-27 10:30:00.000",
"Value3, 2010-06-26 10:30:00.000"
};

list.Sort((a, b) =>
    {
        string[] aSplit = a.Split(',');
        string[] bSplit = b.Split(',');

        if (aSplit.Count() < 2 && bSplit.Count() < 2) 
            return a.CompareTo(b);

        DateTime date1, date2;

        if (!DateTime.TryParse(aSplit[1].Trim(), out date1) || 
            !DateTime.TryParse(bSplit[1].Trim(), out date2))
            return a.CompareTo(b);

        return date2.CompareTo(date1);
    });

Comments

0

If your String contains anything other then a date, then I highly recommend splitting your string into JUST the date part, then TryParse and compare that value. Not the whole string!

yourStringList.Sort(
    (x, y) => {
        DateTime ix;
        DateTime iy;
        DateTime.TryParse(x.Split('(')[2].Split(')')[0], out ix);
        DateTime.TryParse(y.Split('(')[2].Split(')')[0], out iy);
        return ix.CompareTo(iy);
    }
);

In this example, im splitting my string to exactly the part where the date lies, and using tryparse on that. Only after that is parsed correctly can your comparing be done properly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.