ERR
ERR

Reputation: 415

Convert string to MM/yyyy in c# to sort

I have seen previous questions which are related my query but couldn't figure out on how to resolve my issue.

I have a list "Sites" with one of the items as "Year". It is defined as string and is in the format "MM/yyyy". When I try to sort the list based on the year, I'm facing a small problem.

Data for "Year" is

01/2012
04/2012
01/2013
06/2012

When I sort the list by using orderby, the output I'm getting is

01/2012
01/2013
04/2012
06/2012

which is incorrect.

Cannot convert the string using Convert.ToDateTime as the string format doesn't contain day value. How should I go forward with this? How to implement DateTime.TryParseExact without changing the format of the string?

Note : The format should be the same and the list should be sorted.

Upvotes: 5

Views: 2115

Answers (4)

krillgar
krillgar

Reputation: 12805

You can still convert the string to a date within a LINQ statement, and the items will stay as strings.

var strings = new[]
{
    "01/2012",
    "04/2012",
    "01/2013",
    "06/2012"
};

var ordered = strings.OrderBy(s =>
{
    var split = s.Split('/');
    return new DateTime(int.Parse(split[1]), int.Parse(split[0]), 1);
});

Your last item will then be "01/2013".

As MethodMan showed in his answer, DateTime.Parse() will be able to parse a MM/yyyy formatted dated. However, if you need to perform anything that takes more than one line, this would be how you can do that. NB: This will not work in any query against a DbContext!

Upvotes: 4

Serge V.
Serge V.

Reputation: 3613

you also can create a new list with Dates converted to DateTime format and sort it after. It's a lot of lines but good for learning.

    class Sites
    {
        public string Year { get; set; }
    }
    class MainClass
    {
        static void Main()
        {
            List<Sites> ListOfSites = new List<Sites>();
            ListOfSites.Add(new Sites { Year = "01/2012" });
            ListOfSites.Add(new Sites { Year = "04/2012" });
            ListOfSites.Add(new Sites { Year = "01/2013" });
            ListOfSites.Add(new Sites { Year = "06/2012" });

            DateTime SiteYear;
            List<DateTime> listWithDates = new List<DateTime>(); 

            foreach (var item in ListOfSites)
            {
                if(DateTime.TryParse(item.Year, out SiteYear))
                {
                    listWithDates.Add(SiteYear);
                }
            }
            Display(SortAscending(listWithDates), "Sort Ascending");

        }
        static List<DateTime> SortAscending(List<DateTime> list)
        {
            list.Sort((a, b) => a.CompareTo(b));
            return list;
        }
        static void Display(List<DateTime> list, string message)
        {
            Console.WriteLine(message);
            foreach (var datetime in list)
            {
                Console.WriteLine(datetime);
            }
            Console.WriteLine();
        }
    }

Upvotes: -1

JazzSoft
JazzSoft

Reputation: 426

Implement System.IComparable interface:

public int CompareTo(object obj)
{
    // Check null
    if (obj == null)
        return 1;

    // Check types
    if (this.GetType() != obj.GetType())
        throw new ArgumentException("Cannot compare to different type.", "obj");

    // Extract year and month
    var year = int.Parse(this.Year.SubString(3, 4));
    var month = int.Parse(this.Year.SubString(0, 2));

    // Extract year and month to compare
    var site = (Sites)obj;
    var objyear = int.Parse(site.Year.SubString(3, 4));
    var objmonth = int.Parse(site.Year.SubString(0, 2));

    // Compare years first
    if (year != objyear)
        return year - objyear;

    // Same year

    // Compare months
    return month - objmonth;
}

Upvotes: 0

MethodMan
MethodMan

Reputation: 18843

you could try something like this without having to change the input this will give you the order that you like also look at the OrderByDescending property if you need it in a different sort order

var dateList = new List<string> { "01/2012", "04/2012", "01/2013", "06/2012" };
var orderedList = dateList.OrderBy(x => DateTime.Parse(x)).ToList();

enter image description here

Upvotes: 12

Related Questions