您如何使用出生日期计算C#的年龄(考虑闰年)

这是一个问题。 我见过很多解决方案,但似乎没有人能达到我想要的标准……

我想以这种格式显示年龄

20 y(s) 2 m(s) 20 d(s) 20 y(s) 2 m(s) 2 m(s) 20 d(s) 20 d(s) 

等等…

我已经尝试了几种解决方案,但闰年对我造成了问题。 由于闰年,我的unit testing总是失败,无论中间有多少天,飞跃都会计入额外的天数。

这是我的代码….

 public static string AgeDiscription(DateTime dateOfBirth) { var today = DateTime.Now; var days = GetNumberofDaysUptoNow(dateOfBirth); var months = 0; var years = 0; if (days > 365) { years = today.Year - dateOfBirth.Year; days = days % 365; } if (days > DateTime.DaysInMonth(today.Year, today.Month)) { months = Math.Abs(today.Month - dateOfBirth.Month); for (int i = 0; i < months; i++) { days -= DateTime.DaysInMonth(today.Year, today.AddMonths(0 - i).Month); } } var ageDescription = new StringBuilder(""); if (years != 0) ageDescription = ageDescription.Append(years + " y(s) "); if (months != 0) ageDescription = ageDescription.Append(months + " m(s) "); if (days != 0) ageDescription = ageDescription.Append(days + " d(s) "); return ageDescription.ToString(); } public static int GetNumberofDaysUptoNow(DateTime dateOfBirth) { var today = DateTime.Now; var timeSpan = today - dateOfBirth; var nDays = timeSpan.Days; return nDays; } 

有任何想法吗???

更新:

我希望两个日期之间的差异为:

 var dateOfBirth = DateTime.Now.AddYears(-20); string expected = "20 y(s) "; string actual; // returns 20 y(s) 5 d(s) actual = Globals.AgeDiscription(dateOfBirth); Assert.AreEqual(expected, actual); 

年龄相当棘手。 这是我使用的结构的相关摘录。

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

这是一个通过的示例unit testing:

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

使用

 Timespan interval = DateTime.Now - DateOfBirth; 

然后用

 interval.Days interval.TotalDays; interval.Hours; interval.TotalHours; interval.Minutes; interval.TotalMinutes; interval.Seconds; interval.TotalSeconds; interval.Milliseconds; interval.TotalMilliseconds; interval.Ticks; 

获得理想的结果。

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

写下这个小函数,以获得当前年份和出生年份之间的闰年天数,并将返回的天数添加到您的年龄段的日期:

  private static int NumberOfLeapYears(int startYear, int endYear) { int counter = 0; for (int year = startYear; year <= endYear; year++) counter += DateTime.IsLeapYear(year) ? 1 : 0; return counter; } 

检查此代码:

 { dif = int(datediff("D", Convert.ToDateTime("01/" + Q101m.text + "/" + Q101y.Text), (Convert.ToDateTime(Vdate.text)))/365.25) //If dif < 15 Or dif > 49 { MessageBox.Show("xxxxxxx"); Q101m.Focus(); } }