# 我如何计算C＃中的某个人的年龄？

` `// Save today's date. var today = DateTime.Today; // Calculate the age. var age = today.Year - birthdate.Year; // Go back to the year the person was born in case of a leap year if (birthdate > today.AddYears(-age)) age--;` `

` `20080814 - 19800703 = 280111` `

C＃代码：

` `int now = int.Parse(DateTime.Now.ToString("yyyyMMdd")); int dob = int.Parse(dateOfBirth.ToString("yyyyMMdd")); int age = (now - dob) / 10000;` `

` `public static Int32 GetAge(this DateTime dateOfBirth) { var today = DateTime.Today; var a = (today.Year * 100 + today.Month) * 100 + today.Day; var b = (dateOfBirth.Year * 100 + dateOfBirth.Month) * 100 + dateOfBirth.Day; return (a - b) / 10000; }` `

` `DateTime bDay = new DateTime(2000, 2, 29); DateTime now = new DateTime(2009, 2, 28); MessageBox.Show(string.Format("Test {0} {1} {2}", CalculateAgeWrong1(bDay, now), // outputs 9 CalculateAgeWrong2(bDay, now), // outputs 9 CalculateAgeCorrect(bDay, now))); // outputs 8` `

` `public int CalculateAgeWrong1(DateTime birthDate, DateTime now) { return new DateTime(now.Subtract(birthDate).Ticks).Year - 1; } public int CalculateAgeWrong2(DateTime birthDate, DateTime now) { int age = now.Year - birthDate.Year; if (now < birthDate.AddYears(age)) age--; return age; } public int CalculateAgeCorrect(DateTime birthDate, DateTime now) { int age = now.Year - birthDate.Year; if (now.Month < birthDate.Month || (now.Month == birthDate.Month && now.Day < birthDate.Day)) age--; return age; }` `

1. 列表项目

int age = birthDate.Age（）;

` `public static class DateTimeExtensions { /// <summary> /// Calculates the age in years of the current System.DateTime object today. /// </summary> /// <param name="birthDate">The date of birth</param> /// <returns>Age in years today. 0 is returned for a future date of birth.</returns> public static int Age(this DateTime birthDate) { return Age(birthDate, DateTime.Today); } /// <summary> /// Calculates the age in years of the current System.DateTime object on a later date. /// </summary> /// <param name="birthDate">The date of birth</param> /// <param name="laterDate">The date on which to calculate the age.</param> /// <returns>Age in years on a later day. 0 is returned as minimum.</returns> public static int Age(this DateTime birthDate, DateTime laterDate) { int age; age = laterDate.Year - birthDate.Year; if (age > 0) { age -= Convert.ToInt32(laterDate.Date < birthDate.Date.AddYears(age)); } else { age = 0; } return age; } }` `

` `class Program { static void Main(string[] args) { RunTest(); } private static void RunTest() { DateTime birthDate = new DateTime(2000, 2, 28); DateTime laterDate = new DateTime(2011, 2, 27); string iso = "yyyy-MM-dd"; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { Console.WriteLine("Birth date: " + birthDate.AddDays(i).ToString(iso) + " Later date: " + laterDate.AddDays(j).ToString(iso) + " Age: " + birthDate.AddDays(i).Age(laterDate.AddDays(j)).ToString()); } } Console.ReadKey(); } }` `

` `{ Birth date: 2000-02-28 Later date: 2011-02-27 Age: 10 Birth date: 2000-02-28 Later date: 2011-02-28 Age: 11 Birth date: 2000-02-28 Later date: 2011-03-01 Age: 11 Birth date: 2000-02-29 Later date: 2011-02-27 Age: 10 Birth date: 2000-02-29 Later date: 2011-02-28 Age: 11 Birth date: 2000-02-29 Later date: 2011-03-01 Age: 11 Birth date: 2000-03-01 Later date: 2011-02-27 Age: 10 Birth date: 2000-03-01 Later date: 2011-02-28 Age: 10 Birth date: 2000-03-01 Later date: 2011-03-01 Age: 11 }` `

` `{ Birth date: 2000-02-28 Later date: 2012-02-28 Age: 12 Birth date: 2000-02-28 Later date: 2012-02-29 Age: 12 Birth date: 2000-02-28 Later date: 2012-03-01 Age: 12 Birth date: 2000-02-29 Later date: 2012-02-28 Age: 11 Birth date: 2000-02-29 Later date: 2012-02-29 Age: 12 Birth date: 2000-02-29 Later date: 2012-03-01 Age: 12 Birth date: 2000-03-01 Later date: 2012-02-28 Age: 11 Birth date: 2000-03-01 Later date: 2012-02-29 Age: 11 Birth date: 2000-03-01 Later date: 2012-03-01 Age: 12 }` `

` `int age = (int) ((DateTime.Now - bday).TotalDays/365.242199);` `

` `public static int GetAge(DateTime birthDate) { DateTime n = DateTime.Now; // To avoid a race condition around midnight int age = n.Year - birthDate.Year; if (n.Month < birthDate.Month || (n.Month == birthDate.Month && n.Day < birthDate.Day)) age--; return age; }` `

` `int age = new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year-1;` `

2要解决的主要问题是：

1.计算精确年龄 – 年，月，日等

2.计算一般认为的年龄 – 人们通常不关心他们到底有多大年纪，他们只关心当年的生日。

1的解决scheme显而易见：

` `DateTime birth = DateTime.Parse("1.1.2000"); DateTime today = DateTime.Today; //we usually don't care about birth time TimeSpan age = today - birth; //.NET FCL should guarantee this as precise double ageInDays = age.TotalDays; //total number of days ... also precise double daysInYear = 365.2425; //statistical value for 400 years double ageInYears = ageInDays / daysInYear; //can be shifted ... not so precise` `

` `DateTime birth = DateTime.Parse("1.1.2000"); DateTime today = DateTime.Today; int age = today.Year - birth.Year; //people perceive their age in years if (today.Month < birth.Month || ((today.Month == birth.Month) && (today.Day < birth.Day))) { age--; //birthday in current year not yet reached, we are 1 year younger ;) //+ no birthday for 29.2. guys ... sorry, just wrong date for birth }` `

• 这是我首选的解决scheme
• 我们不能使用DateTime.DayOfYear或TimeSpans，因为它们在闰年中移动了多less天
• 为了便于阅读，我已经放了多less行

` `public static int GetAge(DateTime bithDay, DateTime today) { //chosen solution method body } public static int GetAge(DateTime birthDay) { return GetAge(birthDay, DateTime.Now); }` `

` `public static int GetAge(this DateTime dateOfBirth, DateTime dateAsAt) { return dateAsAt.Year - dateOfBirth.Year - (dateOfBirth.DayOfYear < dateAsAt.DayOfYear ? 0 : 1); }` `

（不可否认，这对于在Stack Overflow中显示用户configuration文件是有点噱头的，但也许读者会发现它的一些用处:-)）

` `double AgeDiff(DateTime date1, DateTime date2) { double years = date2.Year - date1.Year; /* * If date2 and date1 + round(date2 - date1) are on different sides * of 29 February, then our partial year is considered to have 366 * days total, otherwise it's 365. Note that 59 is the day number * of 29 Feb. */ double fraction = 365 + (DateTime.IsLeapYear(date2.Year) && date2.DayOfYear >= 59 && (date1.DayOfYear < 59 || date1.DayOfYear > date2.DayOfYear) ? 1 : 0); /* * The only really nontrivial case is if date1 is in a leap year, * and date2 is not. So let's handle the others first. */ if (DateTime.IsLeapYear(date2.Year) == DateTime.IsLeapYear(date1.Year)) return years + (date2.DayOfYear - date1.DayOfYear) / fraction; /* * If date2 is in a leap year, but date1 is not and is March or * beyond, shift up by a day. */ if (DateTime.IsLeapYear(date2.Year)) { return years + (date2.DayOfYear - date1.DayOfYear - (date1.DayOfYear >= 59 ? 1 : 0)) / fraction; } /* * If date1 is not on 29 February, shift down date1 by a day if * March or later. Proceed normally. */ if (date1.DayOfYear != 59) { return years + (date2.DayOfYear - date1.DayOfYear + (date1.DayOfYear > 59 ? 1 : 0)) / fraction; } /* * Okay, here date1 is on 29 February, and date2 is not on a leap * year. What to do now? On 28 Feb in date2's year, the ``age'' * should be just shy of a whole number, and on 1 Mar should be * just over. Perhaps the easiest way is to a point halfway * between those two: 58.5. */ return years + (date2.DayOfYear - 58.5) / fraction; }` `

` `public static class DateTimeExtensions { public static int Age(this DateTime birthDate) { return Age(birthDate, DateTime.Now); } public static int Age(this DateTime birthDate, DateTime offsetDate) { int result=0; result = offsetDate.Year - birthDate.Year; if (offsetDate.DayOfYear < birthDate.DayOfYear) { result--; } return result; } }` `

` `DateTime birthDate = new DateTime(2000,3,1); int age = (int)Math.Floor((DateTime.Now - birthDate).TotalDays / 365.25D);` `

` `DateTime birth = new DateTime(1974, 8, 29); DateTime today = DateTime.Now; TimeSpan span = today - birth; DateTime age = DateTime.MinValue + span; // Make adjustment due to MinValue equalling 1/1/1 int years = age.Year - 1; int months = age.Month - 1; int days = age.Day - 1; // Print out not only how many years old they are but give months and days as well Console.Write("{0} years, {1} months, {2} days", years, months, days);` `

` `using System; using System.Data; using System.Data.Sql; using System.Data.SqlClient; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; public partial class UserDefinedFunctions { [SqlFunction(DataAccess = DataAccessKind.Read)] public static SqlInt32 CalculateAge(string strBirthDate) { DateTime dtBirthDate = new DateTime(); dtBirthDate = Convert.ToDateTime(strBirthDate); DateTime dtToday = DateTime.Now; // get the difference in years int years = dtToday.Year - dtBirthDate.Year; // subtract another year if we're before the // birth day in the current year if (dtToday.Month < dtBirthDate.Month || (dtToday.Month == dtBirthDate.Month && dtToday.Day < dtBirthDate.Day)) years=years-1; int intCustomerAge = years; return intCustomerAge; } };` `

` `public void LoopAge(DateTime myDOB, DateTime FutureDate) { int years = 0; int months = 0; int days = 0; DateTime tmpMyDOB = new DateTime(myDOB.Year, myDOB.Month, 1); DateTime tmpFutureDate = new DateTime(FutureDate.Year, FutureDate.Month, 1); while (tmpMyDOB.AddYears(years).AddMonths(months) < tmpFutureDate) { months++; if (months > 12) { years++; months = months - 12; } } if (FutureDate.Day >= myDOB.Day) { days = days + FutureDate.Day - myDOB.Day; } else { months--; if (months < 0) { years--; months = months + 12; } days += DateTime.DaysInMonth( FutureDate.AddMonths(-1).Year, FutureDate.AddMonths(-1).Month ) + FutureDate.Day - myDOB.Day; } //add an extra day if the dob is a leap day if (DateTime.IsLeapYear(myDOB.Year) && myDOB.Month == 2 && myDOB.Day == 29) { //but only if the future date is less than 1st March if (FutureDate >= new DateTime(FutureDate.Year, 3, 1)) days++; } }` `

` `DateTime birth = new DateTime(1975, 09, 27, 01, 00, 00, 00); TimeSpan ts = DateTime.Now - birth; Console.WriteLine("You are approximately " + ts.TotalSeconds.ToString() + " seconds old.");` `
` `TimeSpan diff = DateTime.Now - birthdayDateTime; string age = String.Format("{0:%y} years, {0:%M} months, {0:%d}, days old", diff);` `

` ` DateTime dateOfBirth = new DateTime(2000, 4, 18); DateTime currentDate = DateTime.Now; int ageInYears = 0; int ageInMonths = 0; int ageInDays = 0; ageInDays = currentDate.Day - dateOfBirth.Day; ageInMonths = currentDate.Month - dateOfBirth.Month; ageInYears = currentDate.Year - dateOfBirth.Year; if (ageInDays < 0) { ageInDays += DateTime.DaysInMonth(currentDate.Year, currentDate.Month); ageInMonths = ageInMonths--; if (ageInMonths < 0) { ageInMonths += 12; ageInYears--; } } if (ageInMonths < 0) { ageInMonths += 12; ageInYears--; } Console.WriteLine("{0}, {1}, {2}", ageInYears, ageInMonths, ageInDays);` `

` `public int AgeInYears(DateTime birthDate, DateTime referenceDate) { Debug.Assert(referenceDate >= birthDate, "birth date must be on or prior to the reference date"); DateTime birth = birthDate.Date; DateTime reference = referenceDate.Date; int years = (reference.Year - birth.Year); // // an offset of -1 is applied if the birth date has // not yet occurred in the current year. // if (reference.Month > birth.Month); else if (reference.Month < birth.Month) --years; else // in birth month { if (reference.Day < birth.Day) --years; } return years ; }` `

• 在英国和香港：这是一年中的第二天，所以第二天的三月一日是你的生日。
• 在新西兰：前一天，2月28日是驾驶执照，3月1日是其他目的。
• 台湾：二月二十八号

` `public enum LeapDayRule { OrdinalDay = 1 , LastDayOfMonth = 2 , } static int ComputeAgeInYears(DateTime birth, DateTime reference, LeapYearBirthdayRule ruleInEffect) { bool isLeapYearBirthday = CultureInfo.CurrentCulture.Calendar.IsLeapDay(birth.Year, birth.Month, birth.Day); DateTime cutoff; if (isLeapYearBirthday && !DateTime.IsLeapYear(reference.Year)) { switch (ruleInEffect) { case LeapDayRule.OrdinalDay: cutoff = new DateTime(reference.Year, 1, 1) .AddDays(birth.DayOfYear - 1); break; case LeapDayRule.LastDayOfMonth: cutoff = new DateTime(reference.Year, birth.Month, 1) .AddMonths(1) .AddDays(-1); break; default: throw new InvalidOperationException(); } } else { cutoff = new DateTime(reference.Year, birth.Month, birth.Day); } int age = (reference.Year - birth.Year) + (reference >= cutoff ? 0 : -1); return age < 0 ? 0 : age; }` `

• 西方（欧洲）的年龄估算，和
• 一个日历，就像公历一样，在一个月的月底插入一个闰日。

` `public static string HowOld(DateTime birthday, DateTime now) { if (now < birthday) throw new ArgumentOutOfRangeException("birthday must be less than now."); TimeSpan diff = now - birthday; int diffDays = (int)diff.TotalDays; if (diffDays > 7)//year, month and week { int age = now.Year - birthday.Year; if (birthday > now.AddYears(-age)) age--; if (age > 0) { return age + (age > 1 ? " years" : " year"); } else {// month and week DateTime d = birthday; int diffMonth = 1; while (d.AddMonths(diffMonth) <= now) { diffMonth++; } age = diffMonth-1; if (age == 1 && d.Day > now.Day) age--; if (age > 0) { return age + (age > 1 ? " months" : " month"); } else { age = diffDays / 7; return age + (age > 1 ? " weeks" : " week"); } } } else if (diffDays > 0) { int age = diffDays; return age + (age > 1 ? " days" : " day"); } else { int age = diffDays; return "just born"; } }` `

` `[TestMethod] public void TestAge() { string age = HowOld(new DateTime(2011, 1, 1), new DateTime(2012, 11, 30)); Assert.AreEqual("1 year", age); age = HowOld(new DateTime(2011, 11, 30), new DateTime(2012, 11, 30)); Assert.AreEqual("1 year", age); age = HowOld(new DateTime(2001, 1, 1), new DateTime(2012, 11, 30)); Assert.AreEqual("11 years", age); age = HowOld(new DateTime(2012, 1, 1), new DateTime(2012, 11, 30)); Assert.AreEqual("10 months", age); age = HowOld(new DateTime(2011, 12, 1), new DateTime(2012, 11, 30)); Assert.AreEqual("11 months", age); age = HowOld(new DateTime(2012, 10, 1), new DateTime(2012, 11, 30)); Assert.AreEqual("1 month", age); age = HowOld(new DateTime(2008, 2, 28), new DateTime(2009, 2, 28)); Assert.AreEqual("1 year", age); age = HowOld(new DateTime(2008, 3, 28), new DateTime(2009, 2, 28)); Assert.AreEqual("11 months", age); age = HowOld(new DateTime(2008, 3, 28), new DateTime(2009, 3, 28)); Assert.AreEqual("1 year", age); age = HowOld(new DateTime(2009, 1, 28), new DateTime(2009, 2, 28)); Assert.AreEqual("1 month", age); age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 3, 1)); Assert.AreEqual("1 month", age); // NOTE. // new DateTime(2008, 1, 31).AddMonths(1) == new DateTime(2009, 2, 28); // new DateTime(2008, 1, 28).AddMonths(1) == new DateTime(2009, 2, 28); age = HowOld(new DateTime(2009, 1, 31), new DateTime(2009, 2, 28)); Assert.AreEqual("4 weeks", age); age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 2, 28)); Assert.AreEqual("3 weeks", age); age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 3, 1)); Assert.AreEqual("1 month", age); age = HowOld(new DateTime(2012, 11, 5), new DateTime(2012, 11, 30)); Assert.AreEqual("3 weeks", age); age = HowOld(new DateTime(2012, 11, 1), new DateTime(2012, 11, 30)); Assert.AreEqual("4 weeks", age); age = HowOld(new DateTime(2012, 11, 20), new DateTime(2012, 11, 30)); Assert.AreEqual("1 week", age); age = HowOld(new DateTime(2012, 11, 25), new DateTime(2012, 11, 30)); Assert.AreEqual("5 days", age); age = HowOld(new DateTime(2012, 11, 29), new DateTime(2012, 11, 30)); Assert.AreEqual("1 day", age); age = HowOld(new DateTime(2012, 11, 30), new DateTime(2012, 11, 30)); Assert.AreEqual("just born", age); age = HowOld(new DateTime(2000, 2, 29), new DateTime(2009, 2, 28)); Assert.AreEqual("8 years", age); age = HowOld(new DateTime(2000, 2, 29), new DateTime(2009, 3, 1)); Assert.AreEqual("9 years", age); Exception e = null; try { age = HowOld(new DateTime(2012, 12, 1), new DateTime(2012, 11, 30)); } catch (ArgumentOutOfRangeException ex) { e = ex; } Assert.IsTrue(e != null); }` `

` `public static int AgeInYears(DateTime birthday, DateTime today) { return ((today.Year - birthday.Year) * 372 + (today.Month - birthday.Month) * 31 + (today.Day - birthday.Day)) / 372; }` `

This has been extensively unit-tested. It does look a bit "magic". The number 372 is the number of days there would be in a year if every month had 31 days.

The explanation of why it works ( lifted from here ) is:

Let's set `Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day`

`age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 372`

We know that what we need is either `Yn-Yb` if the date has already been reached, `Yn-Yb-1` if it has not.

a) If `Mn<Mb` , we have `-341 <= 31*(Mn-Mb) <= -31 and -30 <= Dn-Db <= 30`

`-371 <= 31*(Mn - Mb) + (Dn - Db) <= -1`

With integer division

`(31*(Mn - Mb) + (Dn - Db)) / 372 = -1`

b) If `Mn=Mb` and `Dn<Db` , we have `31*(Mn - Mb) = 0 and -30 <= Dn-Db <= -1`

With integer division, again

`(31*(Mn - Mb) + (Dn - Db)) / 372 = -1`

c) If `Mn>Mb` , we have `31 <= 31*(Mn-Mb) <= 341 and -30 <= Dn-Db <= 30`

`1 <= 31*(Mn - Mb) + (Dn - Db) <= 371`

With integer division

`(31*(Mn - Mb) + (Dn - Db)) / 372 = 0`

d) If `Mn=Mb` and `Dn>Db` , we have `31*(Mn - Mb) = 0 and 1 <= Dn-Db <= 3` 0

With integer division, again

`(31*(Mn - Mb) + (Dn - Db)) / 372 = 0`

e) If `Mn=Mb` and `Dn=Db` , we have `31*(Mn - Mb) + Dn-Db = 0`

and therefore `(31*(Mn - Mb) + (Dn - Db)) / 372 = 0`

This is one of the most accurate answer that is able to resolve the birthday of 29th of Feb compare to any year of 28th Feb.

` `public int GetAge(DateTime birthDate) { int age = DateTime.Now.Year - birthDate.Year; if (birthDate.DayOfYear > DateTime.Now.DayOfYear) age--; return age; }` `

This is not a direct answer, but more of a philosophical reasoning about the problem at hand from a quasi-scientific point of view.

I would argue that the question does not specify the unit nor culture in which to measure age, most answers seem to assume an integer annual representation. The SI-unit for time is `second` , ergo the correct generic answer should be (of course assuming normalized `DateTime` and taking no regard whatsoever to relativistic effects):

` `var lifeInSeconds = (DateTime.Now.Ticks - then.Ticks)/TickFactor;` `

In the Christian way of calculating age in years:

` `var then = ... // Then, in this case the birthday var now = DateTime.UtcNow; int age = now.Year - then.Year; if (now.AddYears(-age) < then) age--;` `

In finance there is a similar problem when calculating something often referred to as the Day Count Fraction , which roughly is a number of years for a given period. And the age issue is really a time measuring issue.

Example for the actual/actual (counting all days "correctly") convention:

` `DateTime start, end = .... // Whatever, assume start is before end double startYearContribution = 1 - (double) start.DayOfYear / (double) (DateTime.IsLeapYear(start.Year) ? 366 : 365); double endYearContribution = (double)end.DayOfYear / (double)(DateTime.IsLeapYear(end.Year) ? 366 : 365); double middleContribution = (double) (end.Year - start.Year - 1); double DCF = startYearContribution + endYearContribution + middleContribution;` `

Another quite common way to measure time generally is by "serializing" (the dude who named this date convention must seriously have been trippin'):

` `DateTime start, end = .... // Whatever, assume start is before end int days = (end - start).Days;` `

I wonder how long we have to go before a relativistic age in seconds becomes more useful than the rough approximation of earth-around-sun-cycles during one's lifetime so far 🙂 Or in other words, when a period must be given a location or a function representing motion for itself to be valid 🙂

` `static string CalcAge(DateTime birthDay) { DateTime currentDate = DateTime.Now; int approximateAge = currentDate.Year - birthDay.Year; int daysToNextBirthDay = (birthDay.Month * 30 + birthDay.Day) - (currentDate.Month * 30 + currentDate.Day) ; if (approximateAge == 0 || approximateAge == 1) { int month = Math.Abs(daysToNextBirthDay / 30); int days = Math.Abs(daysToNextBirthDay % 30); if (month == 0) return "Your age is: " + daysToNextBirthDay + " days"; return "Your age is: " + month + " months and " + days + " days"; ; } if (daysToNextBirthDay > 0) return "Your age is: " + --approximateAge + " Years"; return "Your age is: " + approximateAge + " Years"; ; }` `

I used ScArcher2's solution for an accurate Year calculation of a persons age but I needed to take it further and calculate their Months and Days along with the Years.

` ` public static Dictionary<string,int> CurrentAgeInYearsMonthsDays(DateTime? ndtBirthDate, DateTime? ndtReferralDate) { //---------------------------------------------------------------------- // Can't determine age if we don't have a dates. //---------------------------------------------------------------------- if (ndtBirthDate == null) return null; if (ndtReferralDate == null) return null; DateTime dtBirthDate = Convert.ToDateTime(ndtBirthDate); DateTime dtReferralDate = Convert.ToDateTime(ndtReferralDate); //---------------------------------------------------------------------- // Create our Variables //---------------------------------------------------------------------- Dictionary<string, int> dYMD = new Dictionary<string,int>(); int iNowDate, iBirthDate, iYears, iMonths, iDays; string sDif = ""; //---------------------------------------------------------------------- // Store off current date/time and DOB into local variables //---------------------------------------------------------------------- iNowDate = int.Parse(dtReferralDate.ToString("yyyyMMdd")); iBirthDate = int.Parse(dtBirthDate.ToString("yyyyMMdd")); //---------------------------------------------------------------------- // Calculate Years //---------------------------------------------------------------------- sDif = (iNowDate - iBirthDate).ToString(); iYears = int.Parse(sDif.Substring(0, sDif.Length - 4)); //---------------------------------------------------------------------- // Store Years in Return Value //---------------------------------------------------------------------- dYMD.Add("Years", iYears); //---------------------------------------------------------------------- // Calculate Months //---------------------------------------------------------------------- if (dtBirthDate.Month > dtReferralDate.Month) iMonths = 12 - dtBirthDate.Month + dtReferralDate.Month - 1; else iMonths = dtBirthDate.Month - dtReferralDate.Month; //---------------------------------------------------------------------- // Store Months in Return Value //---------------------------------------------------------------------- dYMD.Add("Months", iMonths); //---------------------------------------------------------------------- // Calculate Remaining Days //---------------------------------------------------------------------- if (dtBirthDate.Day > dtReferralDate.Day) //Logic: Figure out the days in month previous to the current month, or the admitted month. // Subtract the birthday from the total days which will give us how many days the person has lived since their birthdate day the previous month. // then take the referral date and simply add the number of days the person has lived this month. //If referral date is january, we need to go back to the following year's December to get the days in that month. if (dtReferralDate.Month == 1) iDays = DateTime.DaysInMonth(dtReferralDate.Year - 1, 12) - dtBirthDate.Day + dtReferralDate.Day; else iDays = DateTime.DaysInMonth(dtReferralDate.Year, dtReferralDate.Month - 1) - dtBirthDate.Day + dtReferralDate.Day; else iDays = dtReferralDate.Day - dtBirthDate.Day; //---------------------------------------------------------------------- // Store Days in Return Value //---------------------------------------------------------------------- dYMD.Add("Days", iDays); return dYMD; }` `

I have a customized Function to calculate Age + a message if selected date in not matching //This function will validate the date

` `private bool ValidateDate(string dob) { DateTime dobdate = DateTime.Parse(dob); DateTime nowdate = DateTime.Now; TimeSpan ts = nowdate - dobdate; int Years = ts.Days / 365; if (Years < 18) { message = "Date of Birth must not be less then 18"; return false; } else if (Years > 65) { message = "Date of Birth must not be greater then 65"; return false; } dobvalue = dob; return true; } //Below here you call that function and pass out datetime value (MM/DD/YYYY) you can format by any way you like //Function Call if (ValidateDate("03/10/1982") == false) { lbldatemessaeg.Visible = true; lbldatemessaeg.Text = message; //you can replace anything a messagebox,or any container to display return; }` `
` `private int GetAge(int _year, int _month, int _day { DateTime yourBirthDate= new DateTime(_year, _month, _day); DateTime todaysDateTime = DateTime.Today; int noOfYears = todaysDateTime.Year - yourBirthDate.Year; if (DateTime.Now.Month < yourBirthDate.Month || (DateTime.Now.Month == yourBirthDate.Month && DateTime.Now.Day < yourBirthDate.Day)) { noOfYears--; } return noOfYears; }` `

The following approach (extract from Time Period Library for .NET class DateDiff ) considers the calendar of the culture info:

` `// ---------------------------------------------------------------------- private static int YearDiff( DateTime date1, DateTime date2 ) { return YearDiff( date1, date2, DateTimeFormatInfo.CurrentInfo.Calendar ); } // YearDiff // ---------------------------------------------------------------------- private static int YearDiff( DateTime date1, DateTime date2, Calendar calendar ) { if ( date1.Equals( date2 ) ) { return 0; } int year1 = calendar.GetYear( date1 ); int month1 = calendar.GetMonth( date1 ); int year2 = calendar.GetYear( date2 ); int month2 = calendar.GetMonth( date2 ); // find the the day to compare int compareDay = date2.Day; int compareDaysPerMonth = calendar.GetDaysInMonth( year1, month1 ); if ( compareDay > compareDaysPerMonth ) { compareDay = compareDaysPerMonth; } // build the compare date DateTime compareDate = new DateTime( year1, month2, compareDay, date2.Hour, date2.Minute, date2.Second, date2.Millisecond ); if ( date2 > date1 ) { if ( compareDate < date1 ) { compareDate = compareDate.AddYears( 1 ); } } else { if ( compareDate > date1 ) { compareDate = compareDate.AddYears( -1 ); } } return year2 - calendar.GetYear( compareDate ); } // YearDiff` `

` `// ---------------------------------------------------------------------- public void CalculateAgeSamples() { PrintAge( new DateTime( 2000, 02, 29 ), new DateTime( 2009, 02, 28 ) ); // > Birthdate=29.02.2000, Age at 28.02.2009 is 8 years PrintAge( new DateTime( 2000, 02, 29 ), new DateTime( 2012, 02, 28 ) ); // > Birthdate=29.02.2000, Age at 28.02.2012 is 11 years } // CalculateAgeSamples // ---------------------------------------------------------------------- public void PrintAge( DateTime birthDate, DateTime moment ) { Console.WriteLine( "Birthdate={0:d}, Age at {1:d} is {2} years", birthDate, moment, YearDiff( birthDate, moment ) ); } // PrintAge` `

This is simple and appears to be accurate for my needs. I am making an assumption for the purposes of leap years that regardless of when the person chooses to celebrate the birthday they are not technically a year older until a full 365 days has passed since there last birthday (ie 28th February does not make them a year older)

` `DateTime now = DateTime.Today; DateTime birthday = new DateTime(1991, 02, 03);//3rd feb int age = now.Year - birthday.Year; if (now.Month < birthday.Month || (now.Month == birthday.Month && now.Day < birthday.Day))//not had bday this year yet age--; return age;` `

Let us know if you spot any problems 😉