Reputation:
I got a list of entries with a date
, a text
and a finished
attribute.
I want to sort this list by the date
. The date has the following format: dd.mm.yyyy
If I run this code, the result is mixed up like nothing happened. What's wrong?
this is my code:
// in the namespace
struct entry
{
public string date;
public string text;
public bool finished;
public entry(string _date, string _text, bool _finished)
{
date = _date;
text = _text;
finished = _finished;
}
}
// in my class
List<entry> entrys = new List<entry>();
// ** fill the list with content **
// where i want to sort the list
entrys.Sort(delegate (entry x, entry y)
{
string date1 = x.date;
string date2 = y.date;
// 0123456789
// dd.mm.yyyy
int day1 = Convert.ToInt32(date1.Substring(0, 2));
int day2 = Convert.ToInt32(date2.Substring(0, 2));
int month1 = Convert.ToInt32(date1.Substring(3, 2));
int month2 = Convert.ToInt32(date2.Substring(3, 2));
int year1 = Convert.ToInt32(date1.Substring(6, 4));
int year2 = Convert.ToInt32(date2.Substring(6, 4));
if (year1 > year2) return -1;
if (month1 > month2) return -1;
if (day1 > day2) return -1;
return 1;
});
Upvotes: 0
Views: 3572
Reputation: 416131
You're really doing this the hard way:
var entries = new List<entry>();
// ** fill the list with content **
entries = entries.OrderBy(e => DateTime.ParseExact(e.date, "dd.MM.yyyy", null)).ToList();
And one wonders why you don't already have .date
property as a DateTime
type instead of a string.
Upvotes: 2
Reputation: 26316
Just typed this quickly in LinqPad, the idea is to use Linq OrdeBy and defining a get property on the struct/class to return parsed DateTime
. You can use TryPraseExact
for additional safety.
void Main()
{
var list = new List<Entity>{
new Entity{TempDate = "25.10.2015", SomeData="data1"},
new Entity{TempDate = "20.10.2015", SomeData="data2"},
new Entity{TempDate = "26.10.2015", SomeData="data3"},
new Entity{TempDate = "18.10.2015", SomeData="data4"}};
list.Dump("Original");
list.OrderBy(x => x.DateTimeParsed).Dump("Sorted");
}
public struct Entity
{
public string TempDate {get; set;}
public DateTime DateTimeParsed{ get{ return DateTime.ParseExact(TempDate, "dd.mm.yyyy",CultureInfo.InvariantCulture); }}
public string SomeData {get; set;}
}
It is also a good idea to pass around DateTimeOffset
instead of a string date
Upvotes: 0
Reputation: 2825
Always follow the KISS (Keep It Simple Stupid) principle:
entrys.Sort(delegate (entry x, entry y)
{
DateTime dt1 = DateTime.ParseExact(x.date, "dd.MM.yyyy",
CultureInfo.InvariantCulture);
DateTime dt2 = DateTime.ParseExact(y.date, "dd.MM.yyyy",
CultureInfo.InvariantCulture);
return DateTime.Compare(dt1, dt2);
});
Upvotes: 0
Reputation: 813
No need to manually parse strings if computer can do that for you:
var provider = System.Globalization.CultureInfo.InvariantCulture;
entrys.Sort((a, b) =>
DateTime.ParseExact(a.date, "dd.MM.yyyy", provider)
.CompareTo(DateTime.ParseExact(b.date, "dd.MM.yyyy", provider)));
Upvotes: 0
Reputation: 27871
Your date field should become a DateTime. However, if for some reason you need it to be a string, then do the following:
First, add a GetDate method to your entry structure:
public DateTime GetDate()
{
int day = Convert.ToInt32(date.Substring(0, 2));
int month = Convert.ToInt32(date.Substring(3, 2));
int year = Convert.ToInt32(date.Substring(6, 4));
return new DateTime(year,month,day);
}
Then, use the following when you sort:
entrys.Sort((x, y) => x.GetDate().CompareTo(y.GetDate()));
Upvotes: 1
Reputation:
this code works:
entrys.Sort(delegate (entry x, entry y)
{
string date1 = x.date;
string date2 = y.date;
// 0123456789
// dd.mm.yyyy
int day1 = Convert.ToInt32(date1.Substring(0, 2));
int day2 = Convert.ToInt32(date2.Substring(0, 2));
int month1 = Convert.ToInt32(date1.Substring(3, 2));
int month2 = Convert.ToInt32(date2.Substring(3, 2));
int year1 = Convert.ToInt32(date1.Substring(6, 4));
int year2 = Convert.ToInt32(date2.Substring(6, 4));
if (year1 > year2) return 1;
if (year1 == year2 && month1 > month2) return 1;
if (year1 == year2 && month1 == month2 && day1 > day2) return 1;
return -1;
});
Upvotes: 0