首页 文章

如何计算C#中某人的年龄?

提问于
浏览
1743

鉴于 DateTime 代表一个人的生日,我如何计算他们的年龄?

30 回答

  • 15

    与2月28日的任何一年相比,这是能够解决2月29日生日的最准确答案之一 .

    public int GetAge(DateTime birthDate)
    {
        int age = DateTime.Now.Year - birthDate.Year;
    
        if (birthDate.DayOfYear > DateTime.Now.DayOfYear)
            age--;
    
        return age;
    }
    
  • 33

    我迟到了,但这是一个单行:

    int age = new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year-1;
    
  • 15
    private int GetAge(int _year, int _month, int _day
    {
        DateTime yourBirthDate= new DateTime(_year, _month, _day);
    
        DateTime todaysDateTime = DateTime.Today;
        int noOfYears = todaysDateTime.Year - yourBirthDate.Year;
    
        if (DateTime.Now.Month < yourBirthDate.Month ||
            (DateTime.Now.Month == yourBirthDate.Month && DateTime.Now.Day < yourBirthDate.Day))
        {
            noOfYears--;
        }
    
        return  noOfYears;
    }
    
  • 922

    2要解决的主要问题是:

    1. Calculate Exact age - 年,月,日等

    2. Calculate Generally perceived age - 人们通常不在乎他们到底多大年纪,他们只关心当年的生日 .


    1 的解决方案很明显:

    DateTime birth = DateTime.Parse("1.1.2000");
    DateTime today = DateTime.Today;     //we usually don't care about birth time
    TimeSpan age = today - birth;        //.NET FCL should guarantee this as precise
    double ageInDays = age.TotalDays;    //total number of days ... also precise
    double daysInYear = 365.2425;        //statistical value for 400 years
    double ageInYears = ageInDays / daysInYear;  //can be shifted ... not so precise
    

    2 的解决方案是在确定总年龄时不那么精确的解决方案,但被人们认为是精确的 . 人们通常也会使用它,当他们计算年龄"manually"时:

    DateTime birth = DateTime.Parse("1.1.2000");
    DateTime today = DateTime.Today;
    int age = today.Year - birth.Year;    //people perceive their age in years
    
    if (today.Month < birth.Month ||
       ((today.Month == birth.Month) && (today.Day < birth.Day)))
    {
      age--;  //birthday in current year not yet reached, we are 1 year younger ;)
              //+ no birthday for 29.2. guys ... sorry, just wrong date for birth
    }
    

    2的注释:

    • 这是我首选的解决方案

    • 我们无法使用DateTime.DayOfYear或TimeSpans,因为它们会改变闰年的天数

    • 为了便于阅读,我已经添加了更多的行

    再说一遍......我会为它创建2个静态重载方法,一个用于通用,第二个用于友好性:

    public static int GetAge(DateTime bithDay, DateTime today) 
    { 
      //chosen solution method body
    }
    
    public static int GetAge(DateTime birthDay) 
    { 
      return GetAge(birthDay, DateTime.Now);
    }
    
  • 14

    SQL版本:

    declare @dd smalldatetime = '1980-04-01'
    declare @age int = YEAR(GETDATE())-YEAR(@dd)
    if (@dd> DATEADD(YYYY, -@age, GETDATE())) set @age = @age -1
    
    print @age
    
  • 18

    这不是一个直接的答案,而是从准科学的角度来看更多关于手头问题的哲学推理 .

    我认为这个问题没有说明衡量年龄的单位或文化,大多数答案似乎假设一个整数年度代表 . 时间的SI单位是 second ,正确的通用答案应该是(当然假设归一化 DateTime 并且不考虑任何相对论效应):

    var lifeInSeconds = (DateTime.Now.Ticks - then.Ticks)/TickFactor;
    

    用基督徒计算年龄的方法:

    var then = ... // Then, in this case the birthday
    var now = DateTime.UtcNow;
    int age = now.Year - then.Year;
    if (now.AddYears(-age) < then) age--;
    

    在财务方面,在计算通常被称为日计数分数的事情时存在类似的问题,该分数大致是给定时期的若干年 . 年龄问题实际上是衡量问题的时间 .

    实际/实际(计算所有天数“正确”)约定的示例:

    DateTime start, end = .... // Whatever, assume start is before end
    
    double startYearContribution = 1 - (double) start.DayOfYear / (double) (DateTime.IsLeapYear(start.Year) ? 366 : 365);
    double endYearContribution = (double)end.DayOfYear / (double)(DateTime.IsLeapYear(end.Year) ? 366 : 365);
    double middleContribution = (double) (end.Year - start.Year - 1);
    
    double DCF = startYearContribution + endYearContribution + middleContribution;
    

    测量时间的另一种常见方法通常是“序列化”(命名此日期约定的家伙必须认真对待'):

    DateTime start, end = .... // Whatever, assume start is before end
    int days = (end - start).Days;
    

    我想知道我们必须走多长时间才能在几秒钟内相对论时代变得比在一生中到目前为止的地球周围太阳周期的粗略近似更有用:)或者换句话说,当一个时期必须给定一个位置或者表示动作本身有效的函数:)

  • 118

    我不知道如何接受错误的解决方案 . 正确的C#片段由Michael Stum撰写

    这是一个测试片段:

    DateTime bDay = new DateTime(2000, 2, 29);
    DateTime now = new DateTime(2009, 2, 28);
    MessageBox.Show(string.Format("Test {0} {1} {2}",
                    CalculateAgeWrong1(bDay, now),     // outputs 9
                    CalculateAgeWrong2(bDay, now),     // outputs 9
                    CalculateAgeCorrect(bDay, now)));  // outputs 8
    

    在这里你有方法:

    public int CalculateAgeWrong1(DateTime birthDate, DateTime now)
    {
        return new DateTime(now.Subtract(birthDate).Ticks).Year - 1;
    }
    
    public int CalculateAgeWrong2(DateTime birthDate, DateTime now)
    {
        int age = now.Year - birthDate.Year;
    
        if (now < birthDate.AddYears(age))
            age--;
    
        return age;
    }
    
    public int CalculateAgeCorrect(DateTime birthDate, DateTime now)
    {
        int age = now.Year - birthDate.Year;
    
        if (now.Month < birthDate.Month || (now.Month == birthDate.Month && now.Day < birthDate.Day))
            age--;
    
        return age;
    }
    
  • 1807

    我花了一些时间研究这个并想出了这个来计算某人的年龄,月份和日期 . 我已经对2月29日的问题和闰年进行了测试,似乎有效,我很感激任何反馈:

    public void LoopAge(DateTime myDOB, DateTime FutureDate)
    {
        int years = 0;
        int months = 0;
        int days = 0;
    
        DateTime tmpMyDOB = new DateTime(myDOB.Year, myDOB.Month, 1);
    
        DateTime tmpFutureDate = new DateTime(FutureDate.Year, FutureDate.Month, 1);
    
        while (tmpMyDOB.AddYears(years).AddMonths(months) < tmpFutureDate)
        {
            months++;
    
            if (months > 12)
            {
                years++;
                months = months - 12;
            }
        }
    
        if (FutureDate.Day >= myDOB.Day)
        {
            days = days + FutureDate.Day - myDOB.Day;
        }
        else
        {
            months--;
    
            if (months < 0)
            {
                years--;
                months = months + 12;
            }
    
            days +=
                DateTime.DaysInMonth(
                    FutureDate.AddMonths(-1).Year, FutureDate.AddMonths(-1).Month
                ) + FutureDate.Day - myDOB.Day;
    
        }
    
        //add an extra day if the dob is a leap day
        if (DateTime.IsLeapYear(myDOB.Year) && myDOB.Month == 2 && myDOB.Day == 29)
        {
            //but only if the future date is less than 1st March
            if (FutureDate >= new DateTime(FutureDate.Year, 3, 1))
                days++;
        }
    
    }
    
  • 17

    这为这个问题提供了“更多细节” . 也许这就是你要找的东西

    DateTime birth = new DateTime(1974, 8, 29);
    DateTime today = DateTime.Now;
    TimeSpan span = today - birth;
    DateTime age = DateTime.MinValue + span;
    
    // Make adjustment due to MinValue equalling 1/1/1
    int years = age.Year - 1;
    int months = age.Month - 1;
    int days = age.Day - 1;
    
    // Print out not only how many years old they are but give months and days as well
    Console.Write("{0} years, {1} months, {2} days", years, months, days);
    
  • 353

    我发现的最简单的方法就是这样 . 它适用于美国和西欧的地区 . 不能和其他地方说话,特别是像中国这样的地方 . 在最初的年龄计算之后,最多可以进行4次额外比较 .

    public int AgeInYears(DateTime birthDate, DateTime referenceDate)
    {
      Debug.Assert(referenceDate >= birthDate, 
                   "birth date must be on or prior to the reference date");
    
      DateTime birth = birthDate.Date;
      DateTime reference = referenceDate.Date;
      int years = (reference.Year - birth.Year);
    
      //
      // an offset of -1 is applied if the birth date has 
      // not yet occurred in the current year.
      //
      if (reference.Month > birth.Month);
      else if (reference.Month < birth.Month) 
        --years;
      else // in birth month
      {
        if (reference.Day < birth.Day)
          --years;
      }
    
      return years ;
    }
    

    我正在寻找答案,并注意到没有人提到闰日分娩的监管/法律影响 . 例如,per Wikipedia,如果你're born on February 29th in various jurisdictions, you'非闰年生日有所不同:

    • 在英国和香港:这是一年中的序数日,所以第二天,3月1日是你的生日 .

    • 在新西兰:前一天是2月28日,用于驾驶执照,3月1日用于其他目的 .

    • 台湾:2月28日 .

    而且就我所知,在美国,法规对这个问题保持沉默,使其符合普通法以及各种监管机构如何在其规则中定义事物 .

    为此,改进:

    public enum LeapDayRule
    {
      OrdinalDay     = 1 ,
      LastDayOfMonth = 2 ,
    }
    
    static int ComputeAgeInYears(DateTime birth, DateTime reference, LeapYearBirthdayRule ruleInEffect)
    {
      bool isLeapYearBirthday = CultureInfo.CurrentCulture.Calendar.IsLeapDay(birth.Year, birth.Month, birth.Day);
      DateTime cutoff;
    
      if (isLeapYearBirthday && !DateTime.IsLeapYear(reference.Year))
      {
        switch (ruleInEffect)
        {
          case LeapDayRule.OrdinalDay:
            cutoff = new DateTime(reference.Year, 1, 1)
                                 .AddDays(birth.DayOfYear - 1);
            break;
    
          case LeapDayRule.LastDayOfMonth:
            cutoff = new DateTime(reference.Year, birth.Month, 1)
                                 .AddMonths(1)
                                 .AddDays(-1);
            break;
    
          default:
            throw new InvalidOperationException();
        }
      }
      else
      {
        cutoff = new DateTime(reference.Year, birth.Month, birth.Day);
      }
    
      int age = (reference.Year - birth.Year) + (reference >= cutoff ? 0 : -1);
      return age < 0 ? 0 : age;
    }
    

    应该注意的是,此代码假定:

    • 西方(欧洲)的年龄估计,和

    • 日历,如公历,在一个月末插入一个闰日 .

  • 19

    另一个功能,不是我,而是在网上找到并稍微改进了一下:

    public static int GetAge(DateTime birthDate)
    {
        DateTime n = DateTime.Now; // To avoid a race condition around midnight
        int age = n.Year - birthDate.Year;
    
        if (n.Month < birthDate.Month || (n.Month == birthDate.Month && n.Day < birthDate.Day))
            age--;
    
        return age;
    }
    

    我想到的只有两件事:来自那些不使用格里高历的国家的人呢? DateTime.Now是我认为的特定于服务器的文化 . 我对亚洲日历的实际工作知之甚少,我不知道是否有一种简单的方法可以在日历之间转换日期,但万一你想知道那些来自4660年的中国人:-)

  • 78

    我知道的最好的方法是因为闰年和一切都是:

    DateTime birthDate = new DateTime(2000,3,1);
    int age = (int)Math.Floor((DateTime.Now - birthDate).TotalDays / 365.25D);
    

    希望这可以帮助 .

  • 17

    我用这个:

    public static class DateTimeExtensions
    {
        public static int Age(this DateTime birthDate)
        {
            return Age(birthDate, DateTime.Now);
        }
    
        public static int Age(this DateTime birthDate, DateTime offsetDate)
        {
            int result=0;
            result = offsetDate.Year - birthDate.Year;
    
            if (offsetDate.DayOfYear < birthDate.DayOfYear)
            {
                  result--;
            }
    
            return result;
        }
    }
    
  • 27

    我有一个自定义的方法来计算年龄,加上奖励验证消息,以防它有帮助:

    public void GetAge(DateTime dob, DateTime now, out int years, out int months, out int days)
    {
        years = 0;
        months = 0;
        days = 0;
    
        DateTime tmpdob = new DateTime(dob.Year, dob.Month, 1);
        DateTime tmpnow = new DateTime(now.Year, now.Month, 1);
    
        while (tmpdob.AddYears(years).AddMonths(months) < tmpnow)
        {
            months++;
            if (months > 12)
            {
                years++;
                months = months - 12;
            }
        }
    
        if (now.Day >= dob.Day)
            days = days + now.Day - dob.Day;
        else
        {
            months--;
            if (months < 0)
            {
                years--;
                months = months + 12;
            }
            days += DateTime.DaysInMonth(now.AddMonths(-1).Year, now.AddMonths(-1).Month) + now.Day - dob.Day;
        }
    
        if (DateTime.IsLeapYear(dob.Year) && dob.Month == 2 && dob.Day == 29 && now >= new DateTime(now.Year, 3, 1))
            days++;
    
    }   
    
    private string ValidateDate(DateTime dob) //This method will validate the date
    {
        int Years = 0; int Months = 0; int Days = 0;
    
        GetAge(dob, DateTime.Now, out Years, out Months, out Days);
    
        if (Years < 18)
            message =  Years + " is too young. Please try again on your 18th birthday.";
        else if (Years >= 65)
            message = Years + " is too old. Date of Birth must not be 65 or older.";
        else
            return null; //Denotes validation passed
    }
    

    方法调用此处并传递datetime值(如果服务器设置为USA locale,则为MM / dd / yyyy) . 将其替换为消息框或要显示的任何容器:

    DateTime dob = DateTime.Parse("03/10/1982");  
    
    string message = ValidateDate(dob);
    
    lbldatemessage.Visible = !StringIsNullOrWhitespace(message);
    lbldatemessage.Text = message ?? ""; //Ternary if message is null then default to empty string
    

    请记住,您可以按照自己喜欢的方式格式化邮件 .

  • 13
    TimeSpan diff = DateTime.Now - birthdayDateTime;
    string age = String.Format("{0:%y} years, {0:%M} months, {0:%d}, days old", diff);
    

    我不确定你究竟是怎么回事你,所以我做了一个可读的字符串 .

  • 29

    我认为迄今为止的任何答案都没有提供以不同方式计算年龄的文化 . 例如,参见East Asian Age Reckoning与西方的情况相比 .

    任何真正的答案都必须包括本地化 . 在这个例子中,Strategy Pattern可能是有序的 .

  • 30

    我创建了一个SQL Server用户定义函数来计算某人的年龄,考虑到他们的出生日期 . 当您需要它作为查询的一部分时,这非常有用:

    using System;
    using System.Data;
    using System.Data.Sql;
    using System.Data.SqlClient;
    using System.Data.SqlTypes;
    using Microsoft.SqlServer.Server;
    
    public partial class UserDefinedFunctions
    {
        [SqlFunction(DataAccess = DataAccessKind.Read)]
        public static SqlInt32 CalculateAge(string strBirthDate)
        {
            DateTime dtBirthDate = new DateTime();
            dtBirthDate = Convert.ToDateTime(strBirthDate);
            DateTime dtToday = DateTime.Now;
    
            // get the difference in years
            int years = dtToday.Year - dtBirthDate.Year;
    
            // subtract another year if we're before the
            // birth day in the current year
            if (dtToday.Month < dtBirthDate.Month || (dtToday.Month == dtBirthDate.Month && dtToday.Day < dtBirthDate.Day))
                years=years-1;
    
            int intCustomerAge = years;
            return intCustomerAge;
        }
    };
    
  • 67

    保持简单(可能是愚蠢:)) .

    DateTime birth = new DateTime(1975, 09, 27, 01, 00, 00, 00);
    TimeSpan ts = DateTime.Now - birth;
    Console.WriteLine("You are approximately " + ts.TotalSeconds.ToString() + " seconds old.");
    
  • 23

    我的建议

    int age = (int) ((DateTime.Now - bday).TotalDays/365.242199);
    

    这似乎在正确的日期改变了一年 . (我现在测试到107岁)

  • 11

    以下方法(从Time Period Library for .NET类DateDiff中提取)考虑文化信息的日历:

    // ----------------------------------------------------------------------
    private static int YearDiff( DateTime date1, DateTime date2 )
    {
      return YearDiff( date1, date2, DateTimeFormatInfo.CurrentInfo.Calendar );
    } // YearDiff
    
    // ----------------------------------------------------------------------
    private static int YearDiff( DateTime date1, DateTime date2, Calendar calendar )
    {
      if ( date1.Equals( date2 ) )
      {
        return 0;
      }
    
      int year1 = calendar.GetYear( date1 );
      int month1 = calendar.GetMonth( date1 );
      int year2 = calendar.GetYear( date2 );
      int month2 = calendar.GetMonth( date2 );
    
      // find the the day to compare
      int compareDay = date2.Day;
      int compareDaysPerMonth = calendar.GetDaysInMonth( year1, month1 );
      if ( compareDay > compareDaysPerMonth )
      {
        compareDay = compareDaysPerMonth;
      }
    
      // build the compare date
      DateTime compareDate = new DateTime( year1, month2, compareDay,
        date2.Hour, date2.Minute, date2.Second, date2.Millisecond );
      if ( date2 > date1 )
      {
        if ( compareDate < date1 )
        {
          compareDate = compareDate.AddYears( 1 );
        }
      }
      else
      {
        if ( compareDate > date1 )
        {
          compareDate = compareDate.AddYears( -1 );
        }
      }
      return year2 - calendar.GetYear( compareDate );
    } // YearDiff
    

    用法:

    // ----------------------------------------------------------------------
    public void CalculateAgeSamples()
    {
      PrintAge( new DateTime( 2000, 02, 29 ), new DateTime( 2009, 02, 28 ) );
      // > Birthdate=29.02.2000, Age at 28.02.2009 is 8 years
      PrintAge( new DateTime( 2000, 02, 29 ), new DateTime( 2012, 02, 28 ) );
      // > Birthdate=29.02.2000, Age at 28.02.2012 is 11 years
    } // CalculateAgeSamples
    
    // ----------------------------------------------------------------------
    public void PrintAge( DateTime birthDate, DateTime moment )
    {
      Console.WriteLine( "Birthdate={0:d}, Age at {1:d} is {2} years", birthDate, moment, YearDiff( birthDate, moment ) );
    } // PrintAge
    
  • 8

    我使用ScArcher2的解决方案来准确计算一个人的年龄,但我需要进一步计算它们的月份和日期以及年份 .

    public static Dictionary<string,int> CurrentAgeInYearsMonthsDays(DateTime? ndtBirthDate, DateTime? ndtReferralDate)
        {
            //----------------------------------------------------------------------
            // Can't determine age if we don't have a dates.
            //----------------------------------------------------------------------
            if (ndtBirthDate == null) return null;
            if (ndtReferralDate == null) return null;
    
            DateTime dtBirthDate = Convert.ToDateTime(ndtBirthDate);
            DateTime dtReferralDate = Convert.ToDateTime(ndtReferralDate);
    
            //----------------------------------------------------------------------
            // Create our Variables
            //----------------------------------------------------------------------
            Dictionary<string, int> dYMD = new Dictionary<string,int>();
            int iNowDate, iBirthDate, iYears, iMonths, iDays;
            string sDif = "";
    
            //----------------------------------------------------------------------
            // Store off current date/time and DOB into local variables
            //---------------------------------------------------------------------- 
            iNowDate = int.Parse(dtReferralDate.ToString("yyyyMMdd"));
            iBirthDate = int.Parse(dtBirthDate.ToString("yyyyMMdd"));
    
            //----------------------------------------------------------------------
            // Calculate Years
            //----------------------------------------------------------------------
            sDif = (iNowDate - iBirthDate).ToString();
            iYears = int.Parse(sDif.Substring(0, sDif.Length - 4));
    
            //----------------------------------------------------------------------
            // Store Years in Return Value
            //----------------------------------------------------------------------
            dYMD.Add("Years", iYears);
    
            //----------------------------------------------------------------------
            // Calculate Months
            //----------------------------------------------------------------------
            if (dtBirthDate.Month > dtReferralDate.Month)
                iMonths = 12 - dtBirthDate.Month + dtReferralDate.Month - 1;
            else
                iMonths = dtBirthDate.Month - dtReferralDate.Month;
    
            //----------------------------------------------------------------------
            // Store Months in Return Value
            //----------------------------------------------------------------------
            dYMD.Add("Months", iMonths);
    
            //----------------------------------------------------------------------
            // Calculate Remaining Days
            //----------------------------------------------------------------------
            if (dtBirthDate.Day > dtReferralDate.Day)
                //Logic: Figure out the days in month previous to the current month, or the admitted month.
                //       Subtract the birthday from the total days which will give us how many days the person has lived since their birthdate day the previous month.
                //       then take the referral date and simply add the number of days the person has lived this month.
    
                //If referral date is january, we need to go back to the following year's December to get the days in that month.
                if (dtReferralDate.Month == 1)
                    iDays = DateTime.DaysInMonth(dtReferralDate.Year - 1, 12) - dtBirthDate.Day + dtReferralDate.Day;       
                else
                    iDays = DateTime.DaysInMonth(dtReferralDate.Year, dtReferralDate.Month - 1) - dtBirthDate.Day + dtReferralDate.Day;       
            else
                iDays = dtReferralDate.Day - dtBirthDate.Day;             
    
            //----------------------------------------------------------------------
            // Store Days in Return Value
            //----------------------------------------------------------------------
            dYMD.Add("Days", iDays);
    
            return dYMD;
    }
    
  • 16

    一个易于理解和简单的解决方案 .

    // Save today's date.
    var today = DateTime.Today;
    // Calculate the age.
    var age = today.Year - birthdate.Year;
    // Go back to the year the person was born in case of a leap year
    if (birthdate > today.AddYears(-age)) age--;
    

    但是,这假设您正在寻找西方的年龄概念,而不是使用East Asian reckoning .

  • 100

    我做了一个小改动Mark Soen's回答:我重写了第三行,以便可以更容易地解析表达式 .

    public int AgeInYears(DateTime bday)
    {
        DateTime now = DateTime.Today;
        int age = now.Year - bday.Year;            
        if (bday.AddYears(age) > now) 
            age--;
        return age;
    }
    

    为了清晰起见,我还把它变成了一个功能 .

  • 13

    这是另一个答案:

    public static int AgeInYears(DateTime birthday, DateTime today)
    {
        return ((today.Year - birthday.Year) * 372 + (today.Month - birthday.Month) * 31 + (today.Day - birthday.Day)) / 372;
    }
    

    这已经过广泛的单元测试 . 它确实看起来有点“神奇” . 如果每个月有31天,则数字372是一年中的天数 .

    它的工作原理(lifted from here)的解释是:

    设置Yn = DateTime.Now.Year,Yb = birthday.Year,Mn = DateTime.Now.Month,Mb = birthday.Month,Dn = DateTime.Now.Day,Db = birthday.Day age = Yn - Yb( 31 *(Mn - Mb)(Dn - Db))/ 372我们知道,如果已经达到日期,我们需要的是Yn-Yb,如果没有,则为Yn-Yb-1 . a)如果Mn <Mb,我们有-341 <= 31 *(Mn-Mb)<= -31和-30 <= Dn-Db <= 30-371 <= 31 *(Mn - Mb)(Dn - Db) )<= -1有整数除法(31 *(Mn - Mb)(Dn - Db))/ 372 = -1 b)如果Mn = Mb且Dn <Db,我们有31 *(Mn - Mb)= 0和-30 <= Dn-Db <= -1对于整数除法,再次(31 *(Mn - Mb)(Dn - Db))/ 372 = -1 c)如果Mn> Mb,我们有31 <= 31 *( Mn-Mb)<= 341和-30 <= Dn-Db <= 30 1 <= 31 *(Mn-Mb)(Dn-Db)<= 371具有整数除法(31 *(Mn-Mb)(Dn - Db))/ 372 = 0 d)如果Mn = Mb且Dn> Db,我们有31 *(Mn - Mb)= 0和1 <= Dn-Db <= 30再次整数除(31 *(Mn - Mb)(Dn-Db))/ 372 = 0 e)如果Mn = Mb且Dn = Db,我们得到31 *(Mn-Mb)Dn-Db = 0,因此(31 *(Mn-Mb)(Dn-) Db))/ 372 = 0

  • 45

    这个解决方案怎么样?

    static string CalcAge(DateTime birthDay)
    {
        DateTime currentDate = DateTime.Now;         
        int approximateAge = currentDate.Year - birthDay.Year;
        int daysToNextBirthDay = (birthDay.Month * 30 + birthDay.Day) - 
            (currentDate.Month * 30 + currentDate.Day) ;
    
        if (approximateAge == 0 || approximateAge == 1)
        {                
            int month =  Math.Abs(daysToNextBirthDay / 30);
            int days = Math.Abs(daysToNextBirthDay % 30);
    
            if (month == 0)
                return "Your age is: " + daysToNextBirthDay + " days";
    
            return "Your age is: " + month + " months and " + days + " days"; ;
        }
    
        if (daysToNextBirthDay > 0)
            return "Your age is: " + --approximateAge + " Years";
    
        return "Your age is: " + approximateAge + " Years"; ;
    }
    
  • 7

    我们需要考虑小于1年的人吗?作为中国文化,我们将小婴儿的年龄描述为2个月或4周 .

    下面是我的实现,它并不像我想象的那么简单,特别是像2/28那样处理日期 .

    public static string HowOld(DateTime birthday, DateTime now)
    {
        if (now < birthday)
            throw new ArgumentOutOfRangeException("birthday must be less than now.");
    
        TimeSpan diff = now - birthday;
        int diffDays = (int)diff.TotalDays;
    
        if (diffDays > 7)//year, month and week
        {
            int age = now.Year - birthday.Year;
    
            if (birthday > now.AddYears(-age))
                age--;
    
            if (age > 0)
            {
                return age + (age > 1 ? " years" : " year");
            }
            else
            {// month and week
                DateTime d = birthday;
                int diffMonth = 1;
    
                while (d.AddMonths(diffMonth) <= now)
                {
                    diffMonth++;
                }
    
                age = diffMonth-1;
    
                if (age == 1 && d.Day > now.Day)
                    age--;
    
                if (age > 0)
                {
                    return age + (age > 1 ? " months" : " month");
                }
                else
                {
                    age = diffDays / 7;
                    return age + (age > 1 ? " weeks" : " week");
                }
            }
        }
        else if (diffDays > 0)
        {
            int age = diffDays;
            return age + (age > 1 ? " days" : " day");
        }
        else
        {
            int age = diffDays;
            return "just born";
        }
    }
    

    此实现已通过测试用例 .

    [TestMethod]
    public void TestAge()
    {
        string age = HowOld(new DateTime(2011, 1, 1), new DateTime(2012, 11, 30));
        Assert.AreEqual("1 year", age);
    
        age = HowOld(new DateTime(2011, 11, 30), new DateTime(2012, 11, 30));
        Assert.AreEqual("1 year", age);
    
        age = HowOld(new DateTime(2001, 1, 1), new DateTime(2012, 11, 30));
        Assert.AreEqual("11 years", age);
    
        age = HowOld(new DateTime(2012, 1, 1), new DateTime(2012, 11, 30));
        Assert.AreEqual("10 months", age);
    
        age = HowOld(new DateTime(2011, 12, 1), new DateTime(2012, 11, 30));
        Assert.AreEqual("11 months", age);
    
        age = HowOld(new DateTime(2012, 10, 1), new DateTime(2012, 11, 30));
        Assert.AreEqual("1 month", age);
    
        age = HowOld(new DateTime(2008, 2, 28), new DateTime(2009, 2, 28));
        Assert.AreEqual("1 year", age);
    
        age = HowOld(new DateTime(2008, 3, 28), new DateTime(2009, 2, 28));
        Assert.AreEqual("11 months", age);
    
        age = HowOld(new DateTime(2008, 3, 28), new DateTime(2009, 3, 28));
        Assert.AreEqual("1 year", age);
    
        age = HowOld(new DateTime(2009, 1, 28), new DateTime(2009, 2, 28));
        Assert.AreEqual("1 month", age);
    
        age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 3, 1));
        Assert.AreEqual("1 month", age);
    
        // NOTE.
        // new DateTime(2008, 1, 31).AddMonths(1) == new DateTime(2009, 2, 28);
        // new DateTime(2008, 1, 28).AddMonths(1) == new DateTime(2009, 2, 28);
        age = HowOld(new DateTime(2009, 1, 31), new DateTime(2009, 2, 28));
        Assert.AreEqual("4 weeks", age);
    
        age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 2, 28));
        Assert.AreEqual("3 weeks", age);
    
        age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 3, 1));
        Assert.AreEqual("1 month", age);
    
        age = HowOld(new DateTime(2012, 11, 5), new DateTime(2012, 11, 30));
        Assert.AreEqual("3 weeks", age);
    
        age = HowOld(new DateTime(2012, 11, 1), new DateTime(2012, 11, 30));
        Assert.AreEqual("4 weeks", age);
    
        age = HowOld(new DateTime(2012, 11, 20), new DateTime(2012, 11, 30));
        Assert.AreEqual("1 week", age);
    
        age = HowOld(new DateTime(2012, 11, 25), new DateTime(2012, 11, 30));
        Assert.AreEqual("5 days", age);
    
        age = HowOld(new DateTime(2012, 11, 29), new DateTime(2012, 11, 30));
        Assert.AreEqual("1 day", age);
    
        age = HowOld(new DateTime(2012, 11, 30), new DateTime(2012, 11, 30));
        Assert.AreEqual("just born", age);
    
        age = HowOld(new DateTime(2000, 2, 29), new DateTime(2009, 2, 28));
        Assert.AreEqual("8 years", age);
    
        age = HowOld(new DateTime(2000, 2, 29), new DateTime(2009, 3, 1));
        Assert.AreEqual("9 years", age);
    
        Exception e = null;
    
        try
        {
            age = HowOld(new DateTime(2012, 12, 1), new DateTime(2012, 11, 30));
        }
        catch (ArgumentOutOfRangeException ex)
        {
            e = ex;
        }
    
        Assert.IsTrue(e != null);
    }
    

    希望它有用 .

  • 7

    这是我们在这里使用的版本 . 它有效,而且相当简单 . 这与杰夫的想法相同,但我认为它更清晰一点,因为它分离了减去一个的逻辑,所以它更容易理解 .

    public static int GetAge(this DateTime dateOfBirth, DateTime dateAsAt)
    {
        return dateAsAt.Year - dateOfBirth.Year - (dateOfBirth.DayOfYear < dateAsAt.DayOfYear ? 0 : 1);
    }
    

    如果您认为有些事情不清楚,您可以扩展三元运算符以使其更清晰 .

    显然,这是作为 DateTime 上的扩展方法完成的,但显然你可以 grab 那一行代码完成工作并把它放在任何地方 . 这里我们有另一个在 DateTime.Now 中传递的Extension方法的重载,只是为了完整性 .

  • 8

    这是一种奇怪的方法,但如果您将日期格式化为 yyyymmdd 并从当前日期减去出生日期,则删除您已经获得年龄的最后4位数字:)

    我不知道C#,但我相信这会适用于任何语言 .

    20080814 - 19800703 = 280111
    

    丢弃最后4位= 28 .

    C#代码:

    int now = int.Parse(DateTime.Now.ToString("yyyyMMdd"));
    int dob = int.Parse(dateOfBirth.ToString("yyyyMMdd"));
    int age = (now - dob) / 10000;
    

    或者可选地,没有以扩展方法的形式进行所有类型转换 . 错误检查省略:

    public static Int32 GetAge(this DateTime dateOfBirth)
    {
        var today = DateTime.Today;
    
        var a = (today.Year * 100 + today.Month) * 100 + today.Day;
        var b = (dateOfBirth.Year * 100 + dateOfBirth.Month) * 100 + dateOfBirth.Day;
    
        return (a - b) / 10000;
    }
    
  • 22

    对此的简单回答是如下所示应用 AddYears ,因为这是闰年2月29日增加年份的唯一本机方法,并获得2月28日的正确年份的正确结果 .

    有些人认为3月1日是闰人的生日,但是.Net和任何官方规则都不支持这一点,也没有共同的逻辑解释为什么2月份出生的人应该在另一个月有75%的生日 .

    此外,Age方法适合作为 DateTime 的扩展添加 . 通过这种方式,您可以最简单地获得年龄办法:

    • 列出项目

    int age = birthDate.Age();

    public static class DateTimeExtensions
    {
        /// <summary>
        /// Calculates the age in years of the current System.DateTime object today.
        /// </summary>
        /// <param name="birthDate">The date of birth</param>
        /// <returns>Age in years today. 0 is returned for a future date of birth.</returns>
        public static int Age(this DateTime birthDate)
        {
            return Age(birthDate, DateTime.Today);
        }
    
        /// <summary>
        /// Calculates the age in years of the current System.DateTime object on a later date.
        /// </summary>
        /// <param name="birthDate">The date of birth</param>
        /// <param name="laterDate">The date on which to calculate the age.</param>
        /// <returns>Age in years on a later day. 0 is returned as minimum.</returns>
        public static int Age(this DateTime birthDate, DateTime laterDate)
        {
            int age;
            age = laterDate.Year - birthDate.Year;
    
            if (age > 0)
            {
                age -= Convert.ToInt32(laterDate.Date < birthDate.Date.AddYears(age));
            }
            else
            {
                age = 0;
            }
    
            return age;
        }
    }
    

    现在,运行此测试:

    class Program
    {
        static void Main(string[] args)
        {
            RunTest();
        }
    
        private static void RunTest()
        {
            DateTime birthDate = new DateTime(2000, 2, 28);
            DateTime laterDate = new DateTime(2011, 2, 27);
            string iso = "yyyy-MM-dd";
    
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Console.WriteLine("Birth date: " + birthDate.AddDays(i).ToString(iso) + "  Later date: " + laterDate.AddDays(j).ToString(iso) + "  Age: " + birthDate.AddDays(i).Age(laterDate.AddDays(j)).ToString());
                }
            }
    
            Console.ReadKey();
        }
    }
    

    关键日期的例子如下:

    Birth date: 2000-02-29 Later date: 2011-02-28 Age: 11

    输出:

    {
        Birth date: 2000-02-28  Later date: 2011-02-27  Age: 10
        Birth date: 2000-02-28  Later date: 2011-02-28  Age: 11
        Birth date: 2000-02-28  Later date: 2011-03-01  Age: 11
        Birth date: 2000-02-29  Later date: 2011-02-27  Age: 10
        Birth date: 2000-02-29  Later date: 2011-02-28  Age: 11
        Birth date: 2000-02-29  Later date: 2011-03-01  Age: 11
        Birth date: 2000-03-01  Later date: 2011-02-27  Age: 10
        Birth date: 2000-03-01  Later date: 2011-02-28  Age: 10
        Birth date: 2000-03-01  Later date: 2011-03-01  Age: 11
    }
    

    而对于2012-02-28的后期日期:

    {
        Birth date: 2000-02-28  Later date: 2012-02-28  Age: 12
        Birth date: 2000-02-28  Later date: 2012-02-29  Age: 12
        Birth date: 2000-02-28  Later date: 2012-03-01  Age: 12
        Birth date: 2000-02-29  Later date: 2012-02-28  Age: 11
        Birth date: 2000-02-29  Later date: 2012-02-29  Age: 12
        Birth date: 2000-02-29  Later date: 2012-03-01  Age: 12
        Birth date: 2000-03-01  Later date: 2012-02-28  Age: 11
        Birth date: 2000-03-01  Later date: 2012-02-29  Age: 11
        Birth date: 2000-03-01  Later date: 2012-03-01  Age: 12
    }
    
  • 44

    这是一个解决方案 .

    DateTime dateOfBirth = new DateTime(2000, 4, 18);
    DateTime currentDate = DateTime.Now;
    
    int ageInYears = 0;
    int ageInMonths = 0;
    int ageInDays = 0;
    
    ageInDays = currentDate.Day - dateOfBirth.Day;
    ageInMonths = currentDate.Month - dateOfBirth.Month;
    ageInYears = currentDate.Year - dateOfBirth.Year;
    
    if (ageInDays < 0)
    {
        ageInDays += DateTime.DaysInMonth(currentDate.Year, currentDate.Month);
        ageInMonths = ageInMonths--;
    
        if (ageInMonths < 0)
        {
            ageInMonths += 12;
            ageInYears--;
        }
    }
    
    if (ageInMonths < 0)
    {
        ageInMonths += 12;
        ageInYears--;
    }
    
    Console.WriteLine("{0}, {1}, {2}", ageInYears, ageInMonths, ageInDays);
    

相关问题