Here is a problem. I have seen many solutions, but no one seems to be fulfilling the criteria I want...
I want to display the age in this format
20 y
Age is pretty tricky. Here's the relevant excerpts from a struct I use.
public struct Age
{
private readonly Int32 _years;
private readonly Int32 _months;
private readonly Int32 _days;
private readonly Int32 _totalDays;
///
/// Initializes a new instance of .
///
/// The date and time when the age started.
/// The date and time when the age ended.
/// This
public Age(DateTime start, DateTime end)
: this(start, end, CultureInfo.CurrentCulture.Calendar)
{
}
///
/// Initializes a new instance of .
///
/// The date and time when the age started.
/// The date and time when the age ended.
/// Calendar used to calculate age.
public Age(DateTime start, DateTime end, Calendar calendar)
{
if (start > end) throw new ArgumentException("The starting date cannot be later than the end date.");
var startDate = start.Date;
var endDate = end.Date;
_years = _months = _days = 0;
_days += calendar.GetDayOfMonth(endDate) - calendar.GetDayOfMonth(startDate);
if (_days < 0)
{
_days += calendar.GetDaysInMonth(calendar.GetYear(startDate), calendar.GetMonth(startDate));
_months--;
}
_months += calendar.GetMonth(endDate) - calendar.GetMonth(startDate);
if (_months < 0)
{
_months += calendar.GetMonthsInYear(calendar.GetYear(startDate));
_years--;
}
_years += calendar.GetYear(endDate) - calendar.GetYear(startDate);
var ts = endDate.Subtract(startDate);
_totalDays = (Int32)ts.TotalDays;
}
///
/// Gets the number of whole years something has aged.
///
public Int32 Years
{
get { return _years; }
}
///
/// Gets the number of whole months something has aged past the value of .
///
public Int32 Months
{
get { return _months; }
}
///
/// Gets the age as an expression of whole months.
///
public Int32 TotalMonths
{
get { return _years * 12 + _months; }
}
///
/// Gets the number of whole weeks something has aged past the value of and .
///
public Int32 Days
{
get { return _days; }
}
///
/// Gets the total number of days that have elapsed since the start and end dates.
///
public Int32 TotalDays
{
get { return _totalDays; }
}
///
/// Gets the number of whole weeks something has aged past the value of and .
///
public Int32 Weeks
{
get { return (Int32) Math.Floor((Decimal) _days/7); }
}
///
/// Gets the age as an expression of whole weeks.
///
public Int32 TotalWeeks
{
get { return (Int32) Math.Floor((Decimal) _totalDays/7); }
}
}
Here's an example unit test that passes:
[Test]
public void Should_be_exactly_20_years_old()
{
var now = DateTime.Now;
var age = new Age(now.AddYears(-20), now);
Assert.That(age, Has.Property("Years").EqualTo(20)
.And.Property("Months").EqualTo(0)
.And.Property("Days").EqualTo(0));
}