im in ur web, enriching ur code

 
 

Building an Age Class in C#

It may seem like a fairly inconsequential idea since we already have the DateTime and TimeSpan structs. You can take two DateTime instances and easily calculate a TimeSpan. Once you have the TimeSpan, you can retrieve the Days property, divide that by 365 for the round about number of years and you're good to go.

But wait, you can display that as an integer, or perhaps as a decimal for a bit more accuracy, but what if you want a human readable and understandable string like years and months? or even weeks, days or seconds for even younger things?

The C# Vitamins Age encapsulates that functionality into one convenient class that ultimately saves you time! Is that a pun I see before me? Sorry, on to the code...

Using the Age object

DateTime birthdate = new DateTime( 1978, 5, 31 );
 
/// creating an Age with a single DateTime argument will
/// calulate the age between that date and the current DateTime.
Age currentAge = new Age( birthdate );
 
/// or to create a specific age
Age fixedAge = new Age( birthdate, new DateTime( 2007, 5, 24, 14, 19, 23 ) );
 
/// to display the age 
/// e.g. 28 years 11 months 3 weeks 4 days 14 hours 19 minutes 23 seconds
Console.WriteLine( fixedAge.ToString() ); 
 
/// to control the length of the string simply pass 
/// in the number of parts to include
Console.WriteLine( fixedAge.ToString( 2 ) );
Console.WriteLine( fixedAge.ToString( 3 ) );
Console.WriteLine( string.Format( "{0:4}", fixedAge ) );
 
/// the result from the last three statements are:
/// 28 years 11 months
/// 28 years 11 months 3 weeks
/// 28 years 11 months 3 weeks 4 days

Access to the actual DateTime's and the elapsed TimeSpan are also available:

TimeSpan time = currentAge.Elapsed;
DateTime bornOn = currentAge.Advent;
DateTime stillGoingAt = currentAge.Terminus;

This is quite handy for exposing from your business objects. e.g.

public class Customer
{
    // .. class constructors, members etc
 
    DateTime _created = DateTime.Now;
 
    public DateTime Created
    {
        get { return _created; }
    }
 
    public Age AccountAge
    {
        get { return new Age( _created ); }
    }
 
    // .. other class memebers etc
}

Then you can use like so:

Customer customer = new Customer();
Console.WriteLine( customer.AccountAge );
/// which actually prints "less than a second"

An Equality Quandary

Age's are sortable and comparable in the context of how we think of age i.e. the value of the age. They are essentially TimeSpans.

However, depending on the context, this becomes a little bit of a contentious issue. If we think about age, we think about a number. Often we say we are the same age as someone else if we were both born in the same year, but logically, we're not of equal age unless we were born at precisely the same time.

Or if you will allow me an analogy. My first DVD Player lasted 3 years and 1 day before it imploded, (let's say conveniently just after the manufacturers warranty expired). After that, a few months passed before getting the next DVD Player and it, funnily enough, also lasted exactly 3 years and 1 day!

Both DVD Players were exactly the same age. But the dates that they started and ended with are completely different.

So the question is, if each age has different start and end dates, but the same elapsed time, can they be equal?

My first thoughts were to work off the elapsed time, so yes. But it's a little ambiguous, so I've purposely left the implementation for Equals and GetHashCode out of this version for the time being (although one answer is included in the source, just commented out).

How do You think it should be handled?

You can download the Age class source code here.

 

PS: No DVD Players were harmed in the making of this blog post - I've actually only ever owned one, and it's still going :)

kick it on DotNetKicks.com

Posted on Tuesday, May 01, 2007 12:33 PM
Filed Under [ C#, Tips, Source Code ]

Comments

Gravatar
# re: Building an Age Class in C#
Posted by TJ
Posted on 2/2/2008 9:35 AM
Thanks a ton for this. It's helped a lot.
Gravatar
# re: Building an Age Class in C#
Posted by Jeroen
Posted on 1/24/2009 4:02 AM
Made it also usable for not born ages with a trick:
in constructor:
if (advent < terminus)
{
_advent = advent;
_terminus = terminus;
_notBorn = false;
}
else
{
_notBorn = true;
_advent = terminus;
_terminus = advent;
}

and in ToString

StringBuilder result = new StringBuilder();
if (_notBorn)
result.Append('-');

Could be done better but it works for me.

Post Comment

Title *
Name *
Email
Url
Comment *  
Please add 7 and 2 and type the answer here:
 

About C# Vitamins

Dave has been working in the industry for around 10 years, and has a focus on Javascript, C#, ASP.NET and SQL Server web development; not to mention being a standards driven type of guy.

C# Vitamins is the result of a lot of years hard work in the web industry and a desire to share with the community; and if it was traced back far enough, you might say it might not have existed if he hadn't taken such an interest in id Software's original Quake.

Related Links

Below is a list of related links of Dave's other sites.