NextAnniversary
Calculates the next anniversary of an event after the initial date on the Gregorian calendar. Use the original event date or the event month/event day as a parameters. The optional parameter, preserveMonth will determine how to handle an event date of 2/29. Set to true will use February 28 for a standard year anniversary and set to false will use March 1 for a standard year anniversary.
Source
public static class DateExtensions
{
static public DateTime NextAnniversary(this DateTime dt, DateTime eventDate, bool preserveMonth = false)
{
DateTime calcDate;
if (dt.Date < eventDate.Date) // Return the original event date if it occurs later than initial input date.
return new DateTime(eventDate.Year, eventDate.Month, eventDate.Day, 0, 0, 0, dt.Kind);
calcDate = new DateTime(dt.Year + (dt.Month < eventDate.Month || dt.Month == eventDate.Month && dt.Day < eventDate.Day ? 0 : 1), eventDate.Month, 1, 0, 0, 0, dt.Kind).AddDays(eventDate.Day - 1);
if (eventDate.Month == calcDate.Month || !preserveMonth)
return calcDate;
else
return calcDate.AddYears(dt.Month == 2 && dt.Day == 28 ? 1 : 0).AddDays(-1);
}
static public DateTime NextAnniversary(this DateTime dt, int eventMonth, int eventDay, bool preserveMonth = false)
{
DateTime calcDate;
if (eventDay > 31 || eventDay < 1 || eventMonth > 12 || eventMonth < 1 ||
((eventMonth == 4 || eventMonth == 6 || eventMonth == 9 || eventMonth == 11) && eventDay > 30) ||
(eventMonth == 2 && eventDay > 29))
throw new Exception("Invalid combination of Event Year and Event Month.");
calcDate = new DateTime(dt.Year + (dt.Month < eventMonth || dt.Month == eventMonth && dt.Day < eventDay ? 0 : 1), eventMonth, 1, 0, 0, 0, dt.Kind).AddDays(eventDay - 1);
if (eventMonth == calcDate.Month || !preserveMonth)
return calcDate;
else
return calcDate.AddYears(dt.Month == 2 && dt.Day == 28 ? 1 : 0).AddDays(-1);
}
}
Example
DateTime hireDate = new DateTime(1998, 10, 5);
DateTime nextHireAnnivers = DateTime.Now.NextAnniversary(hireDate); // Returns the next occurance of October 5.
DateTime nextAnnivers = DateTime.Now.NextAnniversary(12, 16); // Returns the next occurance of December 16.
DateTime leapDayEvent = DateTime.Now.NextAnniversary(2, 29, true); // Returns the next occurance of February 28 or February 29 depending on if the next anniversary is in a leap year.