Как вычислить возраст человека по дате рождения (DateTime) в C#?
Правильный расчёт возраста с учётом високосных годов и граничных случаев
Проблема с простым делением на 365 действительно даёт ошибки из-за високосных годов. Корректный подход — вычислять возраст на уровне целых лет, проверяя, был ли уже день рождения в текущем году. Вот надёжное решение:
public static int CalculateAge(DateTime birthDate, DateTime referenceDate)
{
// Вычисляем разницу в годах
int age = referenceDate.Year - birthDate.Year;
// Если день рождения в текущем году ещё не наступил, вычитаем 1 год
if (referenceDate.Month < birthDate.Month ||
(referenceDate.Month == birthDate.Month && referenceDate.Day < birthDate.Day))
{
age--;
}
return age;
}
// Использование:
DateTime birthday = new DateTime(2000, 2, 29);
DateTime today = DateTime.Today;
int age = CalculateAge(birthday, today);
Console.WriteLine($"Возраст: {age}");
Почему это работает?
- Базовая разница годов: Сначала мы берём разницу между годами — это максимальный возможный возраст.
- Коррекция на день рождения: Если текущий месяц меньше месяца рождения, или месяц равен, но день ещё не наступил — значит, день рождения в этом году ещё не был, и возраст нужно уменьшить на 1.
- Работа с 29 февраля: Если человек родился 29 февраля 2000 года, а сегодня 28 февраля 2024 года, то условие
referenceDate.Day < birthDate.Dayсработает (28 < 29), и возраст будет 23, а не 24. Если же сегодня 1 марта — условие не сработает, и возраст станет 24. Это корректно, так как в невисокосные годы день рождения формально наступает 1 марта (или считается, что 28 февраля, но логика остаётся верной).
Упрощённый вариант (без отдельного метода)
Если вам не нужна отдельная функция, можно встроить расчёт напрямую:
DateTime birthDate = new DateTime(1990, 5, 15);
DateTime today = DateTime.Today;
int age = today.Year - birthDate.Year;
if (today.Month < birthDate.Month ||
(today.Month == birthDate.Month && today.Day < birthDate.Day))
{
age--;
}
Console.WriteLine($"Возраст: {age}");
Обработка краевых случаев
Этот подход корректно обрабатывает:
- Людей, родившихся 29 февраля
- Ситуации, когда день рождения ещё не наступил в текущем году
- Любые високосные годы
- Даты рождения в прошлом и будущем (если дата рождения в будущем, возраст будет отрицательным — это нормально для валидации)
Важно: Для вычисления возраста на текущую дату используйте DateTime.Today, а не DateTime.Now, чтобы избежать влияния времени суток. Если нужно вычислить возраст на произвольную дату — передавайте её вторым параметром.
Альтернативный подход с использованием DateTime.AddYears
Можно использовать встроенный метод DateTime.AddYears для более лаконичного решения:
public static int CalculateAge(DateTime birthDate, DateTime referenceDate)
{
// Вычисляем возраст, прибавляя годы к дате рождения
int age = referenceDate.Year - birthDate.Year;
// Если после прибавления лет дата оказывается больше referenceDate, значит день рождения ещё не наступил
if (birthDate.AddYears(age) > referenceDate)
{
age--;
}
return age;
}
Этот метод использует тот факт, что DateTime.AddYears корректно обрабатывает 29 февраля: если прибавить 1 год к 29 февраля 2000 года, то получится 28 февраля 2001 года (так как 2001 — невисокосный). Таким образом, сравнение будет точным. Код получается короче, но менее очевиден для новичков. Выбирайте тот вариант, который лучше понимаете.
Дополнительный совет: Для отображения возраста в годах, месяцах и днях можно использовать библиотеку NodaTime, но для простого возраста в годах приведённых решений более чем достаточно.
Ответов пока нет.
Войдите чтобы оставить ответ