473,750 Members | 2,265 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Calculate age / age next birthday from date of birth without using DateDiff solution

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>
Nov 16 '05 #1
7 15502
Adrian,

I am curious, why are you against linking to Microsoft.Visua lBasic.dll?
It's distributed as part of the framework, it contains code you know works,
it is managed code, and you save the cost of developing, writing, and
maintaining the code yourself?
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m

"Adrian" <ad****@camdaw. net> wrote in message
news:73******** *************** ***@posting.goo gle.com...
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>

Nov 16 '05 #2
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard .caspershouse.c om> wrote:
I am curious, why are you against linking to Microsoft.Visua lBasic.dll?
It's distributed as part of the framework, it contains code you know works,
it is managed code, and you save the cost of developing, writing, and
maintaining the code yourself?


There are often good reasons for not using Microsoft.Visua lBasic.dll:

1) It's unfamiliar to many C# developers (hey, it's not even documented
in the same place as the main framework, and you don't get to see the
documentation unless you've got VB.NET in your filter)

2) There are often more idiomatic ways of doing things using the
standard framework classes

3) The Microsoft.Visua lBasic.dll is less likely to be fully implemented
in other frameworks (such as Mono) than things like DateTime and
TimeSpan

Occasionally a function in the MS.VB assembly does exactly what you
want and it would be a pain to do it using the "normal" .NET classes,
but I would suggest avoiding it in other situations.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #3
I agree witht this somewhat.

Granted, if there is an alternative in the framework itself outside of
MSVB.dll, then I would take that, assuming I get the behavior I want.

However, if there is a solution that only exists in MSVB.dll, which
would require me to write code otherwise, then I can't see the
justification. The maintenance of code is just not worth it (no matter how
small).

From what I can tell, the DateDiff functionality offers a little more
than what the TimeSpan structure offers (also, the original poster indicated
a specific need for the functionality in DateDiff).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m

"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard .caspershouse.c om> wrote:
I am curious, why are you against linking to Microsoft.Visua lBasic.dll? It's distributed as part of the framework, it contains code you know works, it is managed code, and you save the cost of developing, writing, and
maintaining the code yourself?


There are often good reasons for not using Microsoft.Visua lBasic.dll:

1) It's unfamiliar to many C# developers (hey, it's not even documented
in the same place as the main framework, and you don't get to see the
documentation unless you've got VB.NET in your filter)

2) There are often more idiomatic ways of doing things using the
standard framework classes

3) The Microsoft.Visua lBasic.dll is less likely to be fully implemented
in other frameworks (such as Mono) than things like DateTime and
TimeSpan

Occasionally a function in the MS.VB assembly does exactly what you
want and it would be a pain to do it using the "normal" .NET classes,
but I would suggest avoiding it in other situations.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 16 '05 #4
For the pragmatic C# programmer who has no interest calculating age or date
differences in anything other than the Gregorian calendar there is little
reason (as far as I can see) why DateDiff in
Microsoft.Visua lBasic.DateAndT ime should not be used.
I have even read reports (see
http://www.dotnet247.com/247referenc.../14/72863.aspx) that provided you
avoid using legacy methods (e.g. Len(MyString) instead of MyString.Length ())
there is no significant measurable peformance penalty in using whats in
Microsoft.Visua lBasic since it appears to be "native" to the .NET framework.
I really think that these usefull functions should have been put in a
namespace where everyone can find them whatever the .NET language used.

My reasons for a "pure" C# solution:

1. Microsoft.Visua lBasic.DateAndT ime.DateDiff are not found located when you
search on DateDiff and filter by C# in Vis.Studio.NET. so I spent a few
minutes thinking and researching about how I would code it in C# before
searching the newsgroups where I found Microsoft.Visua lBasic.DateAndT ime
existed, by which time I had (re)learned of the globalized calender types.
Having the luxury of time I became attracted to the idea of a solution which
"should" work for other calendar types in System.Globaliz ation which may be
usefull for a future project I have in mind.
2. The application dll is 4K bigger going the DateDiff route (OK hardly
significant).
3. It might be irrational but there are some people out there who insist on
a "pure" C# solution avoiding the Microsoft.Visua lBasic namespace, I became
curious to see if anyone would use a "pure" C# solution and if they were
doing it for reasons other than calendar globalization and what those
reasons might be.

TimeSpan might be the nearest C# equivalent to DateDiff, but TimeSpan will
not give you a date difference in months or years, I needed difference in
years to work out age / age next birthday.

If I was pushed for time and found it in MSDN in what I consider a sensible
place I would have gone the Microsoft.Visua lBasic.DateAndT ime.DateDiff route
and worried about calendar globalization when the need arose.

I have just returned to C# after 2 years programming with VB.NET, I've come
home, stupid I know but I really hate typing "Dim x As Integer" instead of
"int x"; etc. etc. VB.NET makes my fingers ache with all that extra typing.

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard .caspershouse.c om> wrote in
message news:eA******** ******@TK2MSFTN GP09.phx.gbl...
I agree witht this somewhat.

Granted, if there is an alternative in the framework itself outside of
MSVB.dll, then I would take that, assuming I get the behavior I want.

However, if there is a solution that only exists in MSVB.dll, which
would require me to write code otherwise, then I can't see the
justification. The maintenance of code is just not worth it (no matter how small).

From what I can tell, the DateDiff functionality offers a little more
than what the TimeSpan structure offers (also, the original poster indicated a specific need for the functionality in DateDiff).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m

"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard .caspershouse.c om> wrote:
I am curious, why are you against linking to Microsoft.Visua lBasic.dll? It's distributed as part of the framework, it contains code you know works, it is managed code, and you save the cost of developing, writing, and
maintaining the code yourself?


There are often good reasons for not using Microsoft.Visua lBasic.dll:

1) It's unfamiliar to many C# developers (hey, it's not even documented
in the same place as the main framework, and you don't get to see the
documentation unless you've got VB.NET in your filter)

2) There are often more idiomatic ways of doing things using the
standard framework classes

3) The Microsoft.Visua lBasic.dll is less likely to be fully implemented
in other frameworks (such as Mono) than things like DateTime and
TimeSpan

Occasionally a function in the MS.VB assembly does exactly what you
want and it would be a pain to do it using the "normal" .NET classes,
but I would suggest avoiding it in other situations.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


Nov 16 '05 #5
OK I've fixed my name now ooops.

"news.newnet.co .uk" <ad***********@ nojunk.camdaw.n et> wrote in message
news:41******** *************** @reader.news.ne wnet.co.uk...
For the pragmatic C# programmer who has no interest calculating age or date differences in anything other than the Gregorian calendar there is little
reason (as far as I can see) why DateDiff in
Microsoft.Visua lBasic.DateAndT ime should not be used.
I have even read reports (see
http://www.dotnet247.com/247referenc.../14/72863.aspx) that provided you avoid using legacy methods (e.g. Len(MyString) instead of MyString.Length ()) there is no significant measurable peformance penalty in using whats in
Microsoft.Visua lBasic since it appears to be "native" to the .NET framework. I really think that these usefull functions should have been put in a
namespace where everyone can find them whatever the .NET language used.

My reasons for a "pure" C# solution:

1. Microsoft.Visua lBasic.DateAndT ime.DateDiff are not found located when you search on DateDiff and filter by C# in Vis.Studio.NET. so I spent a few
minutes thinking and researching about how I would code it in C# before
searching the newsgroups where I found Microsoft.Visua lBasic.DateAndT ime
existed, by which time I had (re)learned of the globalized calender types.
Having the luxury of time I became attracted to the idea of a solution which "should" work for other calendar types in System.Globaliz ation which may be usefull for a future project I have in mind.
2. The application dll is 4K bigger going the DateDiff route (OK hardly
significant).
3. It might be irrational but there are some people out there who insist on a "pure" C# solution avoiding the Microsoft.Visua lBasic namespace, I became curious to see if anyone would use a "pure" C# solution and if they were
doing it for reasons other than calendar globalization and what those
reasons might be.

TimeSpan might be the nearest C# equivalent to DateDiff, but TimeSpan will
not give you a date difference in months or years, I needed difference in
years to work out age / age next birthday.

If I was pushed for time and found it in MSDN in what I consider a sensible place I would have gone the Microsoft.Visua lBasic.DateAndT ime.DateDiff route and worried about calendar globalization when the need arose.

I have just returned to C# after 2 years programming with VB.NET, I've come home, stupid I know but I really hate typing "Dim x As Integer" instead of
"int x"; etc. etc. VB.NET makes my fingers ache with all that extra typing.
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard .caspershouse.c om> wrote in message news:eA******** ******@TK2MSFTN GP09.phx.gbl...
I agree witht this somewhat.

Granted, if there is an alternative in the framework itself outside of MSVB.dll, then I would take that, assuming I get the behavior I want.

However, if there is a solution that only exists in MSVB.dll, which
would require me to write code otherwise, then I can't see the
justification. The maintenance of code is just not worth it (no matter

how
small).

From what I can tell, the DateDiff functionality offers a little more than what the TimeSpan structure offers (also, the original poster

indicated
a specific need for the functionality in DateDiff).
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard. caspershouse.co m

"Jon Skeet [C# MVP]" <sk***@pobox.co m> wrote in message
news:MP******** *************** *@msnews.micros oft.com...
Nicholas Paldino [.NET/C# MVP] <mv*@spam.guard .caspershouse.c om> wrote: > I am curious, why are you against linking to

Microsoft.Visua lBasic.dll?
> It's distributed as part of the framework, it contains code you know

works,
> it is managed code, and you save the cost of developing, writing, and > maintaining the code yourself?

There are often good reasons for not using Microsoft.Visua lBasic.dll:

1) It's unfamiliar to many C# developers (hey, it's not even documented in the same place as the main framework, and you don't get to see the
documentation unless you've got VB.NET in your filter)

2) There are often more idiomatic ways of doing things using the
standard framework classes

3) The Microsoft.Visua lBasic.dll is less likely to be fully implemented in other frameworks (such as Mono) than things like DateTime and
TimeSpan

Occasionally a function in the MS.VB assembly does exactly what you
want and it would be a pain to do it using the "normal" .NET classes,
but I would suggest avoiding it in other situations.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too



Nov 16 '05 #6
news.newnet.co. uk <ad***********@ nojunk.camdaw.n et> wrote:
For the pragmatic C# programmer who has no interest calculating age or date
differences in anything other than the Gregorian calendar there is little
reason (as far as I can see) why DateDiff in
Microsoft.Visua lBasic.DateAndT ime should not be used.
I have even read reports (see
http://www.dotnet247.com/247referenc.../14/72863.aspx) that provided you
avoid using legacy methods (e.g. Len(MyString) instead of MyString.Length ())
there is no significant measurable peformance penalty in using whats in
Microsoft.Visua lBasic since it appears to be "native" to the .NET framework.
It depends on exactly what you're doing - sometimes there *is* a
performance penalty because some VB functions do a lot more than you
need them to. (Other times they do exactly what you need and no more.)
I really think that these usefull functions should have been put in a
namespace where everyone can find them whatever the .NET language used.


I think some of them should possibly have been included in
TimeSpan/DateTime etc. A lot of other ones have direct equivalents in
the library already.

<snip>

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #7
Adrian

So, your just after something in C# to work out the ANB.

Apologies if i've gotten the wrong end of the stick.

/// <summary>
/// Returns the age next birthday

/// Note that if the current day is the birthday then the younger age will
be taken

/// this is to keep in line with both the LAP and POS systems.

/// </summary>

/// <param name="dob"></param>

/// <returns></returns>

public static int AgeNextBirthday (DateTime dob)

{

return AgeNextBirthday (DateTime.Now, dob);

}

public static int AgeNextBirthday (DateTime fromDate, DateTime dob)

{

int yearDifference = fromDate.Year - dob.Year;

int ageNextBirthday ;

if(fromDate.Mon th > dob.Month)

{

ageNextBirthday = yearDifference + 1;

}

else if (fromDate.Month == dob.Month)

{

if (fromDate.Day > dob.Day)

{

ageNextBirthday = yearDifference + 1;

}

else

{

ageNextBirthday = yearDifference;

}

}

else

{

ageNextBirthday = yearDifference;

}
return ageNextBirthday ;

}

Glenn

"Adrian" <ad****@camdaw. net> wrote in message
news:73******** *************** ***@posting.goo gle.com...
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>

Nov 16 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
11856
by: Gav | last post by:
I have a database with date of births stored dd/mm/yyyy (english dating system) and =date() returns a date in the same format in my server. how do i find the persons age using these two pieces of date. thanks gavin
3
5587
by: Alan Mews | last post by:
Hi All Being a Newbie and tried very hard to get my Database (Access) to calculate the age of a person, in years, from the Date of Birth. The Fields are: DateofBirth minus Today's Date =Age, in years, of person. Any help will be much appreciated.
4
9339
by: Jan Szymczuk | last post by:
I'm creating an MS Access 2000 database where I have a number of people entered using simple basic fields, Surname: SMITH Forenames: John DoB: 09/09/1958 Age: (this needs to be automated to show years e.g. 46) I am trying to get the age to be automatically shown after a persons DoB (date of birth) is entered into the DoB field. I have tried using this formula in the Control Source of the Age field...
8
8236
by: TJS | last post by:
what namespaces are required so I can do a simple calculate age from date of birth ?
2
2487
by: David Garamond | last post by:
What would be the more proper way of storing birthday data? It will be used to send out birthday messages for customers ("Happy 30th birthday, Sam!"). But the date of birth is not necessarily known (in which case, we will only send out "Happy birthday, Sam!"). I prefer using the builtin date type instead of three smallints. But I don't like having to arbitrarily set, say, year 1000 AD or 1 BC to represent "unknown year". Any thoughts?
6
6193
by: birchw | last post by:
Hi, I downloaded a function from the Microsoft Knowledge base to calculate a persons age as at the current date based on DOB. The function is as follows: Function Age(varBirthDate As Variant) As Integer Dim varAge As Variant If IsNull(varBirthDate) Then Age = 0: Exit Function varAge = DateDiff("yyyy", varBirthDate, Now)
8
17577
by: helpless | last post by:
Access 2003 - I am trying to calculate the difference between a specific date 5/1/2007 (not in a data field) and other dates that ARE in a field called Birth Date. I am trying to have it fill into an Age field (in years only) by comparing the date above to the Birth Date field. I have tried this and it doesn't work: =DateDiff("yyyy", , ) Displays the variance in years between the values of the Birthday1 and Birthday2 fields. (from Access...
9
2181
by: howzit | last post by:
I have a set date in my MySQL database that records when a Sales Lead is established and I echo that date as $row_rsLead; I need to be able to calculate how many days that lead has existed. $row_rsLead; outputs as 2007-06-14. I have made numerous attempts to create a function that will calculate the days between the lead_date and today's date, but have made absolutely no headway. I am either stuck working between differing date...
15
6438
by: student4lifer | last post by:
Hello, I have 2 time fields dynamically generated in format "m/d/y H:m". Could someone show me a good function to calculate the time interval difference in minutes? I played with strtotime() but but that only gave me difference in hours and only if the times were on the same day (after wrapping with date() function). TIA
0
8838
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9577
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8260
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6804
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6081
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4713
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3322
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2804
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2225
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.