Kaip apskaičiuoti asmens amžių C #?

Atsižvelgiant į asmens gimimo datą, kaip aš galiu apskaičiuoti jų amžių metais?

1743 m
01 авг. nustatė Jeff Atwood 01 rugpjūtis 2008-08-01 02:40 '08 at 2:40 am 2008-08-01 02:40
@ 64 atsakymai
  • 1
  • 2
  • 3

Lengvai suprantamas ir paprastas sprendimas.

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

Tačiau tai rodo, kad ieškote vakarietiškos amžiaus idėjos ir nenaudojate Rytų Azijos skaičiavimų .

1759 m
04 авг. atsakymas, kurį pateikė Mike Polen 04 rug. 2008-08-04 19:50 '08 at 7:50 pm 2008-08-04 19:50

Tai yra keistas būdas tai padaryti, bet jei formatuosite datą iki yyyymmdd ir atimsite gimimo datą nuo dabartinės datos, palikite paskutinius 4 skaitmenis, kurie turi amžių :)

Nežinau C #, bet manau, kad tai veiks bet kuria kalba.

 20080814 - 19800703 = 280111 

Ištrinkite paskutinius 4 skaitmenis = 28 .

border=0

C # kodas:

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

Arba, alternatyviai, be tipo konvertavimo pratęsimo metodo forma. Patvirtinimo klaida:

 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; } 
909
15 авг. atsakymą pateikė ScArcher2 15 rug . 2008-08-15 06:47 '08 6:47 am 2008-08-15 06:47

Nežinau, kaip padaryti neteisingą sprendimą. Teisingą C # ištrauką parašė Michael Stam

Čia yra bandymo fragmentas:

 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 

Čia jūs turite metodus:

 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; } 
349
20 окт. atsakymas pateikiamas RMA 20 okt. 2009-10-20 18:07 '09, 06:07 PM 2009-10-20 18:07

Nemanau, kad nė vienas iš atsakymų teiktų kultūrą, kuri skaičiuoja amžių skirtingai. Žr., Pavyzdžiui, Rytų Azijos amžiaus vertinimą, palyginti su Vakarų.

Bet koks realus atsakymas turi apimti lokalizavimą. Šiame pavyzdyje tikėtina, kad strategijos modelis bus tvarkingas.

116
17 авг. James A. Rosen atsakymas rugpjūčio 17 d 2008-08-17 20:14 '08 at 8:14 pm 2008-08-17 20:14

Paprastas atsakymas į tai yra „ AddYears naudojimas, kaip parodyta žemiau, nes tai yra vienintelis gimtoji metodas, leidžiantis pridėti metų metus iki vasario 29 d. Ir gauti teisingus rezultatus vasario 28 d.

Kai kurie žmonės mano, kad kovo 1 d. Yra šuolių gimtadienis, tačiau nei .Net, nei oficialioji taisyklė tai nepatvirtina, o bendra logika nepaaiškina, kodėl kai kurie, kurie gimė vasarį, turėtų turėti 75% savo gimtadienių kitą mėnesį .

Be to, amžiaus metodas gali būti pridėtas kaip „ DateTime pratęsimas. Dėl to jūs galite gauti amžių lengviausiu būdu:

  • Sąrašo elementas

vidutinis amžius = gimimo data.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; } } 

Dabar paleiskite šį testą:

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

Kritinės datos pavyzdys:

Gimimo data: 2000-02-29 Vėlyvoji data: 2011-02-28 Amžius: 11

Išvada:

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

Ir vėliau - 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 } 
100
20 февр. atsakymas pateikiamas camelCasus 20 vas. 2011-02-20 02:56 '11 at 2:56 2011-02-20 02:56

Mano pasiūlymas

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

Atrodo, kad metai keičiasi į teisingą datą. (Aš išbandžiau dėmę iki 107)

77
03 окт. James Curran atsakymas 03 d 2008-10-03 23:19 '08 at 11:19 pm 2008-10-03 23:19

Kita funkcija, o ne man, bet internete, šiek tiek paaiškinta:

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

Tik du dalykai, kurie ateina mano nuomone: ką apie žmones iš šalių, kurios nenaudoja grigališkojo kalendoriaus? DateTime.Now serverio kultūra, manau. Turiu absoliučiai 0 žinių apie faktinį darbą su Azijos kalendoriais, ir nežinau, ar yra paprastas būdas konvertuoti datas tarp kalendorių, bet tik tuo atveju, jei norite sužinoti apie šiuos kinų vaikinus nuo 4660 metų: -)

65
02 авг. Michael Stum atsakymas rugpjūčio 02 d 2008-08-02 00:46 '08, 12:46 am. 2008-08-02 00:46

Aš vėlu partijai, bet čia yra viena eilutė:

 int age = new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year-1; 
44
18 мая '09 в 15:36 2009-05-18 15:36 atsakymą pateikė „ SillyMonkey “ gegužės 18 d. 15 val. 15:36 2009-05-18 15:36

2 Pagrindinės problemos, kurias reikia išspręsti:

1. Apskaičiuokite tikslų amžių - metais, mėnesiais, dienomis ir tt

2. Apskaičiuoti Paprastai suvokiamas amžius - žmonės paprastai nerūpi, kiek jie yra, jie rūpinasi, kai jų gimtadienis yra einamaisiais metais.


1 sprendimas yra akivaizdus:

 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 sprendimas yra toks, kuris nėra toks tikslus, nustatant bendrą amžių, bet žmogus suvokia, kad jis yra tikslus. Žmonės taip pat paprastai jį naudoja, kai apskaičiuoja savo amžių „rankiniu būdu“:

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

  • Tai mano pageidaujamas sprendimas.
  • Mes negalime naudoti „DateTime.DayOfYear“ arba „TimeSpans“, nes jie keičia dienų skaičių šuolių metais.
  • Aš įterpiau kelias eilutes, kad jas būtų galima perskaityti.

Dar viena pastaba ... jam būtų sukurtos 2 statinės perkrovos metodai, vienas universaliam naudojimui, antrasis - paprastam naudojimui:

 public static int GetAge(DateTime bithDay, DateTime today) { //chosen solution method body } public static int GetAge(DateTime birthDay) { return GetAge(birthDay, DateTime.Now); } 
44
11 апр. Atsakymą pateikė Thetam, balandžio 11 d. 2011-04-11 17:47 '11, 17:47, 2011-04-11 17:47

Prieš daugelį metų, kad galėčiau pateikti savo amžiaus skaičiuoklę savo svetainėje, parašiau funkciją, pagal kurią apskaičiuojamas pasidalijimo amžius. Tai greitas šios funkcijos prievadas C # (nuo PHP versijos ). Bijau, kad negalėjau patikrinti C # versijos, bet tikiuosi, kad vis tiek patiks!

(Žinoma, tai yra šiek tiek nepatogu, kai naudotojo profiliai rodomi „Stack Overflow“, tačiau galbūt skaitytojai naudos tam tikrą naudojimą: -))

 double AgeDiff(DateTime date1, DateTime date2) { double years = date2.Year - date1.Year;  double fraction = 365 + (DateTime.IsLeapYear(date2.Year)  date2.DayOfYear >= 59  (date1.DayOfYear < 59 || date1.DayOfYear > date2.DayOfYear) ? 1 : 0);  if (DateTime.IsLeapYear(date2.Year) == DateTime.IsLeapYear(date1.Year)) return years + (date2.DayOfYear - date1.DayOfYear) / fraction;  if (DateTime.IsLeapYear(date2.Year)) { return years + (date2.DayOfYear - date1.DayOfYear - (date1.DayOfYear >= 59 ? 1 : 0)) / fraction; }  if (date1.DayOfYear != 59) { return years + (date2.DayOfYear - date1.DayOfYear + (date1.DayOfYear > 59 ? 1 : 0)) / fraction; }  return years + (date2.DayOfYear - 58.5) / fraction; } 
33
01 авг. Atsakymas, kurį pateikė Chris Jester-Young 01 rugpjūtis 2008-08-01 11:57 '08 at 11:57 2008-08-01 11:57

Ši versija naudojama čia. Jis veikia, ir tai gana paprasta. Tai ta pati mintis kaip Jeffas, bet manau, kad tai šiek tiek aiškesnė, nes ji atskiria logiką nuo atimties, taigi šiek tiek lengviau suprasti.

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

Jūs galite išplėsti tretinį operatorių, kad jis būtų dar aiškesnis, jei manote, kad tai neaišku.

Akivaizdu, kad tai daroma kaip pratęsimo metodas „ DateTime , bet, žinoma, galite paimti vieną eilutę, kuri atlieka darbą ir įdeda ją bet kur. Čia mes turime dar vieną išplėtimo metodą, kuris eina per DateTime.Now , tik dėl išsamumo.

33
06 авг. David Wengier atsakymas rugpjūčio 6 d 2008-08-06 13:23 '08 13:23 pm 2008-08-06 13:23

Naudoju tai:

 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; } } 
30
17 февр. Atsakymą pateikė Elmeras vasario 17 d. 2010-02-17 16:32 '10, 16:32, 2010-02-17 16:32

Geriausias būdas žinau dėl šuolių metų ir visko:

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

Tikiuosi, kad tai padės.

28
01 авг. Nick Berardi atsakymas 01 rug. 2008-08-01 15:07 '08, 15:07 2008-08-01 15:07

Tai suteikia „daugiau informacijos“ šiam klausimui. Galbūt tai yra tai, ko ieškote.

 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); 
27
20 сент. Jacqueline Loriault atsakymas rugsėjo 20 d 2013-09-20 22:13 '13, 13:13 PM 2013-09-20 22:13

Sukūriau pasirinktinę SQL serverio funkciją, kad būtų galima apskaičiuoti asmens amžių, atsižvelgiant į jų gimimo datą. Tai naudinga, kai jums reikia kaip užklausos dalis:

 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; } }; 
23
23 авг. atsakymą pateikė vartotojo2601 23 rug . 2008-08-23 16:58 '08 at 4:58 pm 2008-08-23 16:58

Aš praleidau tam tikrą laiką dirbdamas su juo ir atėjau su juo apskaičiuoti kasmet, mėnesius ir dienas. Bandžiau išbandyti šią problemą vasario 29 d. Ir šuolių metais, ir atrodo, kad jis veikia, būsiu dėkingas už bet kokią atsiliepimą:

 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++; } } 
22
18 мая '09 в 14:24 2009-05-18 14:24 Atsakymą pateikė Jonas gegužės 18 d., 09:24, 2009-05-18 14:24

Čia yra kitas atsakymas:

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

Jis buvo kruopščiai išbandytas ant įrenginio. Tai atrodo šiek tiek „stebuklinga“. 372 yra dienų skaičius per metus, jei kiekvienas mėnuo turėtų 31 dieną.

Paaiškinimas, kodėl jis veikia ( pašalintas iš čia ):

Leiskite nustatyti 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

Mes žinome, kad mums reikia arba Yn-Yb jei data jau pasiekta, Yn-Yb-1 jei ne Yn-Yb-1 .

a) Jei Mn<Mb , turime -341 <= 31*(Mn-Mb) <= -31 and -30 <= Dn-Db <= 30

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

Su visais padaliniais

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

b) Jei Mn=Mb ir Dn<Db , tada 31*(Mn - Mb) = 0 and -30 <= Dn-Db <= -1

Dar kartą susiskaldžius

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

c) Jei Mn>Mb , mes turime 31 <= 31*(Mn-Mb) <= 341 and -30 <= Dn-Db <= 30

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

Su visais padaliniais

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

d) Jei Mn=Mb ir Dn>Db , tada 31*(Mn - Mb) = 0 and 1 <= Dn-Db <= 3 0

Dar kartą susiskaldžius

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

e) Jei Mn=Mb ir Dn=Db , tada 31*(Mn - Mb) + Dn-Db = 0

ir todėl (31*(Mn - Mb) + (Dn - Db))/372 = 0

18
22 апр. Atsakymą pateikė Matthew Watson balandžio 22 d 2013-04-22 11:19 '13, 11:19, 2013-04-22 11:19
 TimeSpan diff = DateTime.Now - birthdayDateTime; string age = String.Format("{0:%y} years, {0:%M} months, {0:%d}, days old", diff); 

Aš nesu įsitikinęs, kaip tiksliai norite, kad jis sugrįžtų į jus, todėl ką tik padariau skaitomą eilutę.

17
19 сент. Dakotah Hicock atsakymas, pateiktas rugsėjo 19 d. 2013-09-19 18:18 '13, 18:18, 2013-09-19 18:18

Ar turėtume laikyti mažiau nei 1 metų amžiaus žmones? kaip kinų kultūra, mes apibūdiname mažų vaikų amžių kaip 2 mėnesius arba 4 savaites.

Žemiau yra mano įgyvendinimas, tai nėra taip paprasta, kaip įsivaizdavau, ypač sprendžiant datą, pvz., 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"; } } 

Šis įgyvendinimas praėjo žemiau bandymų atvejų.

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

Tikiuosi, kad tai bus naudinga.

17
30 нояб. Atsakymas suteikiamas rockXrock 30 nov. 2012-11-30 15:13 '12 15:13 2012-11-30 15:13

Laikykite jį paprastą (ir galbūt kvailą :)).

 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."); 
17
18 авг. Freddy atsakymas, pateiktas rugpjūčio 18 d 2010-08-18 17:29 '10, 17:29, 2010-08-18 17:29

Paprasčiausias būdas, kurį aš kada nors rasiu. Jis veikia tinkamai JAV ir Vakarų Europos vietose. Negali kalbėti kitose vietose, ypač tokiose vietose kaip Kinija. 4 papildomi lyginami ne daugiau kaip po pradinio amžiaus skaičiavimo

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

Ieškojau atsakymų į šį klausimą ir pastebėjau, kad niekas nenurodė, kokių teisinių ir teisinių pasekmių kyla dėl peršokimo dienos. Pavyzdžiui, jei Vikipedijoje gimėte vasario 29 d. Skirtingose ​​jurisdikcijose, turite kitą gimimo metus:

  • Jungtinėje Karalystėje ir Honkonge: tai yra eilinė metų diena, todėl kitą dieną, kovo 1 d., Yra gimtadienis.
  • Naujojoje Zelandijoje: tai yra ankstesnė diena, vasario 28 d. Vairuotojų licencijavimo, o kovo 1 d. - kitiems tikslams.
  • Taivanas: tai vasario 28 d.

Ir, kiek aš galiu pasakyti, JAV šiose nuostatose nekalbama apie įstatymus, paliekant jį bendram įstatymui ir kaip įvairios reguliavimo institucijos nustato savo taisykles.

Šiuo tikslu:

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

Pažymėtina, kad šis kodas yra:

  • Vakarų (Europos) amžiaus ir amžiaus rodiklis
  • Kalendorius, kaip ir Grigaliaus kalendorius, kuris mėnesio pabaigoje įterpia vieną laiko dieną.
16
06 окт. Nicholas Carey atsakymas spalio 6 d 2010-10-06 04:49 '10, 4:49, 2010-10-06 04:49

Čia yra sprendimas.

 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); 
15
18 июня '09 в 13:35 2009-06-18 13:35 atsakymą pateikė Rajeshwaran SP birželio 18 d., 09 val. 13:35 2009-06-18 13:35

Tai yra vienas iš tiksliausių atsakymų, galinčių nuspręsti dėl vasario 29 d. Gimtadienio, palyginti su bet kuriais vasario 28 d.

 public int GetAge(DateTime birthDate) { int age = DateTime.Now.Year - birthDate.Year; if (birthDate.DayOfYear > DateTime.Now.DayOfYear) age--; return age; } 
15
23 окт. atsakymą mjb pateikė spalio 23 d 2014-10-23 16:18 '14 at 16:18 2014-10-23 16:18

Tai nėra tiesioginis atsakymas, o filosofinis argumentas apie nagrinėjamą problemą iš kvazimokslinio požiūrio.

Sakyčiau, kad šis klausimas nenurodo vieneto ar kultūros, kurioje galima matuoti amžių, dauguma atsakymų, atrodo, sutinka su metiniu skaičiumi. second laiko SI vienetas, ergo turėtų būti teisingas bendras atsakymas (žinoma, darant prielaidą normalizuotą „ DateTime ir neatsižvelgiant į reliatyvistinį poveikį):

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

Krikščioniškame amžiaus skaičiavimo metode:

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

Finansuojant panašią problemą, apskaičiuojant tai, kas dažnai vadinama „Dienų skaičiumi dienomis“, yra maždaug kelerių metų per tam tikrą laikotarpį. Ir amžiaus problema yra laiko matavimo problema.

Faktinio (faktinio) pavyzdys (skaičiuojant visas „teisingas“ dienas):

 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;