C# 计算准确的年龄

C# 计算准确的年龄,c#,C#,任何人都知道如何根据日期(生日)计算年龄 我在想这样的事情 string age = DateTime.Now.GetAccurateAge(); 输出的结果是20年5个月20天,请参见,查看答案,获取想法。要获得年龄,我将使用出生日期的日期时间,并找出它与当前系统时间之间的差异。显示如何查找两个日期时间之间的差异。只需将开始时间设置为用户的生日,结束时间设置为现在(DateTime.now;)这听起来是一个很好的练习,可以更好地了解情况。不确定它是否总是正确的(没有考虑到是否存在闰年等可能导

任何人都知道如何根据日期(生日)计算年龄

我在想这样的事情

string age = DateTime.Now.GetAccurateAge();

输出的结果是20年5个月20天,请参见,查看答案,获取想法。

要获得年龄,我将使用出生日期的日期时间,并找出它与当前系统时间之间的差异。显示如何查找两个日期时间之间的差异。只需将开始时间设置为用户的生日,结束时间设置为现在(DateTime.now;)

这听起来是一个很好的练习,可以更好地了解情况。

不确定它是否总是正确的(没有考虑到是否存在闰年等可能导致失败的情况……),但这是一种轻松的方法,可以让你轻松度过一年又一个月:

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);
公共静态类DateTimeExtensions
{
公共静态字符串Toagesting(此日期时间dob)
{
DateTime today=DateTime.today;
int months=今天.Month-月日.Month;
int YERS=今日年-年月日;
如果(今天<月日)
{
月--;
}
如果(月数<0)
{
年--;
月数+=12;
}
整数天=(今天-月加月份((年*12)+月))。天;
返回string.Format(“{0}年{1},{2}月{3}和{4}日{5}”,
年,(年=1)?“”:“s”,
月数,(月=1)?“”:“s”,
天(天=1)?“”:“s”);
}
}
以下是我使用的:

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

        return age;
    }

由于我无法将代码发布到注释中,因此这里的代码基于@LukeH answer,错误已修复

public static int GetAge( DateTime dob, DateTime today, out int days, out int months ) {
        DateTime dt = today;
        if( dt.Day < dob.Day ) {
            dt = dt.AddMonths( -1 );
        }

        months = dt.Month - dob.Month;
        if( months < 0 ) {
            dt = dt.AddYears( -1 );
            months += 12;
        }

        int years = dt.Year - dob.Year;
        var offs = dob.AddMonths( years * 12 + months );
        days = (int)( ( today.Ticks - offs.Ticks ) / TimeSpan.TicksPerDay );
        return years;
    }
publicstaticintgetage(DateTime-dob、DateTime-today、out-int-days、out-int-months){
日期时间dt=今天;
if(日日<月日){
dt=dt.AddMonths(-1);
}
月数=月数-月数;
如果(月数<0){
dt=dt.AddYears(-1);
月数+=12;
}
int years=dt.Year-dob.Year;
var offs=月新增月数(年*12+月);
days=(int)((today.Ticks-offs.Ticks)/TimeSpan.TicksPerDay);
回归年;
}
@if(Model.CF\u DateOfBirth.HasValue)
{
var today=DateTime.today;
var月=日期时间。今天;
var age=今日.Year-Model.CF_dateof birth.Value.Year;
var mons=months.Month-Model.CF_DateOfBirth.Val`在此处输入代码`ue.Month;
if(Model.CF_dateof birth>today.AddYears(-age)和&Model.CF_dateof birth>months.AddMonths(-mons))
{
年龄;
}
出生日期:@Convert.ToDateTime(Model.CF_DateOfBirth).ToSortDateString().ToString()(@ageYears@mons-Months)
}

我觉得这是最准确的

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

我注意到卢卡的回答和闰年的特点。最简单的例子可能是截至2017年2月28日和2017年3月1日的日期为2016年2月29日的日期。从我的角度来看,2016年2月没有剩余的天数,其间有11个完整的月份(3月-1月),2017年2月至今已经有28天了,截至2017年2月28日,我会称此人为11个月28天。自2017年1月3日起1岁1天。(虽然有些闰日婴儿会在普通年份的第28天庆祝……但我很好奇法律上的考虑是什么。)

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

我不确定如何描述这些方法的根本区别,但这里是我的尝试。似乎总是有一个日期,所以请仔细检查

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"));
}
internal static void CalculateAge(DateTime出生日期、DateTime asOfDate、out int年、out int月、out int天)
{
Write(“截至”+asOfDate.ToShortDateString()+“:”);
//获取每个日期部分之间的相对差异
天=出生日期日-出生日期日;
月=出生日期月-出生日期月;
年=出生日期年-出生日期年;
如果(天数<0)
{
days=DateTime.DaysInMonth(dateOfBirth.Year,dateOfBirth.Month)-dateOfBirth.Day+//生日月份剩余天数+
asOfDate.Day;//在asOfDate的月份中经过了几天
月份--;//减去已计算的未完成月份
}
如果(月数<0)
{
月数+=12;//从12减去月数,将相对差值转换为#个月
年份--;//减去已计算的未完成年份
}
Console.WriteLine(string.Format(“{0}年{1}、{2}月{3}和{4}日{5}”),
年,(年=1)?“”:“s”,
月数,(月=1)?“”:“s”,
天(天=1)“:”s“);
}

若您有一个名为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);
}

我希望
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"));
}
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);
}

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

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