(たとえば)飛躍日のために、すべての日付を現在の年の日付に単純に予測することはできないことに注意してください。作るのは間違っ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は、このコードが日付のリストを2回並べ替えることを正しく指摘しました。1回は評価されたとき、もう1回は評価されたときです。日付を並べ替えるという彼の提案は、スキップ/テイクして連結する必要がないため、さらにエレガントです。以前のコードブロックは不要になり、LINQクエリ部分は次のようになります。afterNow
beforeNow
IsBeforeNow
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-mrt
7月25日
12月31日
2月21日