【问题标题】:How would you calculate the age in C# using date of birth (considering leap years)您将如何使用出生日期计算 C# 中的年龄(考虑闰年)
【发布时间】:2012-05-23 23:54:24
【问题描述】:

这是一个问题。我见过很多解决方案,但似乎没有一个符合我想要的标准......

我想用这种格式显示年龄

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

【问题讨论】:

  • 这个问题被问了太多次了,你没有发现任何有用的?
  • @V4Vendetta 不幸的是,从来没有这样问过。我的意思是,问题是别的,让我更新我的描述......
  • @NaveedButt,你的问题有何不同?
  • @jrummell 看到 HackedByChinese 的评论,他已经说得很清楚了,他和其他人的答案的区别......我的用户需要精确的年龄

标签: c# asp.net .net c#-4.0 datetime


【解决方案1】:

使用

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;

获得想要的结果。

【讨论】:

  • 不会给我与上述描述相对应的任何细节...... :(
  • 这不适用于确定年龄,因为它适用于人。
  • 使用TimeSpan 的年份确实雄心勃勃! !仔细看有一行是var timeSpan = today - dateOfBirth;
  • 不回答问题。
【解决方案2】:

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

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

【讨论】:

  • 那么,当通过start=DateTime.Now.AddYears(-20)end=DateTime.Now 时,这是否会返回20 y(s)?我对此表示怀疑。我认为它会返回 20 y(s) 5 d(s)
  • 已更新为您的示例包含单元测试。我是为医疗软件编写的,用户对年龄的显示方式非常挑剔(其他答案中建议的近似值并不充分)。
【解决方案3】:
static int AgeInYears(DateTime birthday, DateTime today)
{
    return ((today.Year - birthday.Year) * 372 + (today.Month - birthday.Month) * 31 + (today.Day - birthday.Day)) / 372;
}

【讨论】:

  • 年龄不是问题。我想要以年、月、日为单位的年龄
  • 虽然没有真正的意义...想想看 - 两个人的年龄可能完全相同,但是当您将其转换为年、月和日时,月数和天部分可能会根据人们的出生时间而有所不同。例如,二月出生的人和一月出生的人。
  • 无论是否有意义,这是用户的要求 :( 很抱歉,但感谢@HackedByChinese 我得到了答案:)
【解决方案4】:

编写这个小函数以获得当年和出生年份之间的闰年天数,并将返回的天数添加到您年龄的天数部分:

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

【讨论】:

  • 如果是世纪年或千年年,这将失败。这只会给出闰年的数量,并且必须在世纪或千年中进行循环,然后对重叠的世纪、千年和闰年提出更多逻辑......
【解决方案5】:

检查此代码:

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

}

【讨论】:

【解决方案6】:

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

但我认识到结果天数可能与其他计算器略有不同。

【讨论】:

    猜你喜欢
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    • 1970-01-01
    相关资源
    最近更新 更多