2016-12-12 7 views
3

Я видел предыдущие вопросы, связанные с моим запросом, но не мог понять, как решить мою проблему.Преобразование строки в MM/yyyy в C# для сортировки

У меня есть список «Сайты» с одним из предметов как «Год». Он определен как строка и находится в формате «MM/yyyy». Когда я пытаюсь сортировать список в зависимости от года, я столкнулся с небольшой проблемой.

данные для "Год" является

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

Когда я сортировки списка с помощью OrderBy, выход я получаю

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

что неправильно.

Невозможно преобразовать строку, используя Convert.ToDateTime, поскольку формат строки не содержит значения дня. Как мне идти дальше? Как реализовать DateTime.TryParseExact без изменения формата строки?

Примечание: формат должен быть таким же и список должен быть отсортирован.

+2

Использовать константу 1 в качестве значения дня? например 'DateTime.ParseExact (« 01/»+ myDate,« dd/MM/yyyy »)' –

+0

Я не могу изменить формат вывода. Это должно быть в 'MM/yyyy' –

+0

http://stackoverflow.com/questions/3513727/datetime-format-for-a-month-and-year - проверьте это – Aishu

ответ

8

вы могли бы попробовать что-то вроде этого, без необходимости менять вход это даст вам заказ, который вам нравится и смотреть на OrderByDescending собственности, если вам это нужно в другом порядке сортировки

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

+1

Я не понял, что' DateTime.Parse() 'будет принять дату в этом формате.В любом случае, я оставил свой ответ, чтобы показать более сложный «Func», возникающий в лямбда LINQ. – krillgar

+1

@krillgar Я тоже посмотрел на ваше решение, и он отлично работает для тех, кто может понять более сложный Func, я также дал ему '+ 1' – MethodMan

4

Вы все еще можете преобразовать строку в дату в инструкции LINQ, и элементы останутся в виде строк.

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

Последний товар будет "01/2013".

Как показал MethodMan в своем ответе, DateTime.Parse() сможет разобрать MM/yyyy отформатированный. Однако, если вам нужно выполнить что-либо, что занимает более одной строки, это будет так, как вы можете это сделать. NB: Это будет не Работает в любом запросе по DbContext!

0

Реализовать System.IComparable интерфейс:

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; 
} 
-1

Вы также можете создать новый список с датами, преобразованных в формат DateTime и сортировать его после. Это много линий, но полезно для обучения.

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(); 
     } 
    } 
+1

@SergeVikisgenko. Я знаю, что есть много способов скинуть кошку, но вы приближаетесь кажется немного 'OverKill' ​​ – MethodMan

+0

@MethodMan, возможно, вы правы. Я использовал цикл foreach и анализировал каждый элемент в новом списке с форматом DateTime. В вашем случае это выражение лямбда, которое выполняется с двумя строками кода. Это зависит от того, чего вы пытаетесь достичь. В вашем случае ваш список по-прежнему является строкой, мой конвертируется в формат DateTime. –

+0

Я бы посоветовал изучать Лямбду, это сделает вашу жизнь намного легче и не нужно зацикливать, что когда-либо решить эту проблему с уважением. – MethodMan