programing

DateTime 유형의 생일을 기준으로 누군가의 나이를 계산하려면 어떻게 해야 합니까?

goodcopy 2023. 5. 28. 22:16
반응형

DateTime 유형의 생일을 기준으로 누군가의 나이를 계산하려면 어떻게 해야 합니까?

가 주어지면,DateTime한 사람의 생일을 나타내는, 나이를 몇 년으로 계산하려면 어떻게 계산해야 합니까?

이해하기 쉽고 간단한 솔루션입니다.

// Save today's date.
var today = DateTime.Today;

// Calculate the age.
var age = today.Year - birthdate.Year;

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

하지만, 이것은 여러분이 동양의 계산법을 사용하지 않고 그 시대의 서양적인 생각을 찾고 있다고 가정합니다.

이렇게 하는 것은 이상한 방법이지만, 만약 당신이 날짜를 포맷한다면.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;
}

다음은 테스트 스니펫입니다.

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

public int CalculateAgeCorrect2(DateTime birthDate, DateTime now)
{
    int age = now.Year - birthDate.Year;

    // For leap years we need this
    if (birthDate > now.AddYears(-age)) 
        age--;
    // Don't use:
    // if (birthDate.AddYears(age) > now) 
    //     age--;

    return age;
}

이에 대한 간단한 대답은 적용하는 것입니다.AddYears이 방법이 윤년의 2월 29일에 연도를 더하고 평년의 2월 28일의 정확한 결과를 얻을 수 있는 유일한 네이티브 방법이기 때문에 아래와 같이 표시됩니다.

어떤 사람들은 3월 1일이 도약하는 사람들의 생일이라고 느끼지만 둘 다 그렇지 않습니다.인터넷이나 어떤 공식적인 규칙도 이것을 지지하지 않으며, 일반적인 논리도 2월에 태어난 일부 사람들이 다른 달에 75%의 생일을 가져야 하는 이유를 설명하지 않습니다.

또한, Age 메소드는 다음의 확장으로 추가될 수 있습니다.DateTime이를 통해 가장 간단한 방법으로 연령을 확인할 수 있습니다.

  1. 리스트 항목

intage = 생년월일.연령();

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

중요한 날짜의 예는 다음과 같습니다.

생년월일: 2000-02-29 이후 날짜: 2011-02-28세: 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
}

나의 제안

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

그것은 정확한 날짜에 해가 바뀌는 것처럼 보입니다.(107세까지 검사를 받았습니다.)

또 다른 기능은, 제가 만든 것이 아니라 웹에서 찾아 조금 개선했습니다.

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

딱 두 가지 생각이 납니다.그레고리력을 사용하지 않는 나라의 사람들은 어떻습니까?날짜 시간.지금은 서버별 문화에 있다고 생각합니다.저는 아시아 달력을 실제로 사용하는 것에 대해 전혀 지식이 없고 달력 사이의 날짜를 쉽게 변환할 수 있는 방법이 있는지는 모르겠지만, 4660년의 중국 남자들에 대해 궁금할 경우를 대비해서요 :-)

2 해결해야 할 주요 문제는 다음과 같습니다.

정확한 연령 계산(년, 월, 일 등)

일반적으로 인식되는 나이 계산 - 사람들은 보통 그들이 정확히 몇 살인지는 신경 쓰지 않고, 그들은 단지 올해 생일이 언제인지만 신경 씁니다.


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에 대한 해결책은 총 연령을 결정하는 데 있어 그렇게 정확하지는 않지만 사람들이 정확하게 인식하는 해결책입니다.사람들은 또한 그들의 나이를 "수동으로" 계산할 때 그것을 보통 사용합니다.

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.:

  • 이것이 제가 선호하는 솔루션입니다.
  • 날짜 시간을 사용할 수 없습니다.일 년 또는 시간 범위(윤년 시 일 수를 이동할 때)
  • 가독성을 위해 줄을 조금 더 놓았습니다.

음 하나만 더...저는 그것을 위해 두 가지 정적 오버로드 방법을 만들 것입니다. 하나는 보편적인 사용을 위한 것이고, 두 번째는 사용 친화적인 방법입니다.

public static int GetAge(DateTime bithDay, DateTime today) 
{ 
  //chosen solution method body
}

public static int GetAge(DateTime birthDay) 
{ 
  return GetAge(birthDay, DateTime.Now);
}

윤년과 모든 것 때문에 제가 아는 가장 좋은 방법은 다음과 같습니다.

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

여기 한 줄기 글이 있습니다.

int age = new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year-1;

여기서 사용하는 버전입니다.그것은 효과가 있고, 꽤 간단합니다.제프와 같은 생각이지만 하나를 빼는 논리를 구분하기 때문에 조금 더 명확하다고 생각합니다. 그래서 조금 더 이해하기 쉽습니다.

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

3진 연산자를 더 명확하게 하기 위해 확장할 수 있습니다. 만약 여러분이 그런 것이 불분명하다고 생각한다면 말이죠.

분명히 이것은 확장 방법으로 수행됩니다.DateTime하지만 분명히 당신은 작업을 수행하는 코드 한 줄을 잡고 어디에나 놓을 수 있습니다.여기에 전달되는 확장 메서드의 또 다른 오버로드가 있습니다.DateTime.Now완전성을 위해서만.

이것은 이 질문에 대해 "자세한 내용"을 제공합니다.아마도 이것이 당신이 찾고 있는 것일 것입니다.

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

사용자:

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

여기 또 다른 대답이 있습니다.

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

이것은 광범위하게 유닛 테스트를 거쳤습니다.그것은 약간 "마법적"으로 보입니다.숫자 372는 한 달에 31일이 있는 경우 1년 동안의 일수입니다.

작동하는 이유(여기서 들어올려짐)에 대한 설명은 다음과 같습니다.

ㅠㅠ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그렇지 않다면

에 약Mn<Mb,우리는 가지고 있다.-341 <= 31*(Mn-Mb) <= -31 and -30 <= Dn-Db <= 30

-371 <= 31*(Mn - Mb) + (Dn - Db) <= -1

정수 나눗셈 포함

(31*(Mn - Mb) + (Dn - Db)) / 372 = -1

에 약Mn=Mb그리고.Dn<Db,우리는 가지고 있다.31*(Mn - Mb) = 0 and -30 <= Dn-Db <= -1

정수 나눗셈을 사용하면 다시

(31*(Mn - Mb) + (Dn - Db)) / 372 = -1

에 약Mn>Mb,우리는 가지고 있다.31 <= 31*(Mn-Mb) <= 341 and -30 <= Dn-Db <= 30

1 <= 31*(Mn - Mb) + (Dn - Db) <= 371

정수 나눗셈 포함

(31*(Mn - Mb) + (Dn - Db)) / 372 = 0

에 약Mn=Mb그리고.Dn>Db,우리는 가지고 있다.31*(Mn - Mb) = 0 and 1 <= Dn-Db <= 30

정수 나눗셈을 사용하면 다시

(31*(Mn - Mb) + (Dn - Db)) / 372 = 0

에 약Mn=Mb그리고.Dn=Db,우리는 가지고 있다.31*(Mn - Mb) + Dn-Db = 0

그므로러.(31*(Mn - Mb) + (Dn - Db)) / 372 = 0

저는 누군가의 생일을 기준으로 나이를 계산하는 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;
    }
};

저는 이 연구에 시간을 들여서 몇 년, 몇 달, 며칠 안에 누군가의 나이를 계산하기 위해 이것을 생각해 냈습니다.저는 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++;
    }

}

우리는 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);
}

도움이 되길 바랍니다.

제가 찾은 가장 간단한 방법은 이것입니다.미국 및 서유럽 지역에서 올바르게 작동합니다.다른 지역, 특히 중국과 같은 곳에서는 말을 할 수 없습니다. 최대 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 ;
}

저는 이에 대한 답을 검토하던 중 아무도 윤일 출산의 규제/법적 의미에 대해 언급하지 않았다는 것을 알게 되었습니다.를 들어, 위키백과에 따르면, 만약 당신이 다양한 관할권에서 2월 29일에 태어난다면, 당신은 윤년이 아닌 생일은 다양합니다:

  • 영국과 홍콩에서는, 1년 중에서 보통 날입니다. 그래서 다음날, 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;
}

이 코드는 다음을 가정한다는 점에 유의해야 합니다.

  • 서구(유럽)의 나이 계산.
  • 그레고리력과 같이 한 달의 끝에 하나의 윤일을 삽입하는 달력입니다.

단순성 유지(그리고 바보일 수도 있음).

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

이것은 직접적인 대답이 아니라, 준과학적 관점에서 당면한 문제에 대한 철학적 추론에 가깝습니다.

저는 질문이 나이를 측정하는 단위나 문화를 명시하지 않는다고 주장하고 싶습니다. 대부분의 답변은 정수 연간 표현을 가정하는 것 같습니다. SI 는 시에대한 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;

나는 우리가 지금까지 한 사람의 일생 동안 지구 주위 태양 주기의 대략적인 근사치보다 몇 초 안에 상대론적인 나이가 더 유용해지기 전에 얼마나 오래 가야 하는지 궁금하다 :) 또는 다른 말로, 기간이 그 자체가 유효하기 위해 운동을 나타내는 위치나 함수가 주어져야 할 때 :)

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

정확히 얼마나 돌려주길 원하는지 모르겠어요. 그래서 그냥 읽을 수 있는 끈을 만들었어요.

여기 해결책이 있습니다.

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

이것은 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;
}




나이를 계산할 수 있는 맞춤형 방법과 다음과 같은 경우를 대비해 보너스 유효성 확인 메시지를 제공합니다.

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
}

메서드는 여기를 호출하여 날짜 시간 값을 전달합니다(서버가 미국 로케일로 설정된 경우 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

메시지 형식은 원하는 대로 지정할 수 있습니다.

이 해결책은 어떻습니까?

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

이 고전적인 질문은 노다 타임의 해결책을 얻을 자격이 있습니다.

static int GetAge(LocalDate dateOfBirth)
{
    Instant now = SystemClock.Instance.Now;

    // The target time zone is important.
    // It should align with the *current physical location* of the person
    // you are talking about.  When the whereabouts of that person are unknown,
    // then you use the time zone of the person who is *asking* for the age.
    // The time zone of birth is irrelevant!

    DateTimeZone zone = DateTimeZoneProviders.Tzdb["America/New_York"];

    LocalDate today = now.InZone(zone).Date;

    Period period = Period.Between(dateOfBirth, today, PeriodUnits.Years);

    return (int) period.Years;
}

용도:

LocalDate dateOfBirth = new LocalDate(1976, 8, 27);
int age = GetAge(dateOfBirth);

다음과 같은 개선 사항에 관심이 있을 수도 있습니다.

  • 시계에 시간을 보내는 것과 같습니다.IClock사하는대에를 사용하는 SystemClock.Instance테스트 가능성을 향상시킬 수 있습니다.

  • 목표 시간대가 변경될 가능성이 높기 때문에 다음과 같은 작업을 수행해야 합니다.DateTimeZone매개 변수도 마찬가지입니다.

이 주제에 대한 블로그 게시물도 참조:생일 및 기타 기념일 처리

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  

다음 접근 방식(.NET 클래스 DateDiff의 Time Period Library에서 추출)은 문화 정보의 달력을 고려합니다.

// ----------------------------------------------------------------------
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

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

이것은 간단하고 제 요구에 정확한 것 같습니다.저는 윤년의 목적을 위해 그 사람이 생일을 축하하기로 선택한 때와 상관없이 그들은 마지막 생일로부터 365일이 지나기 전까지는 엄밀히 말하면 한 살 더 먹지 않는다고 가정하고 있습니다(즉, 2월 28일이 그들을 한 살 더 먹지는 않습니다).

DateTime now = DateTime.Today;
DateTime birthday = new DateTime(1991, 02, 03);//3rd feb

int age = now.Year - birthday.Year;

if (now.Month < birthday.Month || (now.Month == birthday.Month && now.Day < birthday.Day))//not had bday this year yet
  age--;

return age;

언급URL : https://stackoverflow.com/questions/9/how-do-i-calculate-someones-age-based-on-a-datetime-type-birthday

반응형