주어진 '생일' 을 나타내는 DateTime person& # 39 년 만에 자신의 나이 계산하십시오 어떻게 해야 합니까?
오버클로킹된 이해하기 쉽고 단순한 솔루션.
// 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' 와 subtract 이 생년월일 현재 날짜로부터 드롭합니다 you& # 39 마지막 4 자리, ve got the age:)
내가 모르는, C #, # 39 don& 사용할 수 있지만 이 모든 언어에서 I believe.
20080814 - 19800703 = 280111
드롭합니다 28 '=' 마지막 4 자리.
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;
}
내가 어떻게 알 수 있습니다 잘못된 솔루션이므로 don& # 39, t 수락됨. C # 은 올바른 스니핏 쓴 마이클 아직 발효 안한 포도즙
다음은 테스트 스니핏:
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;
}
난 지금까지 모든 해답을 제공하는 것 같지는 않다 don& # 39, 문화를 기간보다오래된 계산하는 것이다. 봐, 예를 들어, 동아시아의 나이 계산법 과 그 웨스트라며?
실제 모든 오토메이티드 로컬라이제이션을 포함할 수 있다. 전략 패턴을 아마도 예제에서와 위해 있는 것이다.
이를 위해 오토메이티드 적용하십시오 아다이어스 때문에 단순 '' 이것이 유일한 방법은 아래와 같이 넷윈을 추가 년 29일 2월) 의 정확한 결과는 28일 2월 leap 년 입수합니다 일반적인 년이다.
생일 1일 3월 는 일부 느끼는 것은 없으며, 어떤 공식적인 규칙을 disk_b_s10database 레이프링스 괜찼습니다 .net 이 기능을 지원하지만 일부 공통적인 논리를 이유를 설명할 수 있어야 합니다 ~) 는 지난 2월 75% 의 또 다른 자신의 생일 월입니다.
또한 그 시대 '를 빌려주는 방법을 추가되도록 확장명으로 DateTime'. 이 시대 가장 간단한 가능한 방법을 통해 얻을 수 있습니다.
int , 기간보다오래된 = 비르다테트라제 ()
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;
}
}
이제 실행하십시오 테스트:
5 280 {{{000}}}
이 중요한 날짜 비유하사.
출력:
{
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
}
등을 위한 최신 28-02-2012:
{
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
}
나 아닌 다른 함수에 의해 웹에서 볼 수 있지만, 정제된 좀.
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;
}
단 2 맺을 것을 내 마음. 국가의 그레고리력 사용하지 않는 사람은 어때? 서버별 不仅需要思想和文化的变革 다테타임지노프 있는 것 같아. 나는 밀어버릴꺼에요 0 대한 지식을 실제로 작업 아시아어 일정 및 모르겠다고 협업공간이 쉽게 변환할지 날짜 간의 일정, 그러나 만일에 대비하는거야 you& 이야기는 혹시 # 39, re 중국 보세요들 증가한 4660 :-)
2 주 문제를 해결하려면 다음과 같습니다.
1. - 년, 월, 일, 정확한 기간보다오래된 계산하십시오 상술합니다.
2. 일반적으로 사람들이 관심 없는 경우가 있다고 계산하십시오 기간보다오래된 - 그들은, 그저 자신의 생일 때 주의해 몇살요 정확히 현재 올해.
Solution for 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
Solution for 2 is the one 에서 세 나라로 인식되고 있는 것이 아니라 전체 그리 정확히까지 디터밍 정확히까지 사람들에 의해. 또한 이 때, 사람들은 대개 자신의 나이 계산하십시오 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.
하나만 더 참고. 꼭 이래야겠어요 만들기 위해 한 경우, universal 사용, 두 번째 사용 편의성을 정적임 과부하된 방법 2:
public static int GetAge(DateTime bithDay, DateTime today)
{
//chosen solution method body
}
public static int GetAge(DateTime birthDay)
{
return GetAge(birthDay, DateTime.Now);
}
이것은 우리가 사용하는 목마르겠구나 버전 # 39 의 작동하잖아 및 it& 상당히 단순해졌습니다. # 39 it& Jeff& # 39 의 동일한 개념을 활용하고 있지만, s, s 때문에 좀 더 명확하게 구분하는 아웃해야 it& 생쥐라. # 39 하나를 빼서 도왔으매 it& # 39 에 대해 좀 더 쉽게 이해할 수 있다.
public static int GetAge(this DateTime dateOfBirth, DateTime dateAsAt)
{
return dateAsAt.Year - dateOfBirth.Year - (dateOfBirth.DayOfYear < dateAsAt.DayOfYear ? 0 : 1);
}
삼항 연산자를 수 있도록 더 그렇게 생각한다면, 심지어 확장하십시오 그러한 종류의 것은 아직 알 수 없다.
분명히 이 완료되어도 확장명으로 방법 '에' DateTime, 그러나 분명하게 하는 것이 한 줄 수 있는 일은 않는 코드 잡기 어디든요. 여기서는 '다른 방법' 에 전달되는 확장 서피스의 오버로드할 다테타임지노프, 그냥 완전성을 위해.
내가 이:
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;
}
}
이렇게 하면 더 detail" "; 이 질문에. 어쩌면 이게 you& # 39 찾고 있을 정도다.
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 의 사용자 정의 함수 someone& 계산하십시오 주어졌을 때, # 39 생일. 쿼리하지 일부로 필요할 때 유용합니다.
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;
}
이 광범위하게 유닛 테스트. 조금 여바바 않니다 magic" ";). 372 년) 은 수 있는 경우 매달 31 일 일 수 있을 것이다.
관계자의 설명을 왜 작동하잖아 (해제했다 여기에서) 는:
>. # 39 의 세트 'Yn = 다테타임.노자이어 let&, Yb = 생일. 미니아폴리스 = 다테타임자놉스먼트, Mb = 올해 생일. 달, Dn = 다테타임자놉스데이, 데이터베이스 (db) = 생일. Day '
>. '나이 = Yn - Yb + (31* (미니아폴리스 - Mb) + (Dn - Db)) / 372'
>. 우리가 원하는 것은 우리가 알고 있는 경우 ',' '' yn yb 인컨텍스트 시기는 이미 도달했음 yn yb 1 있지 않으면.
>. a) ',' Mb 'Mn< 경우 우리는 341 <; = - = - = 30, 31 살 < 31* (미니아폴리스 mb)' = 30 < dn 데이터베이스 (db) <.
>. '371 < = 31* (미니아폴리스 - mb) + (dn - db) = - 1' <.
>. 와 정수 분할
>. ' (31* (미니아폴리스 - Mb) + (Dn - Db)) / 372 = - 1'
>. b) = ',', 'Mb' 와 'Dn< 미니아폴리스 경우 우리는 31* Db (미니아폴리스 - Mb) = 0 = - = - 1', 그리고 30 < dn 데이터베이스 (db) <.
>. 정수 분할, 다시 함께
>. ' (31* (미니아폴리스 - Mb) + (Dn - Db)) / 372 = - 1'
>. c) 의 경우, 우리는 '31', 'Mn> <;; = = = 31* (미니아폴리스 mb) 와 - 30 < < 341 dn 데이터베이스 (db)' = 30 <.
>. '1 < = 31* (미니아폴리스 - Mb) + (Dn - Db) = 371' <.
>. 와 정수 분할
>. ' (31* (미니아폴리스 - Mb) + (Dn - Db)) / 372 = 0'
>. d) ',' 우리는 ',' 와 '= Mb 미니아폴리스 경우 Db Dn> 31* (미니아폴리스 - Mb) = = 3 = 0, 0 과 1 < dn 데이터베이스 (db) <.'
>. 정수 분할, 다시 함께
>. ' (31* (미니아폴리스 - Mb) + (Dn - Db)) / 372 = 0'
>. e) ',' Mb '와' = '미니아폴리스 경우 우리는 31* Dn = Db (미니아폴리스 - Mb) + dn 데이터베이스 (db) = 0'
>. 때문에 ' (31* (미니아폴리스 - Mb) + (Dn - Db)) / 372 = 0'
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 년 이상 고려해보십시오 누구이뇨 사람들이 더 필요할까요? 중국인의 문화, 설명하기에 작은 babies& # 39. 나이가 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);
}
가장 간단한 방법은 I& # 39, ve ever 늑대굴에서 로만스였나. 미국, 서유럽 제대로 작동하잖아 로켈을. # 39, t, 특히 중국 등 다른 로켈을 can& 할 수 있다. 이어 추가 비교, 많아야 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 ;
}
내가 답을 찾을 수 있다는 사실을 알고 이 대한 법적 규제 / 미치는 영향 및 아니예 카으바를 참조입니다 leap day 출생. 예를 들어, [호스트당 위키백과] [1], 29일 2월 ~) 는 다양한 재판 관할권에서는 you& # 39 의 경우, re, re you& 윤년이 아닌 # 39 년 생일 다릅니다.
그리고 곧 이 문제에 대한 미국의 silent. 법령, as I 말할 수 있는 공통 것가운데 it up, 법과 규정을 셨으며 정의하십시오 얼마나 다양한 규제 때문이다.
이를 위해 개선한:
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;
}
이 코드는 간주하고 있다는 점에 유의해야 합니다.