Как рассчитать возраст человека на С#?

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

1743
задан Jeff Atwood 01 авг. '08 в 2:40
источник поделиться
64 ответов
  • 1
  • 2
  • 3

Легкое для понимания и простое решение.

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

Однако это предполагает, что вы ищете западную идею о возрасте и не используете восточноазиатские расчеты.

1759
ответ дан Mike Polen 04 авг. '08 в 19:50
источник поделиться

Это странный способ сделать это, но если вы отформатируете дату до yyyymmdd и вычтите дату рождения с текущей даты, то оставьте последние 4 цифры, у которых есть возраст:)

Я не знаю С#, но я считаю, что это будет работать на любом языке.

20080814 - 19800703 = 280111 

Отбросьте последние 4 цифры = 28.

Код С#:

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;
}
909
ответ дан ScArcher2 15 авг. '08 в 6:47
источник поделиться

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

Вот фрагмент теста:

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;
}
349
ответ дан RMA 20 окт. '09 в 18:07
источник поделиться

Я не думаю, что какой-либо из ответов до сих пор предоставляет культурам, которые вычисляют возраст по-разному. См., Например, Восточно-азиатское расценение возраста против того, что на Западе.

Любой реальный ответ должен включать локализацию. В этом примере шаблон стратегии, вероятно, будет в порядке.

116
ответ дан James A. Rosen 17 авг. '08 в 20:14
источник поделиться

Простым ответом на это является применение AddYears, как показано ниже, потому что это единственный родной метод добавления лет к 29 февраля високосного года и получение правильного результата 28 февраля для общих лет,

Некоторые считают, что 1-й Март - это день рождения leaplings, но ни .Net, ни официальное правило не поддерживают это, и общая логика не объясняет, почему у некоторых, родившихся в феврале, должно быть 75% их дней рождения в другой месяц.

Кроме того, метод Возраста может быть добавлен как расширение к DateTime. Благодаря этому вы можете получить возраст самым простым способом:

  • Элемент списка

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
}
100
ответ дан camelCasus 20 февр. '11 в 2:56
источник поделиться

Мое предложение

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

Кажется, что год меняется в правильную дату. (Я тестировал пятно до 107)

77
ответ дан James Curran 03 окт. '08 в 23:19
источник поделиться

Другая функция, а не я, но найденная в Интернете, немного уточнила:

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

Только две вещи, которые приходят мне в голову: как насчет людей из стран, которые не используют gregorian календарь? DateTime.Now в культуре сервера, я думаю. У меня есть абсолютно 0 знаний о фактической работе с азиатскими календарями, и я не знаю, есть ли простой способ конвертировать даты между календарями, но на всякий случай вам интересно об этих китайских парнях с 4660 года: -)

65
ответ дан Michael Stum 02 авг. '08 в 0:46
источник поделиться

Я опаздываю на вечеринку, но здесь однострочный:

int age = new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year-1;
44
ответ дан SillyMonkey 18 мая '09 в 15:36
источник поделиться

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
ответ дан Thetam 11 апр. '11 в 17:47
источник поделиться

Много лет назад, чтобы предоставить трюк калькулятора возраста на моем веб-сайте, я написал функцию для вычисления возраста до доли. Это быстрый порт этой функции для С# (из версия PHP). Боюсь, я не смог проверить версию С#, но надеюсь, что вам все равно понравится!

(По общему признанию, это немного неудобно для показа пользовательских профилей в Stack Overflow, но, возможно, читатели найдут для этого некоторое использование.: -))

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 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 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 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
ответ дан Chris Jester-Young 01 авг. '08 в 11:57
источник поделиться

Это версия, которую мы используем здесь. Он работает, и это довольно просто. Это та же идея, что и у Джеффа, но я думаю, что это немного яснее, потому что она отделяет логику от вычитания одной, поэтому ее немного легче понять.

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

Вы можете расширить тернарный оператор, чтобы сделать его еще более ясным, если вы считаете, что это неясно.

Очевидно, это делается как метод расширения на DateTime, но, очевидно, вы можете захватить одну строку кода, которая выполняет эту работу, и помещать ее куда угодно. Здесь у нас есть другая перегрузка метода расширения, который проходит в DateTime.Now, только для полноты.

33
ответ дан David Wengier 06 авг. '08 в 13:23
источник поделиться

Я использую это:

public static class DateTimeExtensions
{
    public static int Age(this DateTime birthDate)
    {
        return Age(birthDate, DateTime.Now);
    }

    public static int Age(this DateTime birthDate, DateTime offsetDate)
    {
        int result=0;
        result = offsetDate.Year - birthDate.Year;

        if (offsetDate.DayOfYear < birthDate.DayOfYear)
        {
              result--;
        }

        return result;
    }
}
30
ответ дан Elmer 17 февр. '10 в 16:32
источник поделиться

Лучший способ, который я знаю из-за високосных лет и всего:

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

Надеюсь, что это поможет.

28
ответ дан Nick Berardi 01 авг. '08 в 15:07
источник поделиться

Это дает "более подробно" на этот вопрос. Возможно, это то, что вы ищете

DateTime birth = new DateTime(1974, 8, 29);
DateTime today = DateTime.Now;
TimeSpan span = today - birth;
DateTime age = DateTime.MinValue + span;

// Make adjustment due to MinValue equalling 1/1/1
int years = age.Year - 1;
int months = age.Month - 1;
int days = age.Day - 1;

// Print out not only how many years old they are but give months and days as well
Console.Write("{0} years, {1} months, {2} days", years, months, days);
27
ответ дан Jacqueline Loriault 20 сент. '13 в 22:13
источник поделиться

Я создал пользовательскую функцию SQL Server, чтобы вычислить возраст человека, учитывая их дату рождения. Это полезно, когда вам это нужно как часть запроса:

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;
    }
};
23
ответ дан user2601 23 авг. '08 в 16:58
источник поделиться

Я потратил некоторое время на то, чтобы поработать над этим, и придумал это, чтобы рассчитать кого-то возраст годами, месяцами и днями. Я тестировал проблему 29 февраля и високосные годы, и, похоже, она работает, я буду благодарен за любую обратную связь:

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

}
22
ответ дан Jon 18 мая '09 в 14:24
источник поделиться

Вот еще один ответ:

public static int AgeInYears(DateTime birthday, DateTime today)
{
    return ((today.Year - birthday.Year) * 372 + (today.Month - birthday.Month) * 31 + (today.Day - birthday.Day)) / 372;
}

Это было тщательно проверено на единицу. Это выглядит немного "волшебным". Число 372 - это количество дней, которое было бы в году, если бы каждый месяц имел 31 день.

Объяснение того, почему он работает (снято отсюда):

Пусть множество Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day

age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db))/372

Мы знаем, что нам нужно либо Yn-Yb если дата уже достигнута, Yn-Yb-1 если она не Yn-Yb-1.

a) Если Mn<Mb, мы имеем -341 <= 31*(Mn-Mb) <= -31 and -30 <= Dn-Db <= 30

-371 <= 31*(Mn - Mb) + (Dn - Db) <= -1

С целым делением

(31*(Mn - Mb) + (Dn - Db))/372 = -1

б) Если Mn=Mb и Dn<Db, то 31*(Mn - Mb) = 0 and -30 <= Dn-Db <= -1

С целым делением снова

(31*(Mn - Mb) + (Dn - Db))/372 = -1

в) Если Mn>Mb, мы имеем 31 <= 31*(Mn-Mb) <= 341 and -30 <= Dn-Db <= 30

1 <= 31*(Mn - Mb) + (Dn - Db) <= 371

С целым делением

(31*(Mn - Mb) + (Dn - Db))/372 = 0

d) Если Mn=Mb и Dn>Db, то 31*(Mn - Mb) = 0 and 1 <= Dn-Db <= 3 0

С целым делением снова

(31*(Mn - Mb) + (Dn - Db))/372 = 0

e) Если Mn=Mb и Dn=Db, то 31*(Mn - Mb) + Dn-Db = 0

и поэтому (31*(Mn - Mb) + (Dn - Db))/372 = 0

18
ответ дан Matthew Watson 22 апр. '13 в 11:19
источник поделиться
TimeSpan diff = DateTime.Now - birthdayDateTime;
string age = String.Format("{0:%y} years, {0:%M} months, {0:%d}, days old", diff);

Я не уверен, как именно вы хотите, чтобы он вернулся к вам, поэтому я просто сделал удобочитаемую строку.

17
ответ дан Dakotah Hicock 19 сент. '13 в 18:18
источник поделиться

Нужно ли рассматривать людей, которые меньше 1 года? как китайская культура, мы описываем возраст маленьких детей как 2 месяца или 4 недели.

Ниже моя реализация, это не так просто, как я себе представлял, особенно для того, чтобы иметь дело с датой, как 2/28.

public static string HowOld(DateTime birthday, DateTime now)
{
    if (now < birthday)
        throw new ArgumentOutOfRangeException("birthday must be less than now.");

    TimeSpan diff = now - birthday;
    int diffDays = (int)diff.TotalDays;

    if (diffDays > 7)//year, month and week
    {
        int age = now.Year - birthday.Year;

        if (birthday > now.AddYears(-age))
            age--;

        if (age > 0)
        {
            return age + (age > 1 ? " years" : " year");
        }
        else
        {// month and week
            DateTime d = birthday;
            int diffMonth = 1;

            while (d.AddMonths(diffMonth) <= now)
            {
                diffMonth++;
            }

            age = diffMonth-1;

            if (age == 1 && d.Day > now.Day)
                age--;

            if (age > 0)
            {
                return age + (age > 1 ? " months" : " month");
            }
            else
            {
                age = diffDays / 7;
                return age + (age > 1 ? " weeks" : " week");
            }
        }
    }
    else if (diffDays > 0)
    {
        int age = diffDays;
        return age + (age > 1 ? " days" : " day");
    }
    else
    {
        int age = diffDays;
        return "just born";
    }
}

Эта реализация прошла ниже тестовых примеров.

[TestMethod]
public void TestAge()
{
    string age = HowOld(new DateTime(2011, 1, 1), new DateTime(2012, 11, 30));
    Assert.AreEqual("1 year", age);

    age = HowOld(new DateTime(2011, 11, 30), new DateTime(2012, 11, 30));
    Assert.AreEqual("1 year", age);

    age = HowOld(new DateTime(2001, 1, 1), new DateTime(2012, 11, 30));
    Assert.AreEqual("11 years", age);

    age = HowOld(new DateTime(2012, 1, 1), new DateTime(2012, 11, 30));
    Assert.AreEqual("10 months", age);

    age = HowOld(new DateTime(2011, 12, 1), new DateTime(2012, 11, 30));
    Assert.AreEqual("11 months", age);

    age = HowOld(new DateTime(2012, 10, 1), new DateTime(2012, 11, 30));
    Assert.AreEqual("1 month", age);

    age = HowOld(new DateTime(2008, 2, 28), new DateTime(2009, 2, 28));
    Assert.AreEqual("1 year", age);

    age = HowOld(new DateTime(2008, 3, 28), new DateTime(2009, 2, 28));
    Assert.AreEqual("11 months", age);

    age = HowOld(new DateTime(2008, 3, 28), new DateTime(2009, 3, 28));
    Assert.AreEqual("1 year", age);

    age = HowOld(new DateTime(2009, 1, 28), new DateTime(2009, 2, 28));
    Assert.AreEqual("1 month", age);

    age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 3, 1));
    Assert.AreEqual("1 month", age);

    // NOTE.
    // new DateTime(2008, 1, 31).AddMonths(1) == new DateTime(2009, 2, 28);
    // new DateTime(2008, 1, 28).AddMonths(1) == new DateTime(2009, 2, 28);
    age = HowOld(new DateTime(2009, 1, 31), new DateTime(2009, 2, 28));
    Assert.AreEqual("4 weeks", age);

    age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 2, 28));
    Assert.AreEqual("3 weeks", age);

    age = HowOld(new DateTime(2009, 2, 1), new DateTime(2009, 3, 1));
    Assert.AreEqual("1 month", age);

    age = HowOld(new DateTime(2012, 11, 5), new DateTime(2012, 11, 30));
    Assert.AreEqual("3 weeks", age);

    age = HowOld(new DateTime(2012, 11, 1), new DateTime(2012, 11, 30));
    Assert.AreEqual("4 weeks", age);

    age = HowOld(new DateTime(2012, 11, 20), new DateTime(2012, 11, 30));
    Assert.AreEqual("1 week", age);

    age = HowOld(new DateTime(2012, 11, 25), new DateTime(2012, 11, 30));
    Assert.AreEqual("5 days", age);

    age = HowOld(new DateTime(2012, 11, 29), new DateTime(2012, 11, 30));
    Assert.AreEqual("1 day", age);

    age = HowOld(new DateTime(2012, 11, 30), new DateTime(2012, 11, 30));
    Assert.AreEqual("just born", age);

    age = HowOld(new DateTime(2000, 2, 29), new DateTime(2009, 2, 28));
    Assert.AreEqual("8 years", age);

    age = HowOld(new DateTime(2000, 2, 29), new DateTime(2009, 3, 1));
    Assert.AreEqual("9 years", age);

    Exception e = null;

    try
    {
        age = HowOld(new DateTime(2012, 12, 1), new DateTime(2012, 11, 30));
    }
    catch (ArgumentOutOfRangeException ex)
    {
        e = ex;
    }

    Assert.IsTrue(e != null);
}

Надеюсь, что это будет полезно.

17
ответ дан rockXrock 30 нояб. '12 в 15:13
источник поделиться

Сохранение его простым (и, возможно, глупым:)).

DateTime birth = new DateTime(1975, 09, 27, 01, 00, 00, 00);
TimeSpan ts = DateTime.Now - birth;
Console.WriteLine("You are approximately " + ts.TotalSeconds.ToString() + " seconds old.");
17
ответ дан Freddy 18 авг. '10 в 17:29
источник поделиться

Самый простой способ, который я когда-либо нашел, - это. Он работает правильно для локалей США и западной Европы. Не может разговаривать с другими местами, особенно в таких местах, как Китай. 4 дополнительных сравнивает, самое большее, после первоначального расчета возраста.

public int AgeInYears(DateTime birthDate, DateTime referenceDate)
{
  Debug.Assert(referenceDate >= birthDate, 
               "birth date must be on or prior to the reference date");

  DateTime birth = birthDate.Date;
  DateTime reference = referenceDate.Date;
  int years = (reference.Year - birth.Year);

  //
  // an offset of -1 is applied if the birth date has 
  // not yet occurred in the current year.
  //
  if (reference.Month > birth.Month);
  else if (reference.Month < birth.Month) 
    --years;
  else // in birth month
  {
    if (reference.Day < birth.Day)
      --years;
  }

  return years ;
}

Я искал ответы на это и заметил, что никто не ссылался на нормативные/правовые последствия рождений високосного дня. Например, в Википедии, если вы родились 29 февраля в разных юрисдикциях, вы несетевый год рождения различается:

  • В Соединенном Королевстве и Гонконге: это порядковый день в году, поэтому на следующий день, 1 марта, ваш день рождения.
  • В Новой Зеландии: это в предыдущий день, 28 февраля для целей лицензирования водителей, и 1 марта для других целей.
  • Тайвань: это 28 февраля.

И насколько я могу судить, в США уставы молчат по этому вопросу, оставляя это до общего закона и как различные регулирующие органы определяют вещи в своих правилах.

С этой целью улучшение:

public enum LeapDayRule
{
  OrdinalDay     = 1 ,
  LastDayOfMonth = 2 ,
}

static int ComputeAgeInYears(DateTime birth, DateTime reference, LeapYearBirthdayRule ruleInEffect)
{
  bool isLeapYearBirthday = CultureInfo.CurrentCulture.Calendar.IsLeapDay(birth.Year, birth.Month, birth.Day);
  DateTime cutoff;

  if (isLeapYearBirthday && !DateTime.IsLeapYear(reference.Year))
  {
    switch (ruleInEffect)
    {
      case LeapDayRule.OrdinalDay:
        cutoff = new DateTime(reference.Year, 1, 1)
                             .AddDays(birth.DayOfYear - 1);
        break;

      case LeapDayRule.LastDayOfMonth:
        cutoff = new DateTime(reference.Year, birth.Month, 1)
                             .AddMonths(1)
                             .AddDays(-1);
        break;

      default:
        throw new InvalidOperationException();
    }
  }
  else
  {
    cutoff = new DateTime(reference.Year, birth.Month, birth.Day);
  }

  int age = (reference.Year - birth.Year) + (reference >= cutoff ? 0 : -1);
  return age < 0 ? 0 : age;
}

Следует отметить, что этот код предполагает:

  • Западный (европейский) показатель возраста и
  • Календарь, как григорианский календарь, который вставляет один височный день в конце месяца.
16
ответ дан Nicholas Carey 06 окт. '10 в 4:49
источник поделиться

Вот решение.

DateTime dateOfBirth = new DateTime(2000, 4, 18);
DateTime currentDate = DateTime.Now;

int ageInYears = 0;
int ageInMonths = 0;
int ageInDays = 0;

ageInDays = currentDate.Day - dateOfBirth.Day;
ageInMonths = currentDate.Month - dateOfBirth.Month;
ageInYears = currentDate.Year - dateOfBirth.Year;

if (ageInDays < 0)
{
    ageInDays += DateTime.DaysInMonth(currentDate.Year, currentDate.Month);
    ageInMonths = ageInMonths--;

    if (ageInMonths < 0)
    {
        ageInMonths += 12;
        ageInYears--;
    }
}

if (ageInMonths < 0)
{
    ageInMonths += 12;
    ageInYears--;
}

Console.WriteLine("{0}, {1}, {2}", ageInYears, ageInMonths, ageInDays);
15
ответ дан Rajeshwaran S P 18 июня '09 в 13:35
источник поделиться

Это один из самых точных ответов, который способен решить день рождения 29 февраля по сравнению с любым годом 28 февраля.

public int GetAge(DateTime birthDate)
{
    int age = DateTime.Now.Year - birthDate.Year;

    if (birthDate.DayOfYear > DateTime.Now.DayOfYear)
        age--;

    return age;
}
15
ответ дан mjb 23 окт. '14 в 16:18
источник поделиться

Это не прямой ответ, а скорее философское рассуждение о проблеме под рукой с квази-научной точки зрения.

Я бы сказал, что в вопросе не указывается единица или культура, в которой можно измерить возраст, большинство ответов, кажется, принимают целочисленное годовое представление. SI-единица для времени second, эрго должен быть правильный общий ответ (конечно, предполагая нормализованный DateTime и не учитывающий релятивистских эффектов):

var lifeInSeconds = (DateTime.Now.Ticks - then.Ticks)/TickFactor;

В христианском способе расчета возраста в годах:

var then = ... // Then, in this case the birthday
var now = DateTime.UtcNow;
int age = now.Year - then.Year;
if (now.AddYears(-age) < then) age--;

В финансировании существует аналогичная проблема при расчете того, что часто называют "Днем числа дней", что примерно на несколько лет за данный период. И проблема возраста - это проблема измерения времени.

Пример фактического/фактического (считая все дни "правильно" ):

DateTime start, end = .... // Whatever, assume start is before end

double startYearContribution = 1 - (double) start.DayOfYear / (double) (DateTime.IsLeapYear(start.Year) ? 366 : 365);
double endYearContribution = (double)end.DayOfYear / (double)(DateTime.IsLeapYear(end.Year) ? 366 : 365);
double middleContribution = (double) (end.Year - start.Year - 1);

double DCF = startYearContribution + endYearContribution + middleContribution;

Другим довольно распространенным способом измерения времени обычно является "сериализация" (чувак, который назвал это соглашение о дате, должен был серьезно быть trippin):

DateTime start, end = .... // Whatever, assume start is before end
int days = (end - start).Days;

Интересно, как долго мы должны идти до того, как релятивистский возраст в считанные секунды станет более полезным, чем приблизительное приближение солнечных циклов на земле за одну жизнь до сих пор:) Или, другими словами, когда должен быть задан период местоположение или функция, представляющая движение для себя, чтобы быть действительной:)

14
ответ дан flindeberg 23 нояб. '12 в 18:00
источник поделиться

Как насчет этого решения?

static string CalcAge(DateTime birthDay)
{
    DateTime currentDate = DateTime.Now;         
    int approximateAge = currentDate.Year - birthDay.Year;
    int daysToNextBirthDay = (birthDay.Month * 30 + birthDay.Day) - 
        (currentDate.Month * 30 + currentDate.Day) ;

    if (approximateAge == 0 || approximateAge == 1)
    {                
        int month =  Math.Abs(daysToNextBirthDay / 30);
        int days = Math.Abs(daysToNextBirthDay % 30);

        if (month == 0)
            return "Your age is: " + daysToNextBirthDay + " days";

        return "Your age is: " + month + " months and " + days + " days"; ;
    }

    if (daysToNextBirthDay > 0)
        return "Your age is: " + --approximateAge + " Years";

    return "Your age is: " + approximateAge + " Years"; ;
}
13
ответ дан Doron 08 марта '11 в 10:25
источник поделиться

У меня есть настроенный метод расчета возраста, плюс сообщение о подтверждении бонуса на всякий случай:

public void GetAge(DateTime dob, DateTime now, out int years, out int months, out int days)
{
    years = 0;
    months = 0;
    days = 0;

    DateTime tmpdob = new DateTime(dob.Year, dob.Month, 1);
    DateTime tmpnow = new DateTime(now.Year, now.Month, 1);

    while (tmpdob.AddYears(years).AddMonths(months) < tmpnow)
    {
        months++;
        if (months > 12)
        {
            years++;
            months = months - 12;
        }
    }

    if (now.Day >= dob.Day)
        days = days + now.Day - dob.Day;
    else
    {
        months--;
        if (months < 0)
        {
            years--;
            months = months + 12;
        }
        days += DateTime.DaysInMonth(now.AddMonths(-1).Year, now.AddMonths(-1).Month) + now.Day - dob.Day;
    }

    if (DateTime.IsLeapYear(dob.Year) && dob.Month == 2 && dob.Day == 29 && now >= new DateTime(now.Year, 3, 1))
        days++;

}   

private string ValidateDate(DateTime dob) //This method will validate the date
{
    int Years = 0; int Months = 0; int Days = 0;

    GetAge(dob, DateTime.Now, out Years, out Months, out Days);

    if (Years < 18)
        message =  Years + " is too young. Please try again on your 18th birthday.";
    else if (Years >= 65)
        message = Years + " is too old. Date of Birth must not be 65 or older.";
    else
        return null; //Denotes validation passed
}

Вызов метода здесь и передайте значение datetime (MM/dd/yyyy, если сервер установлен в локали США). Замените это на любое сообщение или любой контейнер для отображения:

DateTime dob = DateTime.Parse("03/10/1982");  

string message = ValidateDate(dob);

lbldatemessage.Visible = !StringIsNullOrWhitespace(message);
lbldatemessage.Text = message ?? ""; //Ternary if message is null then default to empty string

Помните, что вы можете отформатировать сообщение так, как вам нравится.

13
ответ дан DareDevil 22 янв. '14 в 10:23
источник поделиться
private int GetAge(int _year, int _month, int _day
{
    DateTime yourBirthDate= new DateTime(_year, _month, _day);

    DateTime todaysDateTime = DateTime.Today;
    int noOfYears = todaysDateTime.Year - yourBirthDate.Year;

    if (DateTime.Now.Month < yourBirthDate.Month ||
        (DateTime.Now.Month == yourBirthDate.Month && DateTime.Now.Day < yourBirthDate.Day))
    {
        noOfYears--;
    }

    return  noOfYears;
}
11
ответ дан AEMLoviji 06 сент. '10 в 17:09
источник поделиться

Я использовал решение ScArcher2 для точного расчета года в возрасте лиц, но мне нужно было продолжить его и рассчитать месяцы и дни вместе с Годами.

    public static Dictionary<string,int> CurrentAgeInYearsMonthsDays(DateTime? ndtBirthDate, DateTime? ndtReferralDate)
    {
        //----------------------------------------------------------------------
        // Can't determine age if we don't have a dates.
        //----------------------------------------------------------------------
        if (ndtBirthDate == null) return null;
        if (ndtReferralDate == null) return null;

        DateTime dtBirthDate = Convert.ToDateTime(ndtBirthDate);
        DateTime dtReferralDate = Convert.ToDateTime(ndtReferralDate);

        //----------------------------------------------------------------------
        // Create our Variables
        //----------------------------------------------------------------------
        Dictionary<string, int> dYMD = new Dictionary<string,int>();
        int iNowDate, iBirthDate, iYears, iMonths, iDays;
        string sDif = "";

        //----------------------------------------------------------------------
        // Store off current date/time and DOB into local variables
        //---------------------------------------------------------------------- 
        iNowDate = int.Parse(dtReferralDate.ToString("yyyyMMdd"));
        iBirthDate = int.Parse(dtBirthDate.ToString("yyyyMMdd"));

        //----------------------------------------------------------------------
        // Calculate Years
        //----------------------------------------------------------------------
        sDif = (iNowDate - iBirthDate).ToString();
        iYears = int.Parse(sDif.Substring(0, sDif.Length - 4));

        //----------------------------------------------------------------------
        // Store Years in Return Value
        //----------------------------------------------------------------------
        dYMD.Add("Years", iYears);

        //----------------------------------------------------------------------
        // Calculate Months
        //----------------------------------------------------------------------
        if (dtBirthDate.Month > dtReferralDate.Month)
            iMonths = 12 - dtBirthDate.Month + dtReferralDate.Month - 1;
        else
            iMonths = dtBirthDate.Month - dtReferralDate.Month;

        //----------------------------------------------------------------------
        // Store Months in Return Value
        //----------------------------------------------------------------------
        dYMD.Add("Months", iMonths);

        //----------------------------------------------------------------------
        // Calculate Remaining Days
        //----------------------------------------------------------------------
        if (dtBirthDate.Day > dtReferralDate.Day)
            //Logic: Figure out the days in month previous to the current month, or the admitted month.
            //       Subtract the birthday from the total days which will give us how many days the person has lived since their birthdate day the previous month.
            //       then take the referral date and simply add the number of days the person has lived this month.

            //If referral date is january, we need to go back to the following year December to get the days in that month.
            if (dtReferralDate.Month == 1)
                iDays = DateTime.DaysInMonth(dtReferralDate.Year - 1, 12) - dtBirthDate.Day + dtReferralDate.Day;       
            else
                iDays = DateTime.DaysInMonth(dtReferralDate.Year, dtReferralDate.Month - 1) - dtBirthDate.Day + dtReferralDate.Day;       
        else
            iDays = dtReferralDate.Day - dtBirthDate.Day;             

        //----------------------------------------------------------------------
        // Store Days in Return Value
        //----------------------------------------------------------------------
        dYMD.Add("Days", iDays);

        return dYMD;
}
8
ответ дан Dylan Hayes 12 авг. '11 в 23:53
источник поделиться

SQL-версия:

declare @dd smalldatetime = '1980-04-01'
declare @age int = YEAR(GETDATE())-YEAR(@dd)
if (@dd> DATEADD(YYYY, -@age, GETDATE())) set @age = @age -1

print @age  
8
ответ дан xenedia 30 июня '16 в 14:24
источник поделиться

Я сделал небольшое изменение в ответе Марка Соена: я переписал третью строку, чтобы выражение можно было проанализировать немного легче.

public int AgeInYears(DateTime bday)
{
    DateTime now = DateTime.Today;
    int age = now.Year - bday.Year;            
    if (bday.AddYears(age) > now) 
        age--;
    return age;
}

Я также сделал это для ясности.

7
ответ дан cdiggins 16 июля '11 в 21:01
источник поделиться
  • 1
  • 2
  • 3

Другие вопросы по меткам