您如何使用出生日期计算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(); } }