I want to show upcoming birthdays in grid. I have list of values with random order and I want to get the order the dates from today's date (assume current date is March 1st) using LINQ.
List<DateTime> dtlist = new List<DateTime>();
List 1 value = "25-July-1985" List 2 value = "31-Dec-1956" List 3 value = "21-Feb-1978" List 4 value = "18-Mar-2005"
Output order should be:
18-Mar 25-July 31-Dec 21-Feb
Note: I am not using any DB over here to get values.
Note that we cannot just project all dates to a date with the current year, because of (for example) leap days. Making February 29th, 2000
into February 29th, 2013
would be wrong.
Let's first order the dates by only their month and day:
var ordered = from dt in dtlist
orderby dt.Month, dt.Day
select dt;
Now we need to find all dates that are before the current date (regardless of year):
private static bool IsBeforeNow(DateTime now, DateTime dateTime)
{
return dateTime.Month < now.Month
|| (dateTime.Month == now.Month && dateTime.Day < now.Day);
}
My original suggestion was to skip/take the dates we want and concatenate them together:
var now = DateTime.Now;
var afterNow = ordered.SkipWhile(dt => IsBeforeNow(now, dt));
var beforeNow = ordered.TakeWhile(dt => IsBeforeNow(now, dt));
var birthdays = Enumerable.Concat(afterNow, beforeNow);
However, user Rawling correctly pointed out that this code will order your list of dates twice: once when afterNow
is evaluated, and once when beforeNow
is evaluated. His suggestion to order the dates by IsBeforeNow
is even more elegant, because it removes the need to skip/take and concat. The previous code block is no longer necessary and the LINQ query part then becomes:
var now = DateTime.Now;
var birthdays = from dt in dtlist
orderby IsBeforeNow(now, dt), dt.Month, dt.Day
select dt;
And birthdays
is your result. That has been incorporated in the code below:
The full code:
static void Main(string[] args)
{
var dtlist = new[]{
DateTime.Parse("25-July-1985"),
DateTime.Parse("31-Dec-1956"),
DateTime.Parse("21-Feb-1978"),
DateTime.Parse("18-Mar-2005")
};
var now = DateTime.Now;
var birthdays = from dt in dtlist
orderby IsBeforeNow(now, dt), dt.Month, dt.Day
select dt;
foreach (var dt in birthdays)
{
Console.WriteLine(dt.ToString("dd-MMM"));
}
Console.ReadLine();
}
private static bool IsBeforeNow(DateTime now, DateTime dateTime)
{
return dateTime.Month < now.Month
|| (dateTime.Month == now.Month && dateTime.Day < now.Day);
}
Prints:
18-mrt 25-jul 31-dec 21-feb
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With