请注意,由于(例如)闰日,我们不能将所有日期都投影到当前年份的日期。变成是错误的February 29th, 2000
。February 29th, 2013
让我们首先仅按月份和日期对日期进行排序:
var ordered = from dt in dtlist
orderby dt.Month, dt.Day
select dt;
现在我们需要找到当前日期之前的所有日期(无论年份):
private static bool IsBeforeNow(DateTime now, DateTime dateTime)
{
return dateTime.Month < now.Month
|| (dateTime.Month == now.Month && dateTime.Day < now.Day);
}
我最初的建议是跳过/获取我们想要的日期并将它们连接在一起:
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);
但是,用户 Rawling 正确地指出,此代码将对您的日期列表进行两次排序:一次afterNow
是在评估时,一次beforeNow
是在评估时。他对日期排序的建议IsBeforeNow
更加优雅,因为它消除了跳过/获取和连接的需要。不再需要前面的代码块,LINQ 查询部分变为:
var now = DateTime.Now;
var birthdays = from dt in dtlist
orderby IsBeforeNow(now, dt), dt.Month, dt.Day
select dt;
并且birthdays
是你的结果。这已包含在下面的代码中:
完整代码:
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);
}
印刷:
18-地铁
7月25日
12月31日
2月21日