Vraag Hoe bereken ik iemands leeftijd in C #?


Gegeven a DateTime voor de verjaardag van een persoon, hoe bereken ik hun leeftijd in jaren?


1744


oorsprong


antwoorden:


Een eenvoudig te begrijpen en eenvoudige oplossing.

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

Dit veronderstelt echter dat u op zoek bent naar western idee van leeftijd en niet gebruiken Oost-Aziatische afrekening.


1714



Dit is een vreemde manier om het te doen, maar als je de datum opmaakt yyyymmdd en trek de geboortedatum af van de huidige datum en laat de laatste 4 cijfers vallen waarop je de leeftijd hebt :)

Ik ken C # niet, maar ik geloof dat dit in elke taal zal werken.

20080814 - 19800703 = 280111 

Laat de laatste 4 cijfers vallen = 28.

C # Code:

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

Of alternatief zonder alle typeconversie in de vorm van een uitbreidingsmethode. Foutcontrole weggelaten:

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



Ik weet niet hoe de verkeerde oplossing kan worden aanvaard. Het juiste C # -fragment is geschreven door Michael Stum

Hier is een testfragment:

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

Hier heb je de methoden:

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



Ik denk dat geen van de antwoorden tot nu toe voorziet in culturen die de leeftijd anders berekenen. Zie bijvoorbeeld Oost-Aziatische leeftijdsafrekening versus dat in het Westen.

Ieder echt antwoord moet lokalisatie bevatten. De Strategiepatroon zou waarschijnlijk in dit voorbeeld in orde zijn.


115



Het simpele antwoord hierop is om toe te passen AddYears zoals hieronder getoond, omdat dit de enige inheemse methode is om jaren toe te voegen aan 29 februari van schrikkeljaren en het correcte resultaat te verkrijgen van de 28e februari voor gewone jaren.

Sommigen hebben het gevoel dat 1 maart de geboortedag is van geboortes, maar noch .Net noch enige officiële regel ondersteunt dit, noch verklaart de logica dat sommigen die in februari geboren zijn 75% van hun verjaardagen in een andere maand moeten hebben.

Verder leent een Age-methode zich om te worden toegevoegd als een extensie voor DateTime. Hiermee kunt u de leeftijd op de meest eenvoudige manier verkrijgen:

  1. Lijstitem

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

Voer nu deze test uit:

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

Het voorbeeld van de kritieke datum is dit:

Geboortedatum: 2000-02-29 Datum later: 2011-02-28 Leeftijd: 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
}

En voor de latere datum 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



Mijn suggestie

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

Dat lijkt het jaar op de juiste datum te laten veranderen. (Ik heb een test uitgevoerd tot de leeftijd van 107)


76



Een andere functie, niet door mij maar gevonden op het web en een beetje verfijnd:

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

Slechts twee dingen die in me opkomen: hoe zit het met mensen uit landen die de gregoriaanse kalender niet gebruiken? DateTime.Now zit in de server-specifieke cultuur denk ik. Ik heb absoluut 0 kennis over het werken met Aziatische kalenders en ik weet niet of er een eenvoudige manier is om datums om te zetten tussen kalenders, maar voor het geval je je afvraagt ​​over die Chinese jongens uit het jaar 4660 :-)


65



Ik ben te laat op het feest, maar hier is een one-liner:

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

44



2 Voornaamste problemen om op te lossen zijn:

1. Bereken de exacte leeftijd - in jaren, maanden, dagen, etc.

2. Bereken over het algemeen waargenomen leeftijd - mensen geven er meestal niet om hoe oud ze precies zijn, ze geven er gewoon om wanneer hun verjaardag in het huidige jaar is.


Oplossing voor 1 ligt voor de hand:

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

Oplossing voor 2 is degene die niet zo precies is in het bepalen van de totale leeftijd, maar door mensen als precies wordt ervaren. Mensen gebruiken het meestal ook, wanneer ze hun leeftijd "handmatig" berekenen:

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
}

Aantekeningen bij 2 .:

  • Dit is mijn geprefereerde oplossing
  • We kunnen DateTime.DayOfYear of TimeSpans niet gebruiken, omdat het aantal dagen in schrikkeljaren verschuift
  • Ik heb er weinig meer regels geplaatst voor de leesbaarheid

Nog een opmerking ... Ik zou er twee statische overbelaste methoden voor maken, een voor universeel gebruik, de tweede voor gebruiksvriendelijkheid:

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

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

44



Vele jaren geleden, om een leeftijdscalculator gimmick op mijn website schreef ik een functie om de leeftijd te berekenen tot een fractie. Dit is een snelle poort van die functie naar C # (uit de PHP-versie). Ik ben bang dat ik de C # -versie niet heb kunnen testen, maar ik hoop dat je het toch leuk vindt!

(Toegegeven, dit is een beetje gimmicky voor het weergeven van gebruikersprofielen op Stack Overflow, maar misschien kunnen lezers er wel wat gebruik van maken :-))

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