¿Cómo calculo la edad de alguien en función de un cumpleaños tipo DateTime? -- # campo con .net campo con datetime camp Relacionados El problema

How do I calculate someone's age based on a DateTime type birthday?


1955
vote

problema

Español

Dado un Form5 que representa el cumpleaños de una persona, ¿cómo calculo su edad en años?

Original en ingles

Given a DateTime representing a person's birthday, how do I calculate their age in years?

</div
        
         
         

Lista de respuestas

2207
 
vote
vote
La mejor respuesta
 

una solución fácil de entender y simple.

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

Sin embargo, esto supone que está buscando la Idea de la Edad de y no usar Talloning East Asian .

 

An easy to understand and simple solution.

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

However, this assumes you are looking for the western idea of the age and not using East Asian reckoning.

</div
 
 
       
       
1039
 
vote

Esta es una forma extraña de hacerlo, pero si formatea la fecha a yyyymmdd y resta la fecha de nacimiento desde la fecha actual, coloque los últimos 4 dígitos que tiene la edad: )

No sé C #, pero creo que esto funcionará en cualquier idioma.

  em0  

Drop los últimos 4 dígitos = em1111 .

c # Código:

  em2  

o alternativamente sin toda la conversión de tipo en forma de un método de extensión. Comprobación de errores omitidos:

  em3  
 

This is a strange way to do it, but if you format the date to yyyymmdd and subtract the date of birth from the current date then drop the last 4 digits you've got the age :)

I don't know C#, but I believe this will work in any language.

20080814 - 19800703 = 280111  

Drop the last 4 digits = 28.

C# Code:

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

Or alternatively without all the type conversion in the form of an extension method. Error checking omitted:

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; } 
</div
 
 
         
         
396
 
vote

Aquí hay un fragmento de prueba:

  em4  

Aquí tienes los métodos:

  em5  
 

Here is a test snippet:

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 

Here you have the methods:

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; } 
</div
 
 
         
         
116
 
vote

La respuesta simple a esto es aplicar em6 como se muestra a continuación porque este es el único método nativo para agregar años al 29 de febrero de los años de salto y obtener el resultado correcto del 28 de Febrero por años comunes.

Algunos sienten que el 1 de marzo es el cumpleaños de los soplantes, pero ni .Net ni ninguna regla oficial apoya esto, ni la lógica común explica por qué algunos nacidos en febrero deberían tener el 75% de sus cumpleaños en otro mes.

Además, un método de edad se presta para agregarse como una extensión a em7 . Por esto, puede obtener la edad de la manera más sencilla posible:

  1. artículo de lista

int maye = nataldate.age ();

  em8  

ahora, ejecute esta prueba:

  em9  

El ejemplo de la fecha crítica es esta:

Fecha de nacimiento: 2000-02-29 Fecha posterior: 2011-02-28 Edad: 11

Salida:

  hasLayout0  

y para la fecha posterior 2012-02-28:

  hasLayout1  
 

The simple answer to this is to apply AddYears as shown below because this is the only native method to add years to the 29th of Feb. of leap years and obtain the correct result of the 28th of Feb. for common years.

Some feel that 1th of Mar. is the birthday of leaplings but neither .Net nor any official rule supports this, nor does common logic explain why some born in February should have 75% of their birthdays in another month.

Further, an Age method lends itself to be added as an extension to DateTime. By this you can obtain the age in the simplest possible way:

  1. List item

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

Now, run this 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();     } } 

The critical date example is this:

Birth date: 2000-02-29 Later date: 2011-02-28 Age: 11

Output:

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

And for the later date 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 } 
</div
 
 
   
   
92
 
vote

mi sugerencia

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

Eso parece tener el año cambiando en la fecha correcta. (I Spot Probado hasta los 107 años).

 

My suggestion

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

That seems to have the year changing on the right date. (I spot tested up to age 107.)

</div
 
 
         
         
80
 
vote

Otra función, no por mí, sino que se encuentra en la web y lo refinó un poco:

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

Solo dos cosas que entran en mi mente: ¿qué pasa con las personas de los países que no utilizan el calendario gregoriano? DateTime. ahora está en la cultura específica del servidor, creo. Tengo un conocimiento absolutamente cero sobre el trabajo en realidad con los calendarios asiáticos y no sé si hay una manera fácil de convertir las fechas entre los calendarios, pero en caso de que se estés preguntando acerca de los chinos del año 4660:)

 

Another function, not by me but found on the web and refined it a bit:

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

Just two things that come into my mind: What about people from countries that do not use the Gregorian calendar? DateTime.Now is in the server-specific culture I think. I have absolutely zero knowledge about actually working with Asian calendars and I do not know if there is an easy way to convert dates between calendars, but just in case you're wondering about those Chinese guys from the year 4660 :-)

</div
 
 
 
 
55
 
vote

2 Los problemas principales para resolver son:

1. Calcule la edad exacta - en años, meses, días, etc.

2. Calcule en general la edad percibida - las personas por lo general no les importa la edad que existen exactamente, simplemente se preocupan cuando es su cumpleaños en el año actual.


Solución para 1 es obvio:

  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   

La solución para 2 es la que no es tan precisa para determinar la edad total, pero se percibe como precisa por las personas. Las personas también lo usan, cuando calculan su edad "manualmente":

  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 }   

Notas a 2.:

  • Esta es mi solución preferida
  • No podemos usar DateTime.DoDoFyEar o TimesPANS, ya que cambian el número de días en los años de salto
  • He puesto hay poco más líneas para la legibilidad

Solo una nota más ... Crearía 2 métodos sobrecargados estáticos para ello, uno para uso universal, segundo para uso de uso:

  public static int GetAge(DateTime bithDay, DateTime today)  {    //chosen solution method body }  public static int GetAge(DateTime birthDay)  {    return GetAge(birthDay, DateTime.Now); }   
 

2 Main problems to solve are:

1. Calculate Exact age - in years, months, days, etc.

2. Calculate Generally perceived age - people usually do not care how old they exactly are, they just care when their birthday in the current year is.


Solution for 1 is obvious:

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 which is not so precise in determing total age, but is perceived as precise by people. People also usually use it, when they calculate their age "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 } 

Notes to 2.:

  • This is my preferred solution
  • We cannot use DateTime.DayOfYear or TimeSpans, as they shift number of days in leap years
  • I have put there little more lines for readability

Just one more note ... I would create 2 static overloaded methods for it, one for universal usage, second for usage-friendliness:

public static int GetAge(DateTime bithDay, DateTime today)  {    //chosen solution method body }  public static int GetAge(DateTime birthDay)  {    return GetAge(birthDay, DateTime.Now); } 
</div
 
 
51
 
vote

Aquí hay un soltero:

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

Here's a one-liner:

int age = new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year-1; 
</div
 
 
 
 
49
 
vote

La mejor manera que conozco debido a los años de salto y todo es:

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

The best way that I know of because of leap years and everything is:

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

Esta es la versión que usamos aquí. Funciona, y es bastante simple. Es la misma idea que la de Jeff, pero creo que es un poco más clara porque separa la lógica para restar una, por lo que es un poco más fácil de entender.

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

Podría expandir el operador ternario para que sea aún más claro, si cree que ese tipo de cosas no está claro.

Obviamente, esto se hace como un método de extensión en DateTime , pero claramente puede tomar esa línea de código que hace el trabajo y colóquelo en cualquier lugar. Aquí tenemos otra sobrecarga del método de extensión que pasa en DateTime.Now , solo para completar.

 

This is the version we use here. It works, and it's fairly simple. It's the same idea as Jeff's but I think it's a little clearer because it separates out the logic for subtracting one, so it's a little easier to understand.

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

You could expand the ternary operator to make it even clearer, if you think that sort of thing is unclear.

Obviously this is done as an extension method on DateTime, but clearly you can grab that one line of code that does the work and put it anywhere. Here we have another overload of the Extension method that passes in DateTime.Now, just for completeness.

</div
 
 
   
   
34
 
vote

Esto da "más detalles" a esta pregunta. Tal vez esto es lo que está buscando

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

This gives "more detail" to this question. Maybe this is what you're looking for

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); 
</div
 
 
         
         
34
 
vote

Yo uso esto:

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

I use this:

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;     } } 
</div
 
 
29
 
vote

He creado una función definida por el usuario de SQL Server para calcular la edad de alguien, dada su fecha de nacimiento. Esto es útil cuando lo necesita como parte de una consulta:

  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  
 

I have created a SQL Server User Defined Function to calculate someone's age, given their birthdate. This is useful when you need it as part of a query:

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;     } }; 
</div
 
 
29
 
vote

Aquí está otra respuesta:

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

Esto ha sido extensamente probado. Se ve un poco "magia". El número 372 es el número de días que habría en un año si cada mes tuviera 31 días.

La explicación de por qué funciona ( Levantado desde aquí ) es:

Configuremos 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

Sabemos que lo que necesitamos es Yn-Yb Si ya se ha alcanzado la fecha, 9988777664 si no lo ha hecho.

a) Si Mn<Mb , tenemos 9988777666

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

con división entera

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

b) Si Mn=Mb y Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day0 , tenemos Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day1111

con división entera, otra vez

Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day2

c) Si Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day3 , tenemos 99887776614

Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day5

con división entera

Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day6

d) Si Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day7 y Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day8 , tenemos Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day9 0

con división entera, otra vez

age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 3720

e) Si age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 3721 y age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 3722 , tenemos age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 3723

y por lo tanto age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 3724

 

Here's yet another answer:

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

This has been extensively unit-tested. It does look a bit "magic". The number 372 is the number of days there would be in a year if every month had 31 days.

The explanation of why it works (lifted from here) is:

Let's set 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

We know that what we need is either Yn-Yb if the date has already been reached, Yn-Yb-1 if it has not.

a) If Mn<Mb, we have -341 <= 31*(Mn-Mb) <= -31 and -30 <= Dn-Db <= 30

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

With integer division

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

b) If Mn=Mb and Dn<Db, we have 31*(Mn - Mb) = 0 and -30 <= Dn-Db <= -1

With integer division, again

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

c) If Mn>Mb, we have 31 <= 31*(Mn-Mb) <= 341 and -30 <= Dn-Db <= 30

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

With integer division

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

d) If Mn=Mb and Dn>Db, we have 31*(Mn - Mb) = 0 and 1 <= Dn-Db <= 30

With integer division, again

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

e) If Mn=Mb and Dn=Db, we have 31*(Mn - Mb) + Dn-Db = 0

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

</div
 
 
 
 
25
 
vote

He pasado un tiempo trabajando en esto y se le ocurrió esto para calcular la edad de alguien en años, meses y días. He probado contra el Problema del 29 de febrero y los años de salto y parece que funciona, apreciaría cualquier comentario:

  age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 3725  
 

I've spent some time working on this and came up with this to calculate someone's age in years, months and days. I've tested against the Feb 29th problem and leap years and it seems to work, I'd appreciate any feedback:

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++;     }  } 
</div
 
 
21
 
vote

¿Necesitamos considerar a las personas menores de 1 año? Como cultura china, describimos la edad de bebés pequeños como 2 meses o 4 semanas.

A continuación es mi implementación, no es tan simple como lo que imaginé, especialmente para lidiar con la fecha como 2/28.

  age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 3726  

Esta implementación ha pasado por debajo de los casos de prueba.

  age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 3727  

Espero que sea útil.

 

Do we need to consider people who is smaller than 1 year? as Chinese culture, we describe small babies' age as 2 months or 4 weeks.

Below is my implementation, it is not as simple as what I imagined, especially to deal with date like 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";     } } 

This implementation has passed below test cases.

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

Hope it's helpful.

</div
 
 
20
 
vote

Esta no es una respuesta directa, sino más de un razonamiento filosófico sobre el problema a la mano desde un punto de vista casi científico.

Argumentaría que la pregunta no especifica la unidad ni la cultura para medir la edad, la mayoría de las respuestas parecen asumir una representación anual de enteros. La unidad SI por tiempo es age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 3728 , ERGO La respuesta genérica correcta debe ser (por supuesto, suponiendo que sean normalizados age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 3729 y que no tenga en cuenta lo que sea para los efectos relativistas):

  Yn-Yb0  

En la forma cristiana de calcular la edad en años:

  Yn-Yb1  

En Finanzas, existe un problema similar al calcular algo a menudo denominado la fracción de conteo de día , que es aproximadamente un número de años por un período determinado. Y el problema de edad es realmente un problema de medición de tiempo.

Ejemplo para el Convenio real / real (Contar todos los días "correctamente"):

  Yn-Yb2  

Otra forma bastante común de medir el tiempo en general es por "serializando" (el tipo que nombró a esta convención de fecha debe haber sido seriamente trippin '):

  Yn-Yb3  

Me pregunto cuánto tiempo tenemos que ir antes de que una edad relativista en segundos se vuelva más útil que la aproximación aproximada de los ciclos de la tierra alrededor de la vida durante la vida hasta ahora :) o en otras palabras, cuando se debe dar un período una ubicación o una función que representa el movimiento para sí misma es válida :)

 

This is not a direct answer, but more of a philosophical reasoning about the problem at hand from a quasi-scientific point of view.

I would argue that the question does not specify the unit nor culture in which to measure age, most answers seem to assume an integer annual representation. The SI-unit for time is second, ergo the correct generic answer should be (of course assuming normalized DateTime and taking no regard whatsoever to relativistic effects):

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

In the Christian way of calculating age in years:

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

In finance there is a similar problem when calculating something often referred to as the Day Count Fraction, which roughly is a number of years for a given period. And the age issue is really a time measuring issue.

Example for the actual/actual (counting all days "correctly") convention:

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; 

Another quite common way to measure time generally is by "serializing" (the dude who named this date convention must seriously have been trippin'):

DateTime start, end = .... // Whatever, assume start is before end int days = (end - start).Days; 

I wonder how long we have to go before a relativistic age in seconds becomes more useful than the rough approximation of earth-around-sun-cycles during one's lifetime so far :) Or in other words, when a period must be given a location or a function representing motion for itself to be valid :)

</div
 
 
   
   
20
 
vote

Manteniéndolo simple (y posiblemente estúpido :)).

  Yn-Yb4  
 

Keeping it simple (and possibly stupid:)).

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."); 
</div
 
 
 
 
19
 
vote

La forma más sencilla que he encontrado es esto. Funciona correctamente para los locales de EE. UU. Y Europa occidental. No puedo hablar con otros lugares, especialmente lugares como China. 4 Extra Compara, a lo sumo, siguiendo el cálculo inicial de la edad.

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

Estaba mirando las respuestas a esto y noté que nadie ha hecho referencia a las implicaciones reglamentarias / legales de los nacimientos del Día de Salto. Por ejemplo, por wikipedia , si nace el 29 de febrero en varias jurisdicciones, 'Re Año de salto de cumpleaños varía:

  • En el Reino Unido y Hong Kong: es el día ordinario del año, por lo que el día siguiente, el 1 de marzo es tu cumpleaños.
  • En Nueva Zelanda: es el día anterior, el 28 de febrero con fines de licencias de conducir, y el 1 de marzo por otros fines.
  • Taiwan: Es el 28 de febrero.

y tan cerca como puedo decir, en los EE. UU., Los estatutos están en silencio sobre el asunto, dejándolo a la ley común y de cómo varios organismos reguladores definen las cosas en sus regulaciones.

a ese fin, una mejora:

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

Se debe tener en cuenta que este código asume:

  • un establecimiento de edad occidental (europeo), y
  • un calendario, como el calendario gregoriano que inserta un solo día de leap al final de un mes.
 

The simplest way I've ever found is this. It works correctly for the US and western europe locales. Can't speak to other locales, especially places like China. 4 extra compares, at most, following the initial computation of age.

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

I was looking over the answers to this and noticed that nobody has made reference to regulatory/legal implications of leap day births. For instance, per Wikipedia, if you're born on February 29th in various jurisdictions, you're non-leap year birthday varies:

  • In the United Kingdom and Hong Kong: it's the ordinal day of the year, so the next day, March 1st is your birthday.
  • In New Zealand: it's the previous day, February 28th for the purposes of driver licencing, and March 1st for other purposes.
  • Taiwan: it's February 28th.

And as near as I can tell, in the US, the statutes are silent on the matter, leaving it up to the common law and to how various regulatory bodies define things in their regulations.

To that end, an improvement:

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

It should be noted that this code assumes:

  • A western (European) reckoning of age, and
  • A calendar, like the Gregorian calendar that inserts a single leap day at the end of a month.
</div
 
 
19
 
vote
  TimeSpan diff = DateTime.Now - birthdayDateTime; string age = String.Format("{0:%y} years, {0:%M} months, {0:%d}, days old", diff);   

No estoy seguro de cómo exactamente desea que le haya regresado, así que acabo de hacer una cadena legible.

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

I'm not sure how exactly you'd like it returned to you, so I just made a readable string.

</div
 
 
17
 
vote

Aquí hay una solución.

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

Here is a solution.

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); 
</div
 
 
 
 
16
 
vote

Esta es una de las respuestas más precisas que pueden resolver el cumpleaños del 29 de febrero en comparación con cualquier año del 28 de febrero.

  public int GetAge(DateTime birthDate) {     int age = DateTime.Now.Year - birthDate.Year;      if (birthDate.DayOfYear > DateTime.Now.DayOfYear)         age--;      return age; }       
 

This is one of the most accurate answers that is able to resolve the birthday of 29th of Feb compared to any year of 28th Feb.

public int GetAge(DateTime birthDate) {     int age = DateTime.Now.Year - birthDate.Year;      if (birthDate.DayOfYear > DateTime.Now.DayOfYear)         age--;      return age; }     
</div
 
 
   
   
15
 
vote

Tengo un método personalizado para calcular la edad, más un mensaje de validación de bonificación en caso de que ayude:

  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 }   

Método Llame aquí y transmite el valor de DateTime (MM / DD / YYAY si el servidor se establece en la configuración regional de EE. UU.). Reemplace esto con cualquier otra caja de mensaje o cualquier contenedor para mostrar:

  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   

Recuerde que puede formatear el mensaje de la forma que le guste.

 

I have a customized method to calculate age, plus a bonus validation message just in case it helps:

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 } 

Method call here and pass out datetime value (MM/dd/yyyy if server set to USA locale). Replace this with anything a messagebox or any container to display:

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 

Remember you can format the message any way you like.

</div
 
 
14
 
vote

¿Qué tal esta solución?

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

How about this solution?

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"; ; } 
</div
 
 
12
 
vote
  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; }   
 
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; } 
</div
 
 
10
 
vote

El siguiente enfoque (Extracto de Library Period Biblioteca para .NET clase Datediff ) considera el calendario de la información de la cultura:

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

Uso:

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

The following approach (extract from Time Period Library for .NET class DateDiff) considers the calendar of the culture info:

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

Usage:

// ---------------------------------------------------------------------- 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 
</div
 
 
10
 
vote

Esta pregunta clásica merece una Solución de tiempo .

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

Uso:

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

También podría estar interesado en las siguientes mejoras:

  • Pasando en el reloj como un 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; } 3 , en lugar de usar 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; } 4 , mejoraría la prueba.

  • La zona de tiempo de destino probablemente cambiará, por lo que también desea un parámetro 99887776615 .

Consulte también My Blog Publicación sobre este tema: Manejo de cumpleaños , y otros aniversarios

 

This classic question is deserving of a Noda Time solution.

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

Usage:

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

You might also be interested in the following improvements:

  • Passing in the clock as an IClock, instead of using SystemClock.Instance, would improve testability.

  • The target time zone will likely change, so you'd want a DateTimeZone parameter as well.

See also my blog post on this subject: Handling Birthdays, and Other Anniversaries

</div
 
 
   
   
9
 
vote

La solución de Scarcher2 para un cálculo preciso del año de una edad de personas, pero necesitaba tomarlo más lejos y calcular sus meses y días junto con los años.

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

I used ScArcher2's solution for an accurate Year calculation of a persons age but I needed to take it further and calculate their Months and Days along with the Years.

    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; } 
</div
 
 
9
 
vote

Versión SQL:

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

SQL version:

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   
</div
 
 
8
 
vote

He hecho un pequeño cambio en marca SOEN's Respuesta: He reescribido la tercera línea para que la expresión pueda analizarse un poco más fácilmente.

  public int AgeInYears(DateTime bday) {     DateTime now = DateTime.Today;     int age = now.Year - bday.Year;                 if (bday.AddYears(age) > now)          age--;     return age; }   

También lo he convertido en una función por el bien de la claridad.

 

I've made one small change to Mark Soen's answer: I've rewriten the third line so that the expression can be parsed a bit more easily.

public int AgeInYears(DateTime bday) {     DateTime now = DateTime.Today;     int age = now.Year - bday.Year;                 if (bday.AddYears(age) > now)          age--;     return age; } 

I've also made it into a function for the sake of clarity.

</div
 
 

Relacionados problema

85  ¿Cómo eliminar la parte de tiempo de un valor de DateTime (SQL Server)?  ( How to remove the time portion of a datetime value sql server ) 
Aquí está lo que uso: SELECT CAST(FLOOR(CAST(getdate() as FLOAT)) as DATETIME) Estoy pensando que puede haber una manera mejor y más elegante. Requis...

1955  ¿Cómo calculo la edad de alguien en función de un cumpleaños tipo DateTime?  ( How do i calculate someones age based on a datetime type birthday ) 
Dado un Form5 que representa el cumpleaños de una persona, ¿cómo calculo su edad en años? ...

3  Calculando un delta de años desde una cita  ( Calculating a delta of years from a date ) 
Estoy tratando de descubrir una manera de calcular el año de nacimiento para los registros cuando se le da la edad a dos decimales en una fecha determinada, e...

2  C # fechas - bases de datos, pantalla y localización  ( C sharp dates databases display and localization ) 
Qué son algunas de las mejores prácticas de Fecha (y AMP) Formato de las mejores prácticas cuando quiera adherirse a la localización en una nueva aplicación. ...

41  Convierta la cadena hasta la fecha en .NET si mi formato de fecha entrante está en yyyymmdd  ( Convert string to date in net if my incoming date format is in yyyymmdd ) 
¿Cuál es la mejor manera de convertir la cadena hasta la fecha en C # si mi formato de fecha entrante está en YYYYMMDD EX: 20001106 ...

1563  Calcular el tiempo relativo en C #  ( Calculate relative time in c sharp ) 
Dado un valor específico double16 , ¿cómo mostrar el tiempo relativo, como: hace 2 horas hace 3 días hace un mes ...

17  Tiempo de falsificación sin cambiar el reloj del sistema de Windows  ( Faking time without changing windows system clock ) 
¿Alguien sabe de una herramienta de Windows para reportar fechas / horarios falsos a un proceso? Aparentemente hay programas de Linux que se pueden usar par...

0  Cómo convertir la fecha en el cuadro de texto a MySQL DateTime Format  ( How to convert date in text box to mysql datetime format ) 
Soy bastante nuevo en PHP y he estado leyendo Larry Ullman Libro para desarrollar un sitio básico de DB. He utilizado el selector de la fecha de YUI Calendar ...

-1  Operación MySQL DateTime  ( Mysql datetime operation ) 
¿Cómo obtener el valor de DateTime Varios días / semanas / meses / años más tarde en MySQL? Solo sé que el DateTime actual es ahora (). ...

68  ¿Cómo analizar un tiempo en un objeto de fecha de la entrada del usuario en JavaScript?  ( How to parse a time into a date object from user input in javascript ) 
Estoy trabajando en un widget de formularios para que los usuarios ingresen una hora del día en una entrada de texto (para una solicitud de calendario). Uso d...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos