주어진 DateTime
표현하는 사람의 생일, 어떻게 몇 년 동안 자신의 나이를 계산합니까?
주어진 DateTime
표현하는 사람의 생일, 어떻게 몇 년 동안 자신의 나이를 계산합니까?
답변:
이해하기 쉽고 간단한 솔루션.
// 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.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;
}
20180101 - 20171231 = 8870
. 마지막 4 자리 숫자를 삭제하면 0
연령대에 대한 정보가 있습니다. 어떻게 얻었 1
습니까?
다음은 테스트 스 니펫입니다.
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 일이 도약의 생일이라고 생각하지만 .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();
}
}
중요한 날짜 예는 다음과 같습니다.
생년월일 : 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
}
date.Age(other)
?
나의 제안
int age = (int) ((DateTime.Now - bday).TotalDays/365.242199);
그것은 올바른 날짜에 연도가 바뀌는 것 같습니다. (107 세까지 검사를 받았습니다.)
days in a year = 365.242199
나에 의한 것이 아니라 웹에서 발견 된 또 다른 기능은 조금 수정했습니다.
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 년의 중국인에 대해 궁금해하는 경우를 대비하여 :-)
해결해야 할 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에 대한 참고 사항 ::
한 가지 더 참고하십시오 ... 나는 그것을 위해 두 가지 정적 오버로드 된 메소드를 만들 것입니다. 하나는 보편적 인 사용법을위한 것이고 다른 하나는 사용법 친화적 인 것입니다.
public static int GetAge(DateTime bithDay, DateTime today)
{
//chosen solution method body
}
public static int GetAge(DateTime birthDay)
{
return GetAge(birthDay, DateTime.Now);
}
하나의 라이너가 있습니다.
int age = new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year-1;
이것은 우리가 여기서 사용하는 버전입니다. 작동하며 상당히 간단합니다. 그것은 Jeff와 같은 아이디어이지만 그것을 빼기위한 논리를 분리하기 때문에 조금 더 명확하다고 생각하므로 이해하기가 더 쉽습니다.
public static int GetAge(this DateTime dateOfBirth, DateTime dateAsAt)
{
return dateAsAt.Year - dateOfBirth.Year - (dateOfBirth.DayOfYear < dateAsAt.DayOfYear ? 0 : 1);
}
종류가 불분명하다고 생각되면 삼항 연산자를 확장하여 더 명확하게 만들 수 있습니다.
분명히 이것은에 대한 확장 방법으로 수행 DateTime
되지만 분명히 작업을 수행 하는 한 줄의 코드를 잡고 어디에서나 넣을 수 있습니다. 여기 DateTime.Now
에 완전성을 위해 전달되는 Extension 메서드의 또 다른 과부하가 있습니다 .
윤년과 모든 것 때문에 내가 아는 가장 좋은 방법은 다음과 같습니다.
DateTime birthDate = new DateTime(2000,3,1);
int age = (int)Math.Floor((DateTime.Now - birthDate).TotalDays / 365.25D);
나는 이것을 사용한다 :
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;
}
}
이것은이 질문에 "더 자세한 내용"을 제공합니다. 아마 이것이 당신이 찾고있는 것입니다.
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);
생년월일을 기준으로 누군가의 나이를 계산하기 위해 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;
}
};
여기 또 다른 대답이 있습니다.
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
있습니다.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
나는이 일을하는 데 시간을 보냈고 몇 년, 몇 달, 며칠 동안 누군가의 나이를 계산하기 위해이를 생각해 냈습니다. 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);
}
도움이 되길 바랍니다.
간단하게 (그리고 어리석은 것을 유지하십시오).
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.");
내가 찾은 가장 간단한 방법은 이것입니다. 미국 및 서유럽 로케일에 올바르게 작동합니다. 다른 지역, 특히 중국과 같은 장소에서는 말할 수 없습니다. 초기 연령 계산 후 최대 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 일에 다양한 관할 구역에서 태어난 경우 윤년이 아닌 생일은 다음과 같습니다.
그리고 제가 알 수있는 한, 미국에서는 법령이이 문제에 대해 침묵하고 있으며,이를 일반적인 법과 다양한 규제 기관이 규정에 따라 정의하는 방식에 맡기고 있습니다.
이를 위해 개선 사항 :
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;
}
이 코드는 다음을 가정합니다.
TimeSpan diff = DateTime.Now - birthdayDateTime;
string age = String.Format("{0:%y} years, {0:%M} months, {0:%d}, days old", diff);
정확히 어떻게 당신에게 당신을 돌려 줄지 잘 모르겠으므로 읽을 수있는 문자열을 만들었습니다.
이것은 직접적인 해답이 아니라 준 과학적인 관점에서 문제에 대한 철학적 추론에 가깝습니다.
나는 그 질문이 연령을 측정 할 단위 나 문화를 명시하지 않는다고 주장 할 것이다. 대부분의 대답은 정수로 표현되는 것으로 보인다. 시간에 대한 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;
나는 지금까지의 일생 동안 지구 주위의 태양주기의 대략적인 근사치보다 상대 론적 나이가 몇 초 안에 가야 얼마나 오래 걸리는지 궁금합니다. 자체적으로 유효한 모션을 나타내는 함수 :)
해결책은 다음과 같습니다.
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;
}
다음 접근 방식 은 .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
이 고전적인 질문은 노다 시간이 필요합니다 솔루션이 필요합니다.
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
매개 변수도 필요합니다.
이 주제에 대한 내 블로그 게시물을 참조하십시오. 생일 처리 및 기타 기념일
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;
}
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;
}
또한 명확성을 위해 함수로 만들었습니다.