使用出生日期,你会如何计算年龄在C#中(考虑到闰年) [英] How would you calculate the age in C# using date of birth (considering leap years)

查看:151
本文介绍了使用出生日期,你会如何计算年龄在C#中(考虑到闰年)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一个问题。我见过很多的解决方案,但似乎没有人可以完成我想要的标准......

我要以这种格式显示年龄

  20岁(S)2米(S)20 D(S)
20岁(S)2米(S)
2米(S)20 D(S)
20 D(S)
 

等等...

我已经尝试了几种解决方案,但闰年与我造成问题的原因。我的单元测试总是被失败,因为闰年​​,并不管有多少天之间,飞跃赞成票数的天数外进来,

下面是我的code ....

 公共静态字符串AgeDiscription(日期时间DATEOFBIRTH)
{
    VAR今天= DateTime.Now;
    VAR天= GetNumberofDaysUptoNow(出生日期);
    变种月= 0;
    VAR年= 0;
    如果(天> 365)
    {
        年= today.Year  -  dateOfBirth.Year;
        天=天数365%;
    }
    如果(天> DateTime.DaysInMonth(today.Year,today.Month))
    {
        个月= Math.Abs​​(today.Month  -  dateOfBirth.Month);
        的for(int i = 0; I<个月;我++)
        {
            天 -  = DateTime.DaysInMonth(today.Year,today.AddMonths(0  -  I).Month);
        }
    }

    VAR ageDescription =新的StringBuilder();

    如果(年!= 0)
        ageDescription = ageDescription.Append(年+Y(S));
    如果(月!= 0)
        ageDescription = ageDescription.Append(月+米(S));
    如果(天!=​​ 0)
        ageDescription = ageDescription.Append(天+D(S));

    返回ageDescription.ToString();
}

公共静态INT GetNumberofDaysUptoNow(日期时间DATEOFBIRTH)
{
    VAR今天= DateTime.Now;
    VAR时间跨度=今天 - 出生日期;
    VAR nDays = timeSpan.Days;
    返回nDays;
}
 

任何想法???

更新:

我要为这两个日期之间的差值:

  VAR DATEOFBIRTH = DateTime.Now.AddYears(-20);
预计字符串=20岁(S);
字符串的实际; //返回20岁(S)5天(S)
实际= Globals.AgeDiscription(出生日期);
Assert.AreEqual(预期,实际值);
 

解决方案

年龄是pretty的棘手。下面是一个结构我使用相关的摘录。

 公共结构年龄
{
    私人只读的Int32 _years;
    私人只读的Int32 _months;
    私人只读的Int32 _days;
    私人只读的Int32 _totalDays;

    ///<总结>
    ///的初始化℃的新实例;看到CREF =时代/取代。
    ///< /总结>
    ///&所述; PARAM NAME =开始>将日期和时间,当年龄开始&所述; /参数>
    ///< PARAM NAME =结束>在时代结束的日期和时间< /参数>
    ///<说明>这与LT; /说明>
    公共年龄(DateTime的开始,结束日期时间)
        :这个(开始,结束,CultureInfo.CurrentCulture.Calendar)
    {
    }

    ///<总结>
    ///的初始化℃的新实例;看到CREF =时代/取代。
    ///< /总结>
    ///&所述; PARAM NAME =开始>将日期和时间,当年龄开始&所述; /参数>
    ///< PARAM NAME =结束>在时代结束的日期和时间< /参数>
    ///< PARAM NAME =日历>日历用于计算时代< /参数>
    公共年龄(DateTime的开始,结束日期时间,日历日历)
    {
        如果(开始>结束)抛出新ArgumentException的(起始日期不能晚于结束日期。);

        VAR的startDate = start.Date;
        VAR结束日期= end.Date;

        _years = _months = _days = 0;
        _days + = calendar.GetDayOfMonth(结束日期) -  calendar.GetDayOfMonth(的startDate);
        如果(_days℃,)
        {
            _days + = calendar.GetDaysInMonth(calendar.GetYear(的startDate),calendar.GetMonth(的startDate));
            _months--;
        }
        _months + = calendar.GetMonth(结束日期) -  calendar.GetMonth(的startDate);
        如果(_months℃,)
        {
            _months + = calendar.GetMonthsInYear(calendar.GetYear(的startDate));
            _年份 - ;
        }
        _years + = calendar.GetYear(结束日期) -  calendar.GetYear(的startDate);

        VAR TS = endDate.Subtract(的startDate);
        _totalDays =(Int32)已ts.TotalDays;
    }

    ///<总结>
    ///获取整年的一些已经老化的数量。
    ///< /总结>
    公众的Int32年
    {
        {返回_years; }
    }

    ///<总结>
    ///获取全月一些已经老化的过去和LT的值的数字;查看CREF =岁月/取代。
    ///< /总结>
    公众的Int32月
    {
        {返回_months; }
    }

    ///<总结>
    ///获取年龄作为整个个月前pression。
    ///< /总结>
    公众的Int32 TotalMonths
    {
        {返回_years * 12 + _months; }
    }

    ///<总结>
    ///获取一些已经老化的过去与其中的价值全周数;看到CREF =岁月/>和<看到CREF =月/取代。
    ///< /总结>
    公众的Int32天
    {
        {返回_days; }
    }

    ///<总结>
    ///获取自从开始和结束日期已经经过的天数。
    ///< /总结>
    公众的Int32 TotalDays
    {
        {返回_totalDays; }
    }

    ///<总结>
    ///获取一些已经老化的过去与其中的价值全周数;看到CREF =岁月/>和<看到CREF =月/取代。
    ///< /总结>
    公众的Int32周
    {
        {返回(Int32)已Math.Floor((十进制)_days / 7); }
    }

    ///<总结>
    ///获取年龄作为整个星期的前pression。
    ///< /总结>
    公众的Int32 TotalWeeks
    {
        {返回(Int32)已Math.Floor((十进制)_totalDays / 7); }
    }
}
 

下面是一个例子单元测试通过:

  [测试]
    公共无效Should_be_exactly_20_years_old()
    {
        变种现在= DateTime.Now;
        VAR年龄=新时代(now.AddYears(-20),现在的);

        Assert.That(年龄,Has.Property(岁月)。EqualTo(20)
            .And.Property(月)。EqualTo(0)
            .And.Property(天)EqualTo(0))。
    }
 

Here is a problem. I have seen many solutions, but no one seems to be fulfilling the criteria I want...

I want to display the age in this format

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

etc...

I have tried several solutions, but the leap year is causing the problem with me. My unit tests are always being failed because of leap years and no matter how many days come in between, the leap yeas count for extra number of days.

Here is my code....

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

Any ideas???

UPDATE:

I want the difference between the two dates as:

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

解决方案

Age is pretty tricky. Here's the relevant excerpts from a struct I use.

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

Here's an example unit test that passes:

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

这篇关于使用出生日期,你会如何计算年龄在C#中(考虑到闰年)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆