I hit on this problem converting a VB.NET insurance application to C#.
Age next birthday calculated from date of birth is often needed in
insurance premium calculations.
Originally done using DateDiff in VB.NET which is only available in C#
if you don't mind linking in Microsoft.Visua lBasic.dll to your C#
application.
I wanted to avoid this so set about a pure C# solution which uses a
combination of TimeSpan in whole days and the
System.Globaliz arion.Calendar class GetDaysInYear() function to work
it out.
The added advantage here over DateDiff is this function should work
with all the different System.Globaliz ation.Calendar types (Japanese
etc.), however I have only tested it with GregorianCalend ar.
Here is the C# source code which includes a console application test
harness.
To get "Age" rather than "Age next birthday" just subtract 1 from this
result (sorry for pointing out the obvious!)
<code>
using System;
namespace WorkbenchCSCons ole
{
/// <summary>
/// Summary description for AgeNextBirtdatC alculator.
/// </summary>
class AgeNextBirtdatC alculator
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// Test harness for AgeNextBirthday function
//
int AgeNextBirthday ;
DateTime DOB;
DateTime DateNow;
System.Globaliz ation.Calendar MyCalendar = new
System.Globaliz ation.Gregorian Calendar(); // should work with other
calendars
DateNow = DateTime.Now;
System.Console. WriteLine("Cale ndar independant date of birth to
age NEXT birtday function (commonly required in the insurance
industry) for C# written by Adrian Hilder, Camdaw Limited
www.camdaw.net. You are free to use and distribute this function in
your applications, you may not sell it for profit as a stand alone
utility without prior consent from Camdaw Limited.\nThis function is
provided as is in the hope it is usefull with no warrantee of any
kind. You should test this function to your satisfaction before using
it in your applications.\n If you do find any faults please tell
me!\nIf you use this please tell me, I'm interested to know if anyone
uses it (it was about 3 hours work). (contact details at
www.camdaw.net) \n\n");
DOB = DateTime.MinVal ue;
DOB = DOB.AddYears(19 70-1);
DOB = DOB.AddMonths(D ateNow.Month-1);
DOB = DOB.AddDays(Dat eNow.Day-2);
System.Console. WriteLine("Cale ndar type: " +
MyCalendar.ToSt ring() + "\n");
System.Console. WriteLine("Test ing with todays date " +
DateNow.Day + "/" + DateNow.Month + "/" + DateNow.Year + "
(dd/mm/yyyy)\n");
Console.WriteLi ne("Test with DOB yesterdays date in 1970");
System.Console. WriteLine("DOB entered: " + DOB.Day + "/" +
DOB.Month + "/" + DOB.Year + " (dd/mm/yyyy)");
AgeNextBirthday = DOBToAgeNextBir thday(DOB, MyCalendar);
System.Console. WriteLine("AgeN extBirthdayYear s=" +
AgeNextBirthday + "\n");
Console.WriteLi ne("Test with DOB tommorrows date in 1970");
DOB = DateTime.MinVal ue;
DOB = DOB.AddYears(19 70-1);
DOB = DOB.AddMonths(D ateNow.Month-1);
DOB = DOB.AddDays(Dat eNow.Day);
System.Console. WriteLine("DOB entered: " + DOB.Day + "/" +
DOB.Month + "/" + DOB.Year + " (dd/mm/yyyy)");
AgeNextBirthday = DOBToAgeNextBir thday(DOB, MyCalendar);
System.Console. WriteLine("AgeN extBirthdayYear s=" +
AgeNextBirthday + "\n");
Console.WriteLi ne("Test with DOB this day in 1970");
DOB = DateTime.MinVal ue;
DOB = DOB.AddYears(19 70-1);
DOB = DOB.AddMonths(D ateNow.Month-1);
DOB = DOB.AddDays(Dat eNow.Day-1);
System.Console. WriteLine("DOB entered: " + DOB.Day + "/" +
DOB.Month + "/" + DOB.Year + " (dd/mm/yyyy) ... Happy Birthday!");
AgeNextBirthday = DOBToAgeNextBir thday(DOB, MyCalendar);
System.Console. WriteLine("AgeN extBirthdayYear s=" +
AgeNextBirthday + "\n");
while(!(MyCalen dar.IsLeapYear( DateNow.Year)))
DateNow = DateNow.AddYear s(1);
System.Console. WriteLine("Test ing with the next leap year date "
+ DateNow.Day + "/" + DateNow.Month + "/" + DateNow.Year + "
(dd/mm/yyyy)\n");
System.Console. WriteLine("Note : this DOBToAgeNextBir thday
function and test harness was written 3rd August 2004, which was a
leap year.");
Console.WriteLi ne("Test with DOB yesterdays date in 1970");
System.Console. WriteLine("DOB entered: " + DOB.Day + "/" +
DOB.Month + "/" + DOB.Year + " (dd/mm/yyyy)");
AgeNextBirthday = DOBToAgeNextBir thday(DOB, MyCalendar);
System.Console. WriteLine("AgeN extBirthdayYear s=" +
AgeNextBirthday + "\n");
Console.WriteLi ne("Test with DOB tommorrows date in 1970");
DOB = DateTime.MinVal ue;
DOB = DOB.AddYears(19 70-1);
DOB = DOB.AddMonths(D ateNow.Month-1);
DOB = DOB.AddDays(Dat eNow.Day);
System.Console. WriteLine("DOB entered: " + DOB.Day + "/" +
DOB.Month + "/" + DOB.Year + " (dd/mm/yyyy)");
AgeNextBirthday = DOBToAgeNextBir thday(DOB, MyCalendar);
System.Console. WriteLine("AgeN extBirthdayYear s=" +
AgeNextBirthday + "\n");
Console.WriteLi ne("Test with DOB this day in 1970");
DOB = DateTime.MinVal ue;
DOB = DOB.AddYears(19 70-1);
DOB = DOB.AddMonths(D ateNow.Month-1);
DOB = DOB.AddDays(Dat eNow.Day-1);
System.Console. WriteLine("DOB entered: " + DOB.Day + "/" +
DOB.Month + "/" + DOB.Year + " (dd/mm/yyyy) ... Happy Birthday!");
AgeNextBirthday = DOBToAgeNextBir thday(DOB, MyCalendar);
System.Console. WriteLine("AgeN extBirthdayYear s=" +
AgeNextBirthday + "\n");
}
private static int DOBToAgeNextBir thday(DateTime DOB,
System.Globaliz ation.Calendar ThisCalendar)
{
int DaysPassedInYea r;
DateTime Now;
int YearIndex;
int DiffDays;
Now = DateTime.Now;
DiffDays = (int)Now.Subtra ct(DOB).TotalDa ys;
YearIndex = 0;
DaysPassedInYea r = CalcDaysPassedI nYear(Now, DOB, YearIndex,
ThisCalendar);
while(DiffDays > DaysPassedInYea r)
{
DiffDays = DiffDays - DaysPassedInYea r;
YearIndex++; // on to next year
DaysPassedInYea r = CalcDaysPassedI nYear(Now, DOB, YearIndex,
ThisCalendar);
}
// Now handle last part year
if (DiffDays > 0) // if still some days to account for
{
int DaysPassedToBir thday;
DaysPassedInYea r = CalcDaysPassedI nYear(Now, DOB, -1,
ThisCalendar);
DaysPassedToBir thday =
CalcDaysPassedI nYear(DOB.AddYe ars(YearIndex), DOB, -1, ThisCalendar);
if (DaysPassedInYe ar >= DaysPassedToBir thday)
YearIndex++; // birthday has passed this year
}
return YearIndex;
}
private static int CalcDaysPassedI nYear(DateTime Now, DateTime
DOB, int YearIndex, System.Globaliz ation.Calendar ThisCalendar)
{
DateTime PartYearStartDa te; // 1st Jan <PartYear>
int YearDaysPassed;
int DaysPassedInYea r;
if (YearIndex == 0) // days in starting (DOB) part year
{
PartYearStartDa te = DateTime.MinVal ue;
PartYearStartDa te = PartYearStartDa te.AddYears(DOB .Year-1);
YearDaysPassed =
(int)DOB.Subtra ct(PartYearStar tDate).TotalDay s;
DaysPassedInYea r = ThisCalendar.Ge tDaysInYear(DOB .Year) -
YearDaysPassed;
}
else if (YearIndex == -1) // -1 used to indicate last year in
period, i.e. Now.Year
{
PartYearStartDa te = DateTime.MinVal ue;
PartYearStartDa te.AddYears(Now .Year);
DaysPassedInYea r =
(int)Now.Subtra ct(PartYearStar tDate).TotalDay s;
}
else // a year within the period
{
DaysPassedInYea r = ThisCalendar.Ge tDaysInYear(DOB .Year +
YearIndex);
}
return DaysPassedInYea r;
}
}
}
</code>