Order your upcoming birthdays in LINQ

I want to show upcoming birthdays in the grid. I have a list of values ​​with random order, and I want to receive an order with a date from today (suppose the current date is March 1) 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"

The output order should be:

18-mar
25-July
31-dec
21-Feb

Note. I do not use any DB to get the values.

+5
source share
7 answers

, - () . 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 , / concat. , 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-mrt
25-jul
31-dec
21-feb
+7

List.Sort :

DateTime now = DateTime.Today;
dtlist.Sort((d1, d2) =>
    {
        if (DateTime.IsLeapYear(d1.Year) && d1.Month == 2 && d1.Day == 29)
            d1 = d1.Date.AddMilliseconds(-1);
        if (DateTime.IsLeapYear(d2.Year) && d2.Month == 2 && d2.Day == 29)
            d2 = d2.Date.AddMilliseconds(-1);
        var dtTrunc1 = new DateTime(now.Year, d1.Month, d1.Day, d1.Hour, d1.Minute, d1.Second, d1.Millisecond);
        var dtTrunc2 = new DateTime(now.Year, d2.Month, d2.Day, d2.Hour, d2.Minute, d2.Second, d2.Millisecond);
        TimeSpan diff1 = dtTrunc1 - now;
        TimeSpan diff2 = dtTrunc2 - now;
        if (diff1.Ticks >= 0 && diff2.Ticks >= 0 || diff1.Ticks < 0 && diff2.Ticks < 0)
            return diff1.Ticks.CompareTo(diff2.Ticks);
        else if (diff1.Ticks < 0 && diff2.Ticks >= 0)
            return int.MaxValue;
        else
            return int.MinValue;
    });

1. ( )

2. ( > 1000 , , , )

, . , DateTime.

+1
//A mock up value for comparison (as DayOfYear has a leap year issue)
int doy = DateTime.Today.Month*31 + DateTime.Today.Day;

var results = dtlist.OrderBy( a => 
              (a.DateOfBirth.Month * 31 + a.DateOfBirth.Day) +
              (a.DateOfBirth.Month * 31 + a.DateOfBirth.Day > doy ? 0 : 400 ))
             .ToList();
+1

! :

  • date, , - (, ), .

:

var dtlist  = new[]{
    DateTime.Parse("25-July-1985"),
    DateTime.Parse("31-Dec-1956"),
    DateTime.Parse("21-Feb-1978"),
    DateTime.Parse("18-Mar-2005")
};

var today = DateTime.Today;

var nextbirthDays = 
    from birthdate in dtlist
    select 
        Enumerable.Range(0, 1000)
        .Select(birthdate.AddYears)
        .First(birthday => birthday >= today);

var ordered = 
    nextBirthdays
    .OrderBy(d => d)
    .ToList();

, DateTime , dd-MMM . , .NET 4.0

.Select(age => birthdate.AddYears(age))

.Select(birthdate.AddYears)
0

, DayOfYear leap year issue. : 29 DayOfYear == 60, 1 - DayOfYear == 60 - DayOfYear == 61 , . , DayOfYear , , 29 1 , 1 2 .. , :

var upcomingBirthdays = birthdays.Where(dt => dt.DayOfYear >= DateTime.Today.DayOfYear).OrderBy(dt => dt.Month).ThenBy(dt => dt.Day);

var upcomingBirthdays = from birthday in birthdays
                        where birthday.DayOfYear >= DateTime.Today.DayOfYear
                        orderby birthday.Month, birthday.Day
                        select birthday;

- - 29 , 1 - , . .

Update:

: .

- , , :

var thisYear = from birthday in birthdays
               where birthday.DayOfYear >= DateTime.Today.DayOfYear
               orderby birthday.Month, birthday.Day
               select birthday;

var nextYear = from birthday in birthdays
               where birthday.DayOfYear < DateTime.Today.DayOfYear
               orderby birthday.Month, birthday.Day
               select birthday;

var upcomingBirthdays = thisYear.Concat(nextYear);

, .

0
var currentYear = DateTime.Today.Year;
var birthDays = dtList.Select(d => Tuple.Create(d, new DateTime(currentYear, d.Month, d.Day)))
    .OrderBy(tuple => tuple.Item2)
    .Where(tuple => tuple.Item2 > DateTime.Today)
    .Select(tuple => tuple.Item1)
    .ToList();            
-1

, , . , - , , . , (, 25 - 1985) / (, 25 - 2013), OrderBy, .

public IEnumerable<DateTime> UpcomingBirthdays(IEnumerable<DateTime> birthDates)
{
    return birthDates.Select(
        bd => new DateTime( 
            ((bd.Month >= DateTime.Today.Month || (bd.Month == DateTime.Today.Month && bd.Day >= DateTime.Today.Day)) ? DateTime.Today.Year : DateTime.Today.Year + 1),
            bd.Month,
            bd.Day)
        ).OrderBy(bd => bd);
}

, , .

-1

All Articles