SeToY
SeToY

Reputation: 5895

Compare DateTime without year

I'm trying to get an alert when a Customer has their birthday within the next 7 days.

I've tried it with this code:

public bool IsBirthdayImminent
{
    get { return DateOfBirth != null && DateOfBirth.Value.Date >= DateTime.Today.Date.AddDays(-7); }
}

Of course this doesn't work, as the Date is stored with its year (say 05/21/1980) and it also compares the year. So this query will never be true - well, not if you're born within the next seven days though.

How can I modify this query to ignore the year?

Edit:

Alright, the query itself is not a problem at all. My primary point is the handling of leap years and situations around December <-> January.

Upvotes: 9

Views: 9223

Answers (4)

Caramiriel
Caramiriel

Reputation: 7257

I would suggest using the following code. This includes cases around December - January and February, 29th. Though you might want to take a look and correct February 28th to be included or excluded within the given days.

    BirthdayImminent(new DateTime(1980, 1, 1), new DateTime(2012, 1, 2), 7); // false
    BirthdayImminent(new DateTime(1980, 1, 1), new DateTime(2012, 12, 28), 7); // true
    BirthdayImminent(new DateTime(1980, 2, 28), new DateTime(2012, 2, 21), 7); // true

    private static bool BirthdayImminent(DateTime birthDate, DateTime referenceDate, int days)
    {
        DateTime birthdayThisYear = birthDate.AddYears(referenceDate.Year - birthDate.Year);

        if (birthdayThisYear < referenceDate)
            birthdayThisYear = birthdayThisYear.AddYears(1);

        bool birthdayImminent = (birthdayThisYear - referenceDate).TotalDays <= days;

        return birthdayImminent;
    }

Also keep the edge case in mind Guvante posted in the comments below.

Upvotes: 12

MarcF
MarcF

Reputation: 3299

Something like this:

DateTime birthDate = new DateTime(2012, 12, 2);

DateTime birthdayThisYear;
if (birthDate.Month == 2 && birthDate.Day == 29 && DateTime.IsLeapYear(DateTime.Now.Year))
    birthdayThisYear = new DateTime(DateTime.Now.Year, 2, 28);
else
    birthdayThisYear = new DateTime(DateTime.Now.Year, birthDate.Month, birthDate.Day);

bool birthdayImminent = birthdayThisYear > DateTime.Now && (birthdayThisYear - DateTime.Now).TotalDays <= 7;

As a getter:

public bool IsBirthdayImminent
{
    get 
    { 
        if (DateOfBirth == null) 
            return false;
        else
        {
            DateTime birthdayThisYear;
            if (birthDate.Month == 2 && birthDate.Day == 29 && DateTime.IsLeapYear(DateTime.Now.Year))
                birthdayThisYear = new DateTime(DateTime.Now.Year, 2, 28);
            else
                birthdayThisYear = new DateTime(DateTime.Now.Year, birthDate.Month, birthDate.Day);

            return birthdayThisYear > DateTime.Now && (birthdayThisYear - DateTime.Now).TotalDays <= 7;
        }
    }
}

Upvotes: 1

Bill Gregg
Bill Gregg

Reputation: 7147

Try this:

public bool IsBirthdayImminent
{
    get { return DateOfBirth != null && DateOfBirth.Value.Date.AddYear(DateTime.Now.Year -DateOfBirth.Value.Year) >= DateTime.Today.Date.AddDays(-7); }
}

Upvotes: -1

SamiHuutoniemi
SamiHuutoniemi

Reputation: 1595

Set the birtdate's year explicitly to DateTime.Today.Year, and it will compare just fine.

Upvotes: 0

Related Questions