Reputation: 5895
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
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
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
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
Reputation: 1595
Set the birtdate's year explicitly to DateTime.Today.Year
, and it will compare just fine.
Upvotes: 0