¿Cómo calculo la edad de alguien en C #?

votos
1k

Dado que DateTimerepresenta el cumpleaños de una persona, ¿cómo puedo calcular su edad en años?

Publicado el 01/08/2008 a las 00:40
fuente por usuario
En otros idiomas...                            


64 respuestas

votos
31

Hace muchos años, para proporcionar un truco de calculadora de edad en mi sitio web, escribí una función para calcular la edad en una fracción. Este es un puerto rápido de esa función para C # (de la versión de PHP ). Me temo que no he podido probar la versión de C #, ¡pero espero que disfrutes de todos modos!

(Es cierto que esto es un poco artificioso a los efectos de mostrar los perfiles de usuario en Stack Overflow, pero tal vez los lectores encuentren algún uso para él. :-))

double AgeDiff(DateTime date1, DateTime date2) {
    double years = date2.Year - date1.Year;

    /*
     * If date2 and date1 + round(date2 - date1) are on different sides
     * of 29 February, then our partial year is considered to have 366
     * days total, otherwise it's 365. Note that 59 is the day number
     * of 29 Feb.
     */
    double fraction = 365
            + (DateTime.IsLeapYear(date2.Year) && date2.DayOfYear >= 59
            && (date1.DayOfYear < 59 || date1.DayOfYear > date2.DayOfYear)
            ? 1 : 0);

    /*
     * The only really nontrivial case is if date1 is in a leap year,
     * and date2 is not. So let's handle the others first.
     */
    if (DateTime.IsLeapYear(date2.Year) == DateTime.IsLeapYear(date1.Year))
        return years + (date2.DayOfYear - date1.DayOfYear) / fraction;

    /*
     * If date2 is in a leap year, but date1 is not and is March or
     * beyond, shift up by a day.
     */
    if (DateTime.IsLeapYear(date2.Year)) {
        return years + (date2.DayOfYear - date1.DayOfYear
                - (date1.DayOfYear >= 59 ? 1 : 0)) / fraction;
    }

    /*
     * If date1 is not on 29 February, shift down date1 by a day if
     * March or later. Proceed normally.
     */
    if (date1.DayOfYear != 59) {
        return years + (date2.DayOfYear - date1.DayOfYear
                + (date1.DayOfYear > 59 ? 1 : 0)) / fraction;
    }

    /*
     * Okay, here date1 is on 29 February, and date2 is not on a leap
     * year. What to do now? On 28 Feb in date2's year, the ``age''
     * should be just shy of a whole number, and on 1 Mar should be
     * just over. Perhaps the easiest way is to a point halfway
     * between those two: 58.5.
     */
    return years + (date2.DayOfYear - 58.5) / fraction;
}
Respondida el 01/08/2008 a las 09:57
fuente por usuario

votos
26

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

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

Espero que esto ayude.

Respondida el 01/08/2008 a las 13:07
fuente por usuario

votos
61

Otra función, no por mí, pero que se encuentra en la web y la 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 me vienen a la mente dos cosas: ¿qué hay de las personas de países que no usan el calendario gregoriano? DateTime.Now está en la cultura específica del servidor, creo. Tengo absolutamente 0 conocimiento sobre el hecho de trabajar con calendarios asiáticos y no sé si hay una manera fácil de convertir fechas entre calendarios, pero por si acaso te estás preguntando sobre esos chicos chinos del año 4660 :-)

Respondida el 01/08/2008 a las 22:46
fuente por usuario

votos
1k

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 the person was born in case of a leap year
if (birthdate > today.AddYears(-age)) age--;

Sin embargo, esto supone que está buscando la idea occidental de la edad y no está utilizando el cálculo del este asiático .

Respondida el 04/08/2008 a las 17:50
fuente por usuario

votos
32

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 hacerlo 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 DateTime, pero es evidente que puede tomar esa línea de código que hace el trabajo y ponerlo en cualquier lugar. Aquí tenemos otra sobrecarga del método de extensión que ingresa DateTime.Now, solo para completar.

Respondida el 06/08/2008 a las 11:23
fuente por usuario

votos
874

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

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

20080814 - 19800703 = 280111 

Suelta los últimos 4 dígitos = 28.

C # Code:

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

O alternativamente sin toda la conversión de tipo en la forma de un método de extensión. Error al verificar omitido:

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;
}
Respondida el 15/08/2008 a las 04:47
fuente por usuario

votos
113

No creo que ninguna de las respuestas proporcione culturas que calculen la edad de manera diferente. Ver, por ejemplo, el cálculo de la edad del este asiático versus el de occidente.

Cualquier respuesta real debe incluir localización. El Patrón de Estrategia probablemente estaría en orden en este ejemplo.

Respondida el 17/08/2008 a las 18:14
fuente por usuario

votos
22

Creé 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:

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;
    }
};
Respondida el 23/08/2008 a las 14:58
fuente por usuario

votos
2

Creo que TimeSpan tiene todo lo que necesitamos en él, sin tener que recurrir a 365.25 (o cualquier otra aproximación). Ampliando el ejemplo de Aug:

DateTime myBD = new DateTime(1980, 10, 10);
TimeSpan difference = DateTime.Now.Subtract(myBD);

textBox1.Text = difference.Years + " years " + difference.Months + " Months " + difference.Days + " days";
Respondida el 26/09/2008 a las 21:07
fuente por usuario

votos
74

Mi sugerencia

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

Parece que el año está cambiando en la fecha correcta. (Hice la prueba hasta la edad de 107)

Respondida el 03/10/2008 a las 21:19
fuente por usuario

votos
21

He pasado un tiempo trabajando en esto y se me ocurrió esto para calcular la edad de alguien en años, meses y días. Probé contra el problema del 29 de febrero y saltamos años y parece funcionar, agradecería cualquier comentario:

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

}
Respondida el 18/05/2009 a las 12:24
fuente por usuario

votos