DateTime
주어지면 나이를 몇 년 단위로 계산합니까?
질문자 :Community Wiki
이해하기 쉽고 간단한 솔루션입니다.
// 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--;
그러나 이것은 당신이 동아시아 계산법을 사용하지 않고 시대 에 대한 서구 개념을 찾고 있다고 가정합니다.
Community Wiki
이것은 이상한 방법이지만 날짜 형식을 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; }
Community Wiki
다음은 테스트 스니펫입니다.
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; }
Community Wiki
이에 대한 간단한 답은 AddYears
를 적용하면 윤년의 2월 29일에 연도를 추가하여 평년의 경우 2월 28일의 정확한 결과를 얻을 수 있는 유일한 기본 방법이기 때문입니다.
어떤 사람들은 3월 1일이 도약의 생일이라고 생각하지만 .Net이나 어떤 공식 규칙도 이를 지원하지 않으며 일반적인 논리도 2월에 태어난 사람들이 생일의 75%를 다른 달에 가져야 하는 이유를 설명하지 않습니다.
DateTime
대한 확장으로 추가될 수 있습니다. 이를 통해 가장 간단한 방법으로 나이를 얻을 수 있습니다.
- 목록 항목
정수 나이 = 생년월일.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(); } }
중요한 날짜의 예는 다음과 같습니다.
생년월일: 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년 2월 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 }
Community Wiki
나의 제안
int age = (int) ((DateTime.Now - bday).TotalDays/365.242199);
그것은 올바른 날짜에 연도가 바뀌는 것 같습니다. (나는 107세까지 스팟 테스트를 했다.)
Community Wiki
내가 아니라 웹에서 찾은 또 다른 기능으로 약간 수정했습니다.
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년의 중국인에 대해 궁금한 경우를 대비하여 :-)
Community Wiki
2 해결해야 할 주요 문제는 다음과 같습니다.
1. 정확한 나이 를 년, 월, 일 등으로 계산합니다.
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에 대한 참고 사항:
- 이것은 내가 선호하는 솔루션입니다
- DateTime.DayOfYear 또는 TimeSpan은 윤년의 일 수를 변경하므로 사용할 수 없습니다.
- 가독성을 위해 줄을 조금 더 넣었습니다.
한 가지만 더 참고하세요 ... 저는 2개의 정적 오버로드 메서드를 만들 것입니다. 하나는 범용 사용을 위한 것이고, 두 번째는 사용 편의성을 위한 것입니다.
public static int GetAge(DateTime bithDay, DateTime today) { //chosen solution method body } public static int GetAge(DateTime birthDay) { return GetAge(birthDay, DateTime.Now); }
Community Wiki
다음은 한 줄짜리입니다.
int age = new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year-1;
Community Wiki
윤년과 모든 것 때문에 내가 아는 가장 좋은 방법은 다음과 같습니다.
DateTime birthDate = new DateTime(2000,3,1); int age = (int)Math.Floor((DateTime.Now - birthDate).TotalDays / 365.25D);
Community Wiki
여기에서 사용하는 버전입니다. 작동하며 상당히 간단합니다. 제프님과 같은 생각인데 1을 빼는 논리를 따로 분리해서 풀어서 좀 더 이해하기 쉬운 것 같아요.
public static int GetAge(this DateTime dateOfBirth, DateTime dateAsAt) { return dateAsAt.Year - dateOfBirth.Year - (dateOfBirth.DayOfYear < dateAsAt.DayOfYear ? 0 : 1); }
그런 종류의 것이 불분명하다고 생각되면 삼항 연산자를 확장하여 더 명확하게 만들 수 있습니다.
DateTime
의 확장 메서드로 수행되지만 작업을 수행하는 한 줄의 코드를 잡아서 아무데나 넣을 수 있습니다. 여기에는 완전성을 위해 DateTime.Now
를 전달하는 Extension 메서드의 또 다른 오버로드가 있습니다.
Community Wiki
나는 이것을 사용한다:
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; } }
Community Wiki
이것은 이 질문에 "더 자세한 정보"를 제공합니다. 아마도 이것이 당신이 찾고있는 것입니다
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);
Community Wiki
생년월일이 주어진 사람의 나이를 계산하기 위해 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; } };
Community Wiki
여기에 또 다른 답변이 있습니다.
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년이 되는 날의 수입니다.
그것이 작동하는 이유에 대한 설명( 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 and -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 and -30 <= Dn-Db <= -1
정수 나누기로 다시
(31*(Mn - Mb) + (Dn - Db)) / 372 = -1
c)
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
d)
Mn=Mb
이고Dn>Db
이면31*(Mn - Mb) = 0 and 1 <= Dn-Db <= 3
0입니다.정수 나누기로 다시
(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
Community Wiki
나는 이 작업에 시간을 할애했고 누군가의 나이를 년, 월, 일 단위로 계산하기 위해 이것을 생각해 냈습니다. 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++; } }
Community Wiki
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); }
도움이 되기를 바랍니다.
Community Wiki
내가 찾은 가장 간단한 방법은 이것이다. 미국 및 서유럽 로케일에 대해 올바르게 작동합니다. 다른 로케일, 특히 중국과 같은 곳에서는 말할 수 없습니다. 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 ; }
나는 이것에 대한 답변을 살펴보고 있었고 아무도 윤일 출생의 규제/법적 의미를 언급하지 않았다는 것을 알아차렸습니다. 예를 들어 Wikipedia에 따르면 다양한 관할 구역에서 2월 29일에 태어난 경우 윤년이 아닌 생일은 다음과 같이 다양합니다.
- 영국과 홍콩: 올해의 서수이므로 다음 날인 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; }
이 코드는 다음을 가정합니다.
- 나이에 대한 서양식(유럽식) 계산,
- 월말에 단일 윤일을 삽입하는 그레고리력과 같은 달력입니다.
Community Wiki
간단하게(그리고 아마도 어리석게:).
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.");
Community Wiki
이것은 직접적인 대답이 아니라 준과학적 관점에서 당면한 문제에 대한 철학적 추론에 가깝습니다.
나는 그 질문이 연령을 측정하는 단위나 문화를 지정하지 않는다고 주장하고, 대부분의 답변은 정수 연간 표현을 가정하는 것으로 보입니다. 시간에 대한 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--;
금융에서는 주어진 기간 동안 대략 년 수인 Day Count Fraction 이라고 하는 것을 계산할 때 유사한 문제가 있습니다. 그리고 나이 문제는 실제로 시간 측정 문제입니다.
실제/실제(모든 날짜를 "정확하게" 계산) 규칙의 예:
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;
나는 지금까지의 일생 동안의 지구-태양-주기의 대략적인 근사치보다 몇 초 단위의 상대주의적 시대가 더 유용해지기 전에 우리가 얼마나 오래 가야 하는지 궁금합니다. 자신의 움직임을 나타내는 함수가 유효합니다 :)
Community Wiki
TimeSpan diff = DateTime.Now - birthdayDateTime; string age = String.Format("{0:%y} years, {0:%M} months, {0:%d}, days old", diff);
정확히 얼마나 반환되기를 원하는지 잘 모르겠습니다. 그래서 그냥 읽을 수 있는 문자열을 만들었습니다.
Community Wiki
여기에 해결책이 있습니다.
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);
Community Wiki
이것은 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; }
Community Wiki
나이를 계산하는 맞춤형 방법과 도움이 될 경우를 대비하여 보너스 확인 메시지가 있습니다.
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 값을 전달합니다(서버가 미국 로케일로 설정된 경우 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
원하는 방식으로 메시지 형식을 지정할 수 있음을 기억하십시오.
Community Wiki
이 솔루션은 어떻습니까?
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"; ; }
Community Wiki
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; }
Community Wiki
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
Community Wiki
다음 접근 방식(.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
Community Wiki
이 고전적인 질문은 Noda Time 솔루션의 가치가 있습니다.
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);
다음 개선 사항에 관심이 있을 수도 있습니다.
SystemClock.Instance
를 사용하는 대신IClock
시계를 전달하면 테스트 가능성이 향상됩니다.대상 시간대가 변경될 수 있으므로
DateTimeZone
매개변수도 필요합니다.
이 주제에 대한 내 블로그 게시물: 생일 및 기타 기념일 처리도 참조하십시오.
Community Wiki
나는 사람의 정확한 연도 계산을 위해 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; }
Community Wiki
Mark Soen의 답변을 약간 변경했습니다. 표현식을 좀 더 쉽게 구문 분석할 수 있도록 세 번째 줄을 다시 작성했습니다.
public int AgeInYears(DateTime bday) { DateTime now = DateTime.Today; int age = now.Year - bday.Year; if (bday.AddYears(age) > now) age--; return age; }
또한 명확성을 위해 함수로 만들었습니다.
Community Wiki
출처 : http:www.stackoverflow.com/questions/9/how-do-i-calculate-someones-age-based-on-a-datetime-type-birthday
'etc. > StackOverFlow' 카테고리의 다른 글
C++에서 Python보다 stdin에서 줄을 읽는 것이 훨씬 느린 이유는 무엇입니까? (0) | 2021.12.20 |
---|---|
JavaScript를 사용하여 드롭다운 목록에서 선택한 값 가져오기 (0) | 2021.12.20 |
C#의 enum에서 int 값 가져오기 (0) | 2021.12.20 |
목록에서 항목을 무작위로 선택하려면 어떻게 합니까? (0) | 2021.12.20 |
PostgreSQL: PostgreSQL에서 테이블 표시 (0) | 2021.12.20 |