Question Comment puis-je calculer l'âge de quelqu'un en C #?


Donné un DateTime représentant l'anniversaire d'une personne, comment puis-je calculer son âge en années?


1744


origine


Réponses:


Une solution facile à comprendre et 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--;

Cependant, cela suppose que vous recherchez le occidental idée de l'âge et ne pas utiliser Compter sur l'Asie de l'Est.


1714



C'est une manière étrange de le faire, mais si vous formatez la date à yyyymmdd et soustrayez la date de naissance de la date actuelle puis déposez les 4 derniers chiffres dont vous avez l'âge :)

Je ne connais pas C #, mais je crois que cela fonctionnera dans n'importe quelle langue.

20080814 - 19800703 = 280111 

Déposez 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. Erreur lors de la vérification 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;
}

892



Je ne sais pas comment la mauvaise solution peut être acceptée. L'extrait C # correct a été écrit par Michael Stum

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

Ici vous avez 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;
}

344



Je ne pense pas que l'une des réponses à ce jour fournisse des cultures qui calculent l'âge différemment. Voir, par exemple, Reckoning de l'âge de l'Asie de l'Est par rapport à celui de l'Ouest.

Tout réal la réponse doit inclure la localisation. le Modèle de stratégie serait probablement en ordre dans cet exemple.


115



La réponse simple à cela est d'appliquer AddYears comme indiqué ci-dessous parce que 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 semis, mais ni .Net ni aucune règle officielle ne le confirme, et la logique commune n'explique pas pourquoi certains nés en février devraient avoir 75% de leurs anniversaires dans un autre mois.

En outre, une méthode d'âge se prête à être ajouté comme une extension de DateTime. Par ceci vous pouvez obtenir l'âge de la façon la plus simple possible:

  1. Élément de liste

int age = date_de_naissance.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, lancez 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 date critique est le suivant:

Date de naissance: 2000-02-29 Date prévue: 2011-02-28 Âge: 11

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
}

99



Ma suggestion

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

Cela semble changer l'année à la bonne date. (J'ai repéré testé jusqu'à l'âge de 107)


76



Une autre fonction, pas par moi mais trouvée sur le web et affinée un peu:

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

Juste deux choses qui me viennent à l'esprit: Qu'en est-il des gens de pays qui n'utilisent pas le calendrier grégorien? DateTime.Now est dans la culture spécifique au serveur, je pense. Je n'ai absolument aucune connaissance sur le fait de travailler avec les calendriers asiatiques et je ne sais pas s'il existe un moyen facile de convertir les dates entre les calendriers, mais juste au cas où vous vous poseriez des questions sur les chinois de l'année 4660 :-)


65



Je suis en retard à la fête, mais voici un one-liner:

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

44



2 Les principaux problèmes à résoudre sont:

1. Calculer l'âge exact - en années, mois, jours, etc.

2. Calculer l'âge généralement perçu - Les gens ne se soucient généralement pas de leur âge, ils se soucient seulement de leur anniversaire dans l'année en cours.


Solution pour 1 est évident:

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 pour 2 est celui qui n'est pas si précis dans la détermination de l'âge total, mais est perçu comme précis par les gens. Les gens l'utilisent aussi habituellement lorsqu'ils calculent leur âge «manuellement»:

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 à 2 .:

  • C'est ma solution préférée
  • Nous ne pouvons pas utiliser DateTime.DayOfYear ou TimeSpans, car ils décalent le nombre de jours dans les années bissextiles
  • Je l'ai mis un peu plus de lignes pour la lisibilité

Juste une note de plus ... Je voudrais créer deux méthodes statiques surchargées, une pour l'utilisation universelle, deuxièmement pour la convivialité:

public static int GetAge(DateTime bithDay, DateTime today) 
{ 
  //chosen solution method body
}

public static int GetAge(DateTime birthDay) 
{ 
  return GetAge(birthDay, DateTime.Now);
}

44



Il y a plusieurs années, pour fournir gimmick calculatrice d'âge Sur mon site, j'ai écrit une fonction pour calculer l'âge à une fraction. C'est un port rapide de cette fonction à C # (de la version PHP). Je crains de ne pas avoir pu tester la version C #, mais j'espère que vous apprécierez tout de même!

(Certes, c'est un peu gadget dans le but de montrer des profils d'utilisateurs sur Stack Overflow, mais peut-être que les lecteurs trouveront une utilité pour cela :-))

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

33



C'est la version que nous utilisons ici. Cela fonctionne, et c'est assez simple. C'est la même idée que celle de Jeff, mais je pense que c'est un peu plus clair parce que ça sépare la logique de la soustraction, donc c'est un peu plus facile à comprendre.

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

Vous pourriez étendre l'opérateur ternaire pour le rendre encore plus clair, si vous pensez que ce genre de chose n'est pas clair.

Évidemment, cela est fait comme une méthode d'extension sur DateTime, mais il est clair que vous pouvez saisir cette ligne de code qui fait le travail et le mettre n'importe où. Ici, nous avons une autre surcharge de la méthode d'extension qui passe dans DateTime.Now, juste pour l'exhaustivité.


33