A: 

I don't really understand why you would make this an HTML Helper. I would make it part of the ViewData dictionary in an action method of the controller. Something like this:

ViewData["Age"] = DateTime.Now.Year - birthday.Year;

Given that birthday is passed into an action method and is a DateTime object.

Jacob R
doesn't work if someone was born in `'2009-12-31'`; in `'2010-01-01'` already have one year?
Rubens Farias
+4  A: 

Stackoverflow uses such function to determine the age of a user.

http://stackoverflow.com/questions/9/how-do-i-calculate-someones-age-in-c

The given answer is

DateTime now = DateTime.Today;
int age = now.Year - bday.Year;
if (now < bday.AddYears(age)) age--;

So your helper method would look like

public static string Age(this HtmlHelper helper, DateTime birthday)
{
    DateTime now = DateTime.Today;
    int age = now.Year - birthday.Year;
    if (now < birthday.AddYears(age)) age--;

    return age.ToString();
}
Pierre-Alain Vigeant
Why not just `new DateTime(DateTime.Now.Subtract(birthDate.Ticks).Year - 1`?
Steven Sudit
On a side note, what's the right behavior for birthdates in the future? Return a negative number? Throw? Also, do people literally born yesterday have an age of 0 years?
Steven Sudit
@Steven Someone that is not yet born should always have a age of 0, imo.You only have 1 year at the end of that year. That's the same debate that occurred on y2k. We celebrated the change in date, but the 2000ieth year was complete only at the start of 2001, so we should have been celebrating the 2000ieth year at the start of 2001 not at the start of 2000.
Pierre-Alain Vigeant
Perhaps if we wanted to return 0 for future births, we could do something like: `return (new DateTime(Math.Max(0, DateTime.Now.Substract(birthDate.Ticks)).Year - 1)`
Steven Sudit
There are some cultures that count the first year of the baby's life as #1.
BillW
And still others that count birthdays in terms of reaching a specific time of year. I was restricting myself to en-us, though. :-)
Steven Sudit
A: 

I do it like this:

(Shortened the code a bit)

public struct Age { public readonly int Years; public readonly int Months; public readonly int Days;

public Age( int y, int m, int d ) : this()
{
    Years = y;
    Months = m;
    Days = d;
}

public static Age CalculateAge ( DateTime birthDate, DateTime anotherDate )
{
    if( startDate.Date > endDate.Date )
        {
            throw new ArgumentException ("startDate cannot be higher then endDate", "startDate");
        }

        int years = endDate.Year - startDate.Year;
        int months = 0;
        int days = 0;

        // Check if the last year, was a full year.
        if( endDate < startDate.AddYears (years) && years != 0 )
        {
            years--;
        }

        // Calculate the number of months.
        startDate = startDate.AddYears (years);

        if( startDate.Year == endDate.Year )
        {
            months = endDate.Month - startDate.Month;
        }
        else
        {
            months = ( 12 - startDate.Month ) + endDate.Month;
        }

        // Check if last month was a complete month.
        if( endDate < startDate.AddMonths (months) && months != 0 )
        {
            months--;
        }

        // Calculate the number of days.
        startDate = startDate.AddMonths (months);

        days = ( endDate - startDate ).Days;

        return new Age (years, months, days);
}

// Implement Equals, GetHashCode, etc... as well
// Overload equality and other operators, etc...

}

Frederik Gheysels
A: 

Another cleaver way from that ancient thread:

int age = (
    Int32.Parse(DateTime.Today.ToString("yyyyMMdd")) - 
    Int32.Parse(birthday.ToString("yyyyMMdd"))) / 10000;
Rubens Farias