Питання Як підрахувати вік в C #?


Даний а DateTime репрезентуючи день народження людини, як я можу розрахувати свій вік у роки?


1744


походження


які відповіді до цих пір пропустили, це те, що залежить від того, де людина народилася і де вони зараз. - Yaur
@ Яур: Просто перетворюйте час зараз + народження в GMT / UTC, вік становить лише відносне значення, тому часові пояси не мають значення. Для визначення поточного часового поясу користувача можна використовувати GeoLocating. - Stefan Steiger
Чому б не вважати [Julian Date] [1]? [1]: stackoverflow.com/questions/7103064/... - Muhammad Hewedy
Якщо ми беремо до уваги пропозицію Яура щодо розрахунку перехресних часових поясів, чи слід будь-яким чином впливати на день освітлення? - DDM
Ніхто не розглядав високосні роки? або перевірити місяць? - Crash Override


Відповіді:


Легко зрозуміле та просте рішення.

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

Однак це припускає, що ви шукаєте західний ідея віку і не використовую Східно-азіатський розрахунок.


1720



Просто хотів прокоментувати роботу DateTime.Now. Якщо вам не потрібне точне значення часової зони, скористайтеся DataTime.UtcNow, це набагато швидше. - JAG
З огляду на те, що ми говоримо про дні народження, ви можете просто скористатися DataTime. На даний час даний час не має релевантності. - Tristan Warner-Smith
Ця відповідь не працює з усіма регіонами та різними віками. Кілька країн пропустили дати після народження нинішніх живих людей, зокрема Росії (1918 р.), Греції (1924 р.) Та Туреччини (1926 р.). - Lars D
Фактично, це все ще не цілком правильно. Цей код передбачає, що "bday" - це частина дати DateTime. Це краєвид (я думаю, більшість людей просто передаватимуть дати, а не дату), але якщо ви перейдете в день народження як дату та час, коли час перевищує 00:00:00, Вдайся в помилку, зазначений Денвіл. Встановлення bday = bday.Date виправляє це. - Øyvind
Останній рядок змусив мене задуматися надто багато. Замість того, як: if (bday.AddYears (age)> now) age--; Це здається більш інтуїтивним виразом. - cdiggins


Це не дивно, але якщо ви форматуєте дату yyyymmdd і відніміть дату народження від поточної дати, тоді скиньте останні 4 цифри у вас віку :)

Я не знаю C #, але я вважаю, що це буде працювати на будь-якій мові.

20080814 - 19800703 = 280111 

Залиште останні 4 цифри = 28.

Код C #:

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

Або альтернативно, без будь-якої конверсії типу у формі методу розширення. Помилка перевірки пропущено:

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

894



Horrai для yyyymmdd. Перший продукт бази даних я використовував на Р.ersonal Сomputer (близько 1981) зберігаються дати в цьому форматі. Маніпулювання датою будь-якого виду було набагато простіше. - radarbob
Насправді це чудово підходить для використання на MS-SQL з датами-полями (загальні дні з 01-011900) - Patrik Eckebrecht
@numerek Будь ласка, опублікуйте запропоновані модифікації як свою власну відповідь. Для того, що це коштує, нинішній рік у 10 000 разів не перевищує цілого числа, на два порядки. 20 150 000 проти 2 147 483 648 - GalacticCowboy
@ LongChalk 20180101 - 20171231 = 8870. Залиште останні 4 цифри, і у вас є (передбачається) 0 на вік. Як ти дістався 1? - Rufus L
@ фліндеберг Так, ось що я казав до LongChalk ... - Rufus L


Я не знаю, як можна прийняти неправильне рішення. Правильний фрагмент C # був написаний Майклом Стумом

Ось тестовий фрагмент:

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

Тут у вас є методи:

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

345



Вихід був-Тест 9 9 8 - MoXplod
Хоча цей код працює, він стверджує, що людина, яка народилася в стрибковій день, 1 березня стає наступним роком не високосні роки, а не 28 лютого. В реальності, будь-який варіант може бути правильним. У Вікіпедії є що сказати про це. Таким чином, якщо ваш код не "неправильний", це не є прийнятним рішенням. - Matt Johnson
@Матт Джонсон Я думаю, що це насправді правильно. Якщо мій bday був 29 лютого, то 28 лютого мій bday не пройшов, і я повинен бути тим самим віком, що і 27 лютого. Однак 1 березня ми пройшли мій Bday, і я повинен бути наступним віком. У США бізнес, який продає алкоголь, матиме знак, який говорить щось подібне: "Якщо ви народилися після цього дня в річному обчисленні, ви не можете купувати алкоголь" (де річний рік змінюється щороку). Це означає, що хтось, хто народився 29 лютого, не може купувати алкоголь 28 лютого, коли вони становлять 21 (більшість місць), і підтримує думку, що до 1 березня вони не досягли більше року. - jfren484
@ jfren484 - читати статтю Вікіпедії. Він значно відрізняється в різних юрисдикціях. - Matt Johnson
@ jfren484 Ваша претензія абсолютно не пов'язана з філософією; але все пов'язане з цим ваше особисте почуття. Коли людина, яка народилася 29 лютого, "віками" в значній мірі не має значення, якщо вік не є "законним віком" (наприклад, можна купувати алкоголь, голосувати, отримувати пенсію, приєднуватися до армії, отримати водійське посвідчення). Розгляньте вік пиття в США (21 рік): для більшості людей це 7670 днів. Це 7671 день, якщо він народився до 29 лютого у високосний рік або з 1 березня до високосного року. Якщо народжується 29 лютого: 28 лютого - 7670 днів, а 1 марта - 7671 день. Вибір є довільним це може йти в будь-якому випадку. - Craig Young


Я не думаю, що жоден із відповідей поки що не передбачає культури, які розраховують вік різним чином. Див., Наприклад, Східно-Азіатський віковий розрахунок проти Заходу.

Будь-який реальний відповідь має включати локалізацію. The Стратегія мабуть, буде в порядку в цьому прикладі.


115



З статті вікіпедії, яку ви надали: "У Китаї та Японії це використовується для традиційного гадання або релігії, і він зникає в повсякденному житті між народами міста". - some
@some - корейці все ще використовують цю систему в першу чергу. - Justin L.
Власне, ця концепція може бути досить важливою - людям не подобається, що їхню персональну інформацію неправильно розповідають. Як приклад, половина моєї сім'ї живе в Малайзії, а половина - у Великобританії. Зараз моє вік вважається на два роки вище, коли я з однією стороною моєї сім'ї, ніж з іншою. - Phil Gan
Ця система не тільки використовується нами в основному в Кореї, але і як турист, що обговорює віки з місцевими жителями, місцеві жителі ввічливо посилаються на себе один одного в рік свого народження. Мені не 25, мені 87 років. Мені подобається цей підхід краще. більше "міжнародного формату дати народження" - Dean Rather
У В'єтнамі в повсякденному житті, навіть коли використовується західна система, вік розраховується просто шляхом віднімання років. Дата виключена - phuclv


Проста відповідь на це потрібно застосувати AddYears як показано нижче, оскільки це єдиний нативний спосіб, який додає до 29 лютого високосні роки і отримує правильний результат 28 лютого на загальні роки.

Деякі вважають, що 1-го числа березня - день народження лепесток, але ні .Net, ні будь-яке офіційне правило це не підтримують, а також загальна логіка пояснює, чому деякі народжені у лютому повинні мати 75% днів народження в інший місяць.

Крім того, метод Age дає змогу додавати як розширення до DateTime. За допомогою цього ви можете отримати вік найпростішим способом:

  1. Список елементів

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

Запустіть цей тест:

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

Критичним прикладом дати є таке:

Дата народження: 2000-02-29. Пізніше: 2011-02-28 Вік: 11

Вихід:

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

І на більш пізню дату 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



Коментар щодо того, що 1-го березня - день народження 29-го, технічно, воно на 28-му занадто рано (на початку дня - на 1 день). На 1-й день занадто пізно. Але з моменту, коли день народження між ними, використання першого для розрахунку віку у непідготовлені роки для мене є більш сприйнятливим, оскільки ця людина дійсно є старою 1 березня (і 2 і 3) кожен рік, але не 28 лютого. - CyberClaw


Моє пропозиція

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

Здається, що рік змінився на потрібну дату. (Я пройшов тестування до 107 років)


76



Звідки виходить 365.255? Я не думаю, що це буде працювати взагалі. - dreeves
365 днів на рік. +0,25 для високосного року. +0,005 для інших виправлень - James Curran
Я не думаю, що Гаррі Патч оцінив би вашу методологію тестування: latimes.com/news/obituaries/... - MusiGenesis
Середня тривалість року в григоріанському календарі 365.2425 днів. - dan04
^ ^ Оскільки іноді це важливо. У моєму тестуванні це не вдається на день народження людей, він повідомляє, що вони молодші, ніж вони. - ChadT


Ще одна функція, а не мене, але знайдена в Інтернеті, трохи покращена.

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

Лише дві речі, які приходять в мою думку: як щодо людей з країн, які не використовують григоріанський календар? DateTime.Now знаходиться в специфічній для сервера культурі, я думаю. У мене є абсолютно 0 знань про те, як працювати з азіатськими календарями, і я не знаю, чи є легкий спосіб конвертувати дати між календарями, але на всякий випадок вам цікаво, що ці китайські хлопці з року 4660 :-)


65



Здається, що це найкраще підходить для різних регіонів (форматів дати). - webdad3


Я запізнююсь на вечірку, але ось один вкладиш:

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

44



Це зламано. Зроблено тестування: public static int CalculateAge (DateTime dateOfBirth, DateTime dateToCalculateAge) {повернути новий DateTime (dateToCalculateAge.Subtract (dateOfBirth) .Ticks) .Year - 1; } ... Дає 14 років, коли я ввожу 1990-06-01, і розраховую вік на день, перш ніж його 14-річний день народження (1990-05-31). - Kjensen


2 Основними проблемами вирішення є:

1. Обчислити Точний вік - у роках, місяцях, днях і т. д.

2. Обчислити загальноприйнятий вік - людям зазвичай не подобається, на скільки років вони точно, вони просто дбають, коли їхній день народження в поточному році.


Рішення для 1 очевидно:

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

Рішення для 2 це така, яка не є настільки точною у визначенні загального віку, але сприймається як точна людиною. Люди також зазвичай використовують його, коли вони розраховують свій вік "вручну":

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
}

Примітки до 2:

  • Це моє бажане рішення
  • Ми не можемо використовувати DateTime.DayOfYear або TimeSpans, оскільки вони змінюють кількість днів у високосні роки
  • Я поставив там трохи більше рядків для читання

Ще одне примітка ... Я б створив 2 статичних перевантажених методів для нього, один для універсального використання, другий для зручності використання:

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

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

44





Багато років тому, щоб забезпечити віковий калькулятор трюк на моєму веб-сайті я написав функцію для розрахунку віку до частки. Це швидкий порт цієї функції для C # (від версія PHP) Боюся, що я не спромігся протестувати версію C #, але сподіваюся, вам все одно подобається!

(Напевно, це трохи трюк для цілей показу користувацьких профілів у переповненні стака, але, можливо, читачі знайдуть для неї якесь використання. :-))

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



Круто. Хоча я просто використовував астрономічні роки. - IllidanS4