C#计算准确的年龄

时间:2010-06-16 15:26:49

标签: c#

任何人都知道如何根据日期(出生日期)获得年龄

我正在考虑这样的事情

string age = DateTime.Now.GetAccurateAge();

输出将是20年5月20日

之类的东西

15 个答案:

答案 0 :(得分:44)

public static class DateTimeExtensions
{
    public static string ToAgeString(this DateTime dob)
    {
        DateTime today = DateTime.Today;

        int months = today.Month - dob.Month;
        int years = today.Year - dob.Year;

        if (today.Day < dob.Day)
        {
            months--;
        }

        if (months < 0)
        {
            years--;
            months += 12;
        }

        int days = (today - dob.AddMonths((years * 12) + months)).Days;

        return string.Format("{0} year{1}, {2} month{3} and {4} day{5}",
                             years, (years == 1) ? "" : "s",
                             months, (months == 1) ? "" : "s",
                             days, (days == 1) ? "" : "s");
    }
}

答案 1 :(得分:4)

请参阅How do I calculate someone’s age in C#?的答案了解相关信息。

答案 2 :(得分:2)

答案 3 :(得分:2)

不确定它是否总是正确的(没有考虑是否有一些闰年等情况可能导致它失败......),但这是一个简单的方法来摆脱年月: / p>

DateTime bd = DateTime.Parse("2009-06-17");
TimeSpan ts = DateTime.Now.Subtract(bd);
DateTime age = DateTime.MinValue + ts;
string s = string.Format("{0} Years {1} months {2} days", age.Year -1 , age.Month - 1, age.Day - 1);

答案 4 :(得分:1)

这听起来像是一个很好的练习,可以更好地了解TimeSpan class

答案 5 :(得分:1)

由于我无法将代码发布到评论中,这里是基于@LukeH答案的代码,修复了错误

if let dataDict = data[0] as? [Int]{
print(dataDict) }

答案 6 :(得分:1)

我的答案不完全是一个答案;这是在此线程和类似线程中找到答案的一种方法。 LukeH已经提供了正确的答案,并且 我在这里的2美分是给所有想知道哪个是更正确答案*的人的。

*更正确,因为,正如您在分散的讨论和评论中所看到的那样,我们必须在leap年里折衷一些先决条件-dob在正常年份是1 mar还是28 feb?

我正在使用做为基准的thisthis other网站以及我的大脑;)

我在这里实现了LukeH,@ Panos Theof和@ xr280xr答案:

  public static class DateTimeExtensions
{
    public static int HowOld(this DateTime initialDay, DateTime dayToCalculate, out int days, out int months)
    {
        //https://stackoverflow.com/a/3055445/2752308
        //LukeH: essentially right
        months = dayToCalculate.Month - initialDay.Month;
        int years = dayToCalculate.Year - initialDay.Year;

        if (dayToCalculate.Day < initialDay.Day)
        {
            months--;
        }

        if (months < 0)
        {
            years--;
            months += 12;
        }

        days = (dayToCalculate - initialDay.AddMonths((years * 12) + months)).Days;
        Console.WriteLine(
            $"{years} year{((years == 1) ? "" : "s")}, {months} month{((months == 1) ? "" : "s")} and {days} day{((days == 1) ? "" : "s")}");
        return years;
    }
    public static int HowOld2(this DateTime initialDay, DateTime dayToCalculate, out int days, out int months)
    {
        //@Panos Theof: wrong

        months = dayToCalculate.Month - initialDay.Month;
        int years = dayToCalculate.Year - initialDay.Year;

        if (dayToCalculate.Day < initialDay.Day)
        {
            dayToCalculate = dayToCalculate.AddMonths(-1);
        }

        if (months < 0)
        {
            dayToCalculate = dayToCalculate.AddYears(-1);
            months += 12;
        }
        years = dayToCalculate.Year - initialDay.Year;
        var offs = initialDay.AddMonths(years * 12 + months);
        days = (int)((dayToCalculate.Ticks - offs.Ticks) / TimeSpan.TicksPerDay);
        Console.WriteLine(
            $"{years} year{((years == 1) ? "" : "s")}, {months} month{((months == 1) ? "" : "s")} and {days} day{((days == 1) ? "" : "s")}");
        return years;
    }
    public static int HowOld3(this DateTime initialDay, DateTime dayToCalculate, out int days, out int months)
    {
        //@xr280xr: wrong

        //Get the relative difference between each date part
        days = dayToCalculate.Day - initialDay.Day;
        months = dayToCalculate.Month - initialDay.Month;
        int years = dayToCalculate.Year - initialDay.Year;

        if (days < 0)
        {
            days = DateTime.DaysInMonth(initialDay.Year, initialDay.Month) - initialDay.Day +    //Days left in month of birthday +
                   dayToCalculate.Day;                                                                   //Days passed in dayToCalculate's month
            months--;                                                                               //Subtract incomplete month that was already counted
        }

        if (months < 0)
        {
            months += 12;   //Subtract months from 12 to convert relative difference to # of months
            years--;        //Subtract incomplete year that was already counted
        }

        Console.WriteLine(string.Format("{0} year{1}, {2} month{3} and {4} day{5}",
            years, (years == 1) ? "" : "s",
            months, (months == 1) ? "" : "s",
            days, (days == 1) ? "" : "s"));
        return years;
    }
}

使用VS2019和XUnit创建一个Inlinedata生成器类:

   public class CalculatorTestData : IEnumerable<object[]>
            public IEnumerator<object[]> GetEnumerator()
            {
                yield return new object[] { new DateTime(1966, 7, 27), new DateTime(2020, 7, 26), 53, 11, 29 };
                yield return new object[] { new DateTime(1966, 7, 27), new DateTime(2020, 7, 27), 54, 0, 0 };
                yield return new object[] { new DateTime(1966, 7, 27), new DateTime(2020, 7, 28), 54, 0, 1 };
                yield return new object[] { new DateTime(1968, 2, 29), new DateTime(2020, 2, 28), 51, 11, 30 };
                yield return new object[] { new DateTime(1968, 2, 29), new DateTime(2020, 2, 29), 52, 0, 0 };
                yield return new object[] { new DateTime(1968, 2, 29), new DateTime(2020, 3, 01), 52, 0, 1 };
                yield return new object[] { new DateTime(2016, 2, 29), new DateTime(2017, 2, 28), 0, 11, 30 };
            }

            IEnumerator<object[]> IEnumerable<object[]>.GetEnumerator() => GetEnumerator();
            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
        }

并设置三种方法:

    [Theory]
    [ClassData(typeof(CalculatorTestData))]
    public void TestHowOld(DateTime initialDay, DateTime dayToCalculate,int expectedYears, int expectedMonths, int expectedDays)//, out int days, out int months
    {
        //LukeH: essentially right
        int resultMonths, resultDays;
        int age = initialDay.HowOld(dayToCalculate,out resultDays,
            out resultMonths); //https://stackoverflow.com/questions/28970265/how-to-test-method-with-out-parameters
        Assert.Equal(age, expectedYears);
        Assert.Equal(resultMonths, expectedMonths);
        Assert.Equal(resultDays, expectedDays);
    }
    [Theory]
    [ClassData(typeof(CalculatorTestData))]
    public void TestHowOld2(DateTime initialDay, DateTime dayToCalculate, int expectedYears, int expectedMonths, int expectedDays)//, out int days, out int months
    {
        //@Panos Theof: wrong
        int resultMonths, resultDays;
        int age = initialDay.HowOld2(dayToCalculate, out resultDays,
            out resultMonths); //https://stackoverflow.com/questions/28970265/how-to-test-method-with-out-parameters
        Assert.Equal(age, expectedYears);
        Assert.Equal(resultMonths, expectedMonths);
        Assert.Equal(resultDays, expectedDays);

    }
    [Theory]
    [ClassData(typeof(CalculatorTestData))]
    public void TestHowOld3(DateTime initialDay, DateTime dayToCalculate, int expectedYears, int expectedMonths, int expectedDays)//, out int days, out int months
    {
        //@xr280xr: wrong
        int resultMonths, resultDays;
        int age = initialDay.HowOld3(dayToCalculate, out resultDays,
            out resultMonths); //https://stackoverflow.com/questions/28970265/how-to-test-method-with-out-parameters
        Assert.Equal(age, expectedYears);
        Assert.Equal(resultMonths, expectedMonths);
        Assert.Equal(resultDays, expectedDays);

    }

当然,预期结果在InlineData类上。

输出结果是:

enter image description here

因此,卢克(LukeH)有正确的答案。而且,令我惊讶的是,两个站点都不同意跳跃DOB,并且IMHO Calculator.net是正确的,而timeanddate.com显然是错误的,从而产生以下错误输出:

对于2月29日的DOB:

  • 28/02和29/02都产生52、0、0(?!)

  • 01/03产生52,0,2(!!! ???)

  • 2016年2月29日=> 2017年2月28日=> 1 y,0 m,1 d(!!! ???)

希望显示测试设置可以帮助某人。

答案 7 :(得分:0)

为了获得年龄,我将使用生日的日期时间,并找出它与当前系统时间之间的差异。 This link显示了如何找到两个日期时间之间的差异。只需将starttime设为用户的生日和结束时间(DateTime.Now;)

答案 8 :(得分:0)

以下是我使用的内容:

    public static int GetAge(DateTime dateOfBirth)
    {
        int age = DateTime.Now.Year - dateOfBirth.Year;
        if (dateOfBirth.AddYears(age) > DateTime.Now)
        {
            age = age - 1;
        }

        return age;
    }

答案 9 :(得分:0)

试试这个。它在两个日期之间的所有日子循环,并在途中计算天,月和年。这就是我需要的。

    public static class DateTimeExtension
    {
    /// <summary>
    /// Returns day, month, and year by subtracting date2 from date1
    /// </summary>
    /// <param name="date1">the date from which date2 will be subtracted</param>
    /// <param name="date2">this date will be subtracted from date1</param>
    /// <returns></returns>
    public static string GetAge(this DateTime date1, DateTime date2)
    {
        int y = 0, m = 0, d = 0;
        for (DateTime i = date2; i < date1; i = i.AddDays(1))
        {
            d++;
            if (d >= DateTime.DaysInMonth(i.Year, i.Month))
            {
                d = 0;
                m++;
            }
            if (m >= 12)
            {
                y++;
                m = 0;
            }
        }
        return "Time-span: " + y + " Year(s), " + m + " Month(s), " + d + " Day(s)";
    }
}

使用方法:

            Console.WriteLine(new DateTime(2018, 4, 24).GetAge(new DateTime(2018,1,3)));
            //Time-span: 0 Year(s), 3 Month(s), 20 Day(s)

            Console.WriteLine(new DateTime(2010, 4, 24).GetAge(new DateTime(2000, 7, 23)));
            //Time-span: 9 Year(s), 9 Month(s), 2 Day(s)

答案 10 :(得分:0)

ServiceManifest

答案 11 :(得分:0)

我觉得这是最准确的。

            private int GetAge(DateTime birthDate)
            {
                TimeSpan ageTimeSpan = DateTime.UtcNow.Subtract(birthDate);
                int age = new DateTime(ageTimeSpan.Ticks).Year;
                return age;
            }

答案 12 :(得分:0)

我注意到LukeH的回答和leap年的特殊之处。最简单的示例可能是dob = 2/29/20162/28/2017中的3/1/2017。从我的角度来看,2016年2月没有剩余时间,介于11月之间(3月至1月),到目前为止,截至2/28/2017到2017年2月为止有28天,我会将此人称为11个月28天大的人。截至3/1/2017,已满1岁1天。 (尽管有些leap日婴儿会庆祝并在普通年的28日举行……我很好奇法律上的考虑。)

因为LukeH的方法利用了DateTime.AddMonths,所以它计算了11个月30天,因为它发现了2/28/20171/29/2017之间的天数差异。因此,它计算出2/28/20172/29/2016之后30天的11个月,以及3/1/2016之后27天的11个月。生日间隔3天,相隔仅1天。如果它像我“手工”那样花了28天,他们就会有一天的年龄差异。

我不确定如何描述方法的根本区别,但这是我的目的。似乎总是有约会的陷阱,请仔细检查。

internal static void CalculateAge(DateTime dateOfBirth, DateTime asOfDate, out int years, out int months, out int days)
{
    Console.Write("As of " + asOfDate.ToShortDateString() + ": ");

    //Get the relative difference between each date part
    days = asOfDate.Day - dateOfBirth.Day;
    months = asOfDate.Month - dateOfBirth.Month;
    years = asOfDate.Year - dateOfBirth.Year;

    if (days < 0)
    {
        days = DateTime.DaysInMonth(dateOfBirth.Year, dateOfBirth.Month) - dateOfBirth.Day +    //Days left in month of birthday +
                asOfDate.Day;                                                                   //Days passed in asOfDate's month
        months--;                                                                               //Subtract incomplete month that was already counted
    }

    if (months < 0)
    {
        months += 12;   //Subtract months from 12 to convert relative difference to # of months
        years--;        //Subtract incomplete year that was already counted
    }

    Console.WriteLine(string.Format("{0} year{1}, {2} month{3} and {4} day{5}",
                years, (years == 1) ? "" : "s",
                months, (months == 1) ? "" : "s",
                days, (days == 1) ? "" : "s"));
}

答案 13 :(得分:0)

如果您有一个名为DateOfBirth的实例变量/属性,则可以使用此方法。否则,您可以将“出生日期”作为方法的参数传递。 我进行了微积分,并证明了它永远不会失败。

public int AgeCalc(){
      DateTime now = DateTime.Now;
      double age =  Math.Floor((DateTime.Now - DateOfBirth).TotalDays)/((DateTime.IsLeapYear(year: now.Year)? 366 : 365));
      return (age % 1) >= 0.951 ? Math.Round(age) : Math.Floor(age);
}

我希望这可以对您有所帮助:)

答案 14 :(得分:0)

这就是我用的。它是selected answerthis answer的组合。

对于2016年2月29日出生的人,在2017年3月3日的年龄输出:

年份:1
月:1(2月为28天)
天数:0

var today = new DateTime(2020,11,4);
//var today = DateTime.Today;

// Calculate the age.
var years = today.Year - dateOfBirth.Year;

// Go back to the year in which the person was born in case of a leap year
if (dateOfBirth.Date > today.AddYears(-years))
{
    years--;
}

var months = today.Month - dateOfBirth.Month;
// Full month hasn't completed
if (today.Day < dateOfBirth.Day)
{
    months--;
}

if (months < 0)
{
    months += 12;
}

Years = years;
Months = months;
Days = (today - dateOfBirth.AddMonths((years * 12) + months)).Days;