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

给定DateTime代表一个人的生日,我怎样计算他们的年龄?

一个容易理解和简单的解决scheme。

 // 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--; 

不过,这假定你正在寻找西方的年龄思想,而不是使用东亚推算

这是一个奇怪的方式来做到这一点,但如果你把date格式化为yyyymmdd并从当前date中减去出生date,那么删除最后4位数字,你有年龄:)

我不知道C#,但我相信这可以用任何语言。

 20080814 - 19800703 = 280111 

删除最后4位数= 28

C#代码:

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

或者,也可以不用扩展方法的forms进行所有的types转换。 错误检查省略:

 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; } 

我不知道如何接受错误的解决scheme。 正确的C#代码片段是由Michael Stum编写的

这是一个testing片段:

 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; } 

我不认为迄今为止的答案都提供了计算年龄不同的文化。 例如,参见东亚时代的估算与西方的估算 。

任何真正的答案都必须包括本地化。 在这个例子中, 战略模式可能会是有序的。

这个简单的答案是应用AddYears ,如下所示,因为这是将闰年年份加到2月29日的唯一本地方法,并且获得了2月28日的正确结果。

有些人觉得3月1日是跳跳舞的生日,但networking也没有任何官方的规则支持这一点,普通逻辑也没有解释为什么二月份出生的一个月中应该有百分之七十五的生日。

另外,Age方法适合作为DateTime的扩展添加。 通过这个,你可以用最简单的方式获得年龄:

  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; } } 

现在运行这个testing:

 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(); } } 

关键date的例子是这样的:

出生date:2000-02-29更新date:2011-02-28年龄:11

输出:

 { 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 } 

而对于后来的date2012-02-28:

 { 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 } 

我的build议

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

这似乎有一个正确的date改变了一年。 (我现场testing到107岁)

另一个function,不是由我,而是在网上find,并提炼一下:

 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; } 

我想到的只有两件事情:那些不使用公历的国家的人呢? DateTime.Now是在我认为的服务器特定的文化。 我完全不知道如何使用亚洲的日历,我不知道是否有一个简单的方法来转换日历之间的date,但万一你想知道从4660年的中国家伙:-)

我迟到了,但这里是一个单行的:

 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 

对于2的解决scheme是在确定总年龄方面不是那么精确,但被人们认为是精确的。 人们通常也会使用它,当他们“手动”计算他们的年龄时:

 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 } 

注释2:

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

再多注意一下…我会为它创build2个静态重载方法,一个用于通用,另一个用于友好的用法:

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

这是我们在这里使用的版本。 它工作,而且相当简单。 这和Jeff的想法是一样的,但是我认为它更清晰一些,因为它将逻辑减去了一个,所以它更容易理解。

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

如果你认为这样的事情不清楚,你可以扩展三元运算符,使其更清晰。

显然这是作为DateTime一个扩展方法完成的,但显然你可以抓住那一行代码来完成工作,并将它放在任何地方。 这里我们有另外一个在DateTime.Now中传递的扩展方法的重载,只是为了完整性。

许多年前,为了在我的网站上提供一个年龄计算器噱头 ,我写了一个函数来计算年龄到一个分数。 这是C#的一个快速端口(来自PHP版本 )。 恐怕我没有能够testing的C#版本,但希望你享受都一样!

(不可否认,这对于在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); 

我已经创build了一个SQL Server用户定义函数来计算某个人的年龄,给出他们的出生date。 当你需要它作为查询的一部分时,这很有用:

 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; } }; 

我花了一些时间在这方面做了一些工作,并提出了这个计算年龄,几个月和几天的人的年龄。 我已经testing了2月29日的问题和闰年,似乎工作,我会很感激任何反馈:

 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); 

我不确定你想如何回复给你,所以我只是做了一个可读的string。

这是一个解决scheme。

  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); 

我find的最简单的方法是这样的。 它适用于美国和西欧的语言环境。 不能和其他地区,特别是像中国这样的地方说话。 最多4个额外的比较,按照年龄的初始计算。

 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 ; } 

我正在研究这个问题的答案,并注意到没有人提到闰日出生的监pipe/法律方面的问题。 例如, 根据维基百科 ,如果你是在2月29日出生在不同的司法pipe辖区,那么你是非闰年的生日有所不同:

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

就我所知,在美国,这些法令对这个问题没有任何规定,只是在普通法上,以及各个监pipe机构如何在法规中定义一些东西。

为此,有一个改进:

 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; } 

应该指出,这个代码假定:

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

我们需要考虑一年以下的人吗? 作为中国文化,我们将小婴儿的年龄描述为2个月或4周。

下面是我的实现,它不像我想象的那么简单,尤其是处理2/28的date。

 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"; } } 

这个实现已经通过了testing用例。

 [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); } 

希望这是有帮助的。

Here's yet another answer:

 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 🙂

How about this solution?

 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 😉