您将如何使用出生日期(考虑闰年)计算 C# 中的年龄
本文关键字:计算 闰年 何使用 出生日期 | 更新日期: 2023-09-27 18:34:15
这里有个问题。我已经看到了很多解决方案,但似乎没有人满足我想要的标准......
我想以这种格式显示年龄
20 y(s) 2 m(s) 20 d(s)
20 y(s) 2 m(s)
2 m(s) 20 d(s)
20 d(s)
等。。。
我已经尝试了几种解决方案,但是闰年导致了我的问题。我的单元测试总是因为闰年而失败,无论中间有多少天,闰年都算作额外的天数。
这是我的代码....
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;
/// <summary>
/// Initializes a new instance of <see cref="Age"/>.
/// </summary>
/// <param name="start">The date and time when the age started.</param>
/// <param name="end">The date and time when the age ended.</param>
/// <remarks>This </remarks>
public Age(DateTime start, DateTime end)
: this(start, end, CultureInfo.CurrentCulture.Calendar)
{
}
/// <summary>
/// Initializes a new instance of <see cref="Age"/>.
/// </summary>
/// <param name="start">The date and time when the age started.</param>
/// <param name="end">The date and time when the age ended.</param>
/// <param name="calendar">Calendar used to calculate age.</param>
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;
}
/// <summary>
/// Gets the number of whole years something has aged.
/// </summary>
public Int32 Years
{
get { return _years; }
}
/// <summary>
/// Gets the number of whole months something has aged past the value of <see cref="Years"/>.
/// </summary>
public Int32 Months
{
get { return _months; }
}
/// <summary>
/// Gets the age as an expression of whole months.
/// </summary>
public Int32 TotalMonths
{
get { return _years * 12 + _months; }
}
/// <summary>
/// Gets the number of whole weeks something has aged past the value of <see cref="Years"/> and <see cref="Months"/>.
/// </summary>
public Int32 Days
{
get { return _days; }
}
/// <summary>
/// Gets the total number of days that have elapsed since the start and end dates.
/// </summary>
public Int32 TotalDays
{
get { return _totalDays; }
}
/// <summary>
/// Gets the number of whole weeks something has aged past the value of <see cref="Years"/> and <see cref="Months"/>.
/// </summary>
public Int32 Weeks
{
get { return (Int32) Math.Floor((Decimal) _days/7); }
}
/// <summary>
/// Gets the age as an expression of whole weeks.
/// </summary>
public Int32 TotalWeeks
{
get { return (Int32) Math.Floor((Decimal) _totalDays/7); }
}
}
下面是通过的示例单元测试:
[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();
}
}
我在 DateTime 类中创建了一个解决方案作为扩展方法,该解决方案是从@HackedByChinese"派生"出来的:
/// <summary>
/// Calculate age in years relative to months and days, for example Peters age is 25 years 2 months and 10 days
/// </summary>
/// <param name="startDate">The date when the age started</param>
/// <param name="endDate">The date when the age ended</param>
/// <param name="calendar">Calendar used to calculate age</param>
/// <param name="years">Return number of years, with considering months and days</param>
/// <param name="months">Return calculated months</param>
/// <param name="days">Return calculated days</param>
public static bool GetAge(this DateTime startDate, DateTime endDate, Calendar calendar, out int years, out int months, out int days)
{
if (startDate > endDate)
{
years = months = days = -1;
return false;
}
years = months = days = 0;
days += calendar.GetDayOfMonth(endDate) - calendar.GetDayOfMonth(startDate);
// When negative select days of last month
if (days < 0)
{
days += calendar.GetDaysInMonth(calendar.GetYear(startDate), calendar.GetMonth(startDate));
months--;
}
months += calendar.GetMonth(endDate) - calendar.GetMonth(startDate);
// when negative select month of last year
if (months < 0)
{
months += calendar.GetMonthsInYear(calendar.GetYear(startDate));
years--;
}
years += calendar.GetYear(endDate) - calendar.GetYear(startDate);
return true;
}
但我认识到结果天数可能与其他计算器略有不同。