2017 votes

Comment calculer l'âge d'une personne sur la base d'un anniversaire de type DateTime ?

Étant donné un DateTime représentant l'anniversaire d'une personne, comment calculer son âge en années ?

163 votes

Ce que toutes les réponses données jusqu'à présent ont omis, c'est que cela dépend de l'endroit où la personne est née et de l'endroit où elle se trouve actuellement.

49 votes

@Yaur : Il suffit de convertir l'heure actuelle + la naissance en GMT/UTC, l'âge est seulement une valeur relative, donc les fuseaux horaires ne sont pas pertinents. Pour déterminer le fuseau horaire actuel de l'utilisateur, vous pouvez utiliser GeoLocating.

1 votes

Pourquoi ne pas envisager la [date julienne][1] ? [1] : stackoverflow.com/questions/7103064/

2252voto

Mike Polen Points 3173

Une solution simple et facile à comprendre.

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

Cependant, cela suppose que vous cherchez le ouest idée de l'âge et ne pas utiliser Les comptes de l'Asie de l'Est .

86 votes

Cette réponse ne fonctionne pas avec toutes les régions et tous les âges. Plusieurs pays ont sauté des dates après la naissance de personnes actuellement vivantes, notamment la Russie (1918), la Grèce (1924) et la Turquie (1926).

35 votes

En fait, ce n'est pas encore tout à fait correct. Ce code suppose que 'bday' est la partie date d'un DateTime. C'est un cas limite (je suppose que la plupart des gens ne passeront que des dates et non des dates-horaires), mais si vous passez une date d'anniversaire comme une date-heure où l'heure est supérieure à 00:00:00, vous rencontrerez le bogue que Danvil a signalé. Définir bday = bday.Date résout ce problème.

4 votes

C'est 12 ans mais pourquoi ne pas simplement enlever le jour de la naissance - aujourd'hui plus tard, aller chercher l'intervalle de temps et vous pouvez l'obtenir sans un "si".

1053voto

ScArcher2 Points 22118

C'est une façon étrange de le faire, mais si vous formatez la date au format yyyymmdd et soustrayez la date de naissance de la date actuelle puis enlevez les 4 derniers chiffres, vous avez l'âge :)

Je ne connais pas le C#, mais je pense que cela fonctionnera dans n'importe quel langage.

20080814 - 19800703 = 280111 

Laissez tomber les 4 derniers chiffres = 28 .

Code C# :

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

Ou alternativement sans toute la conversion de type sous la forme d'une méthode d'extension. La vérification des erreurs est omise :

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

10 votes

En fait, c'est très bien pour l'utilisation de MS-SQL avec des champs de type date-temps (nombre total de jours depuis le 01-011900).

0 votes

Dans votre autre réponse, vous pouvez éviter le dépassement d'entier en soustrayant les années, puis en soustrayant le mois * 30,5 + le jour et en divisant par 366.

8 votes

@numerek Veuillez poster vos suggestions de modifications comme une réponse à part entière. Pour ce que ça vaut, l'année en cours multipliée par 10000 est loin d'être un dépassement d'entier, de deux ordres de grandeur. 20.150.000 vs 2.147.483.648

401voto

RMA Points 231

Voici un extrait de test :

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

Vous avez ici les méthodes :

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

37 votes

Bien que ce code fonctionne, il affirme qu'une personne née un jour bissextile atteint l'année d'âge suivante le 1er mars des années non bissextiles, plutôt que le 28 février. En réalité, l'une ou l'autre option peut être correcte . Wikipedia a quelque chose à dire à ce sujet . Ainsi, si votre code n'est pas "mauvais", la solution acceptée ne l'est pas non plus.

21 votes

@MattJohnson Je pense que c'est en fait correct. Si mon anniversaire était le 29 février, alors le 28 février mon anniversaire n'est pas passé, et je devrais avoir le même âge que le 27 février. Le 1er mars, par contre, mon anniversaire est passé et je devrais avoir l'âge suivant. Aux États-Unis, un commerce qui vend de l'alcool affichera un panneau du type "Si vous êtes né après ce jour de l'an 2000, vous ne pouvez pas acheter d'alcool" (l'an 2000 change chaque année). Cela signifie qu'une personne née le 29 février ne peut pas acheter d'alcool le 28 février de l'année de ses 21 ans (dans la plupart des endroits), ce qui conforte l'idée qu'elle n'a pas un an de plus avant le 1er mars.

6 votes

@jfren484 - lisez l'article de Wikipedia. Il varie considérablement selon les juridictions.

131voto

James A. Rosen Points 25774

Je pense qu'aucune des réponses données jusqu'à présent ne tient compte des cultures qui calculent l'âge différemment. Voir, par exemple, L'âge de l'Asie de l'Est par rapport à celle de l'Ouest.

Tout réel La réponse doit inclure la localisation. Le site Modèle de stratégie serait probablement de mise dans cet exemple.

117voto

camelCasus Points 61

La réponse simple à cette question est d'appliquer AddYears comme indiqué ci-dessous car c'est la seule méthode native pour ajouter des années au 29 février des années bissextiles et obtenir le résultat correct du 28 février pour les années communes.

Certains pensent que le 1er mars est l'anniversaire des bissextiles, mais ni .Net ni aucune règle officielle ne le confirme, et la logique commune n'explique pas pourquoi certaines personnes nées en février devraient avoir 75% de leur anniversaire dans un autre mois.

En outre, une méthode d'âge se prête à être ajoutée comme une extension de la méthode d'âge. DateTime . Vous pouvez ainsi obtenir l'âge de la manière la plus simple possible :

  1. Élément de liste

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

Maintenant, exécutez ce 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();
    }
}

L'exemple de la date critique est le suivant :

Date de naissance : 2000-02-29 Date ultérieure : 2011-02-28 Âge : 11 ans

Sortie :

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

Et pour la date ultérieure 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
}

4 votes

Un commentaire concernant le fait d'avoir l'anniversaire du 29 février le 1er mars, techniquement, l'avoir le 28 est trop tôt (1 jour plus tôt en fait). Le 1er mars est un jour trop tard. Mais puisque l'anniversaire se situe entre deux dates, l'utilisation du 1er pour calculer l'âge dans les années non bissextiles me semble plus logique, puisque cette personne a effectivement cet âge le 1er (et le 2 et le 3) mars de chaque année, mais pas le 28 février.

2 votes

Du point de vue de la conception du logiciel, écrire ceci comme une méthode d'extension n'a pas beaucoup de sens pour moi. date.Age(other) ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X