К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как вычислить возраст в 1С: практические способы и примеры

Способы вычислить возраст в 1С: функции БСП, запрос с РАЗНОСТЬДАТ, расчет на дату в СКД. Примеры кода, типичные ошибки и проверка результата.

Возраст сотрудника, клиента или контрагента требуется в кадровых отчётах, печатных формах, проверках условий документов и отборах. В 1С нет единой встроенной функции «Возраст()», поэтому задачу решают несколькими способами: через функции общих модулей Библиотеки стандартных подсистем (БСП), через язык запросов с функцией РАЗНОСТЬДАТ или собственным алгоритмом на встроенном языке. Выбор зависит от того, где нужен результат — в коде, в запросе, в СКД или в произвольном отчёте.

Главная сложность — корректный учёт дня рождения. Простое деление разности дат на 365 даёт ошибку в 1 день на каждый високосный год, а на больших выборках это сотни неверных значений. Правильный подход всегда сравнивает месяц и день рождения с текущей датой и уменьшает результат на единицу, если день рождения в этом году ещё не наступил.

Ниже разобраны рабочие варианты: готовые функции типовых конфигураций, запрос к справочнику физических лиц, расчёт на произвольную дату, вычисление возраста в СКД и проверка граничных случаев — 29 февраля, пустая дата рождения, возраст на дату документа.

Как устроен правильный алгоритм расчёта возраста

Возраст в полных годах — это количество прошедших дней рождения между датой рождения и датой расчёта. Формально: берём разность годов и проверяем, наступил ли в текущем году день рождения. Если месяц рождения больше текущего месяца, либо месяцы равны, но день рождения больше текущего дня, — вычитаем единицу.

Такой алгоритм корректно обрабатывает високосные годы, потому что оперирует календарными месяцами и днями, а не количеством дней между датами. Деление разности дат на 365 или 365,25 — распространённая ошибка: она даёт сбой на границах дат рождения и накапливает погрешность.

Отдельный вопрос — дата, на которую считается возраст. В кадровых отчётах это обычно текущая дата или конец периода отчёта, в документах — дата документа, в проверках совершеннолетия — дата операции. Всегда передавайте дату расчёта явным параметром, а не зашивайте ТекущаяДатаСеанса() внутрь функции: иначе отчёт за прошлый период покажет неверные данные.

Расчёт возраста на встроенном языке 1С

Универсальная функция на встроенном языке выглядит так:

Функция ВозрастВГодах(ДатаРождения, ДатаРасчета) Экспорт

Если Не ЗначениеЗаполнено(ДатаРождения) Тогда

Возврат Неопределено;

КонецЕсли;

Возраст = Год(ДатаРасчета) - Год(ДатаРождения);

Если Месяц(ДатаРасчета) < Месяц(ДатаРождения)

Или (Месяц(ДатаРасчета) = Месяц(ДатаРождения)

И День(ДатаРасчета) < День(ДатаРождения)) Тогда

Возраст = Возраст - 1;

КонецЕсли;

Возврат Возраст;

КонецФункции

Функция принимает дату рождения и дату расчёта, возвращает целое число полных лет либо Неопределено для пустой даты. Такой вариант подходит для модулей форм, печатных форм, проверок при записи документа и любых серверных процедур.

Расчёт с учётом месяцев и дней

Иногда нужен возраст вида «35 лет 4 месяца 12 дней» — например, для медицинских документов или персональных карточек. В этом случае последовательно вычисляют годы, затем месяцы остатка и дни, каждый раз сдвигая опорную дату. В типовых конфигурациях для представления возраста строкой часто используются функции склонения и разбора периодов из общих модулей работы с датами.

1c
Возраст = Год(ДатаРасчета) - Год(ДатаРождения);
Если Месяц(ДатаРасчета) < Месяц(ДатаРождения)
	Или (Месяц(ДатаРасчета) = Месяц(ДатаРождения) И День(ДатаРасчета) < День(ДатаРождения)) Тогда
	Возраст = Возраст - 1;
КонецЕсли;

Готовые функции в типовых конфигурациях (БСП)

В конфигурациях на Библиотеке стандартных подсистем (ЗУП, УТ, ERP, Бухгалтерия) уже есть инструменты для работы с датами и возрастом. Перед написанием собственной функции проверьте общие модули: в них есть процедуры разбора периодов, расчёта разности дат в годах, месяцах и днях, а также представления возраста строкой с правильным склонением («год», «года», «лет»).

В ЗУП возраст физического лица нередко доступен в готовых отчётах и в данных кадрового учёта без дополнительного программирования. Если задача — вывести возраст в списке сотрудников или в отчёте, сначала проверьте настройки типового отчёта: возможно, достаточно добавить поле или включить группировку.

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

Маршрут решения

Как выбрать способ расчёта

Конфигурация типовая на БСП и нужен возраст в коде или печатной формеИспользуйте функции общих модулей работы с датами из БСП
Нужен возраст в отчёте на СКД без доработки кодаДобавьте вычисляемое поле или выражение в запросе набора данных
Выборка большая и считается в запросеСчитайте возраст прямо в запросе через РАЗНОСТЬДАТ и ВЫБОР
Конфигурация самописная без БСПНапишите собственную функцию по алгоритму с поправкой на день рождения

Вычисление возраста в запросе

В запросе возраст вычисляют через РАЗНОСТЬДАТ и поправку на день рождения. Пример для справочника физических лиц с реквизитом «ДатаРождения»:

ВЫБРАТЬ

ФизическиеЛица.Ссылка КАК ФизическоеЛицо,

РАЗНОСТЬДАТ(ФизическиеЛица.ДатаРождения, &ДатаРасчета, ГОД)

- ВЫБОР

КОГДА МЕСЯЦ(&ДатаРасчета) < МЕСЯЦ(ФизическиеЛица.ДатаРождения)

ИЛИ МЕСЯЦ(&ДатаРасчета) = МЕСЯЦ(ФизическиеЛица.ДатаРождения)

И ДЕНЬ(&ДатаРасчета) < ДЕНЬ(ФизическиеЛица.ДатаРождения)

ТОГДА 1

ИНАЧЕ 0

КОНЕЦ КАК Возраст

ИЗ

Справочник.ФизическиеЛица КАК ФизическиеЛица

ГДЕ

ФизическиеЛица.ДатаРождения <> ДАТАВРЕМЯ(1, 1, 1)

Обратите внимание: РАЗНОСТЬДАТ(…, ГОД) возвращает разность календарных годов без учёта месяца и дня, поэтому поправка через ВЫБОР обязательна. Условие ГДЕ отсекает записи с пустой датой рождения — иначе в результат попадут фиктивные значения в тысячи лет.

Дату расчёта передавайте параметром &ДатаРасчета. Не используйте в запросе функции текущей даты без параметра, если отчёт может строиться за прошлый период, — результат будет зависеть от дня запуска, а не от данных отчёта.

Возраст в СКД

В системе компоновки данных тот же запрос помещается в набор данных, а поле «Возраст» становится доступным для группировок, отборов и ресурсов. Альтернатива — вычисляемое поле с выражением на языке выражений СКД, но запросный вариант работает быстрее на больших выборках, потому что расчёт выполняется на стороне СУБД.

Порядок добавления возраста в отчёт на СКД
  1. 1
    Откройте схему компоновки данных отчёта и перейдите в набор данных
  2. 2
    Добавьте в запрос вычисление возраста через РАЗНОСТЬДАТ с поправкой ВЫБОР
  3. 3
    Передайте дату расчёта параметром, свяжите его с периодом отчёта
  4. 4
    Проверьте поле на закладке настроек: добавьте в группировку или ресурсы
  5. 5
    Запустите отчёт на тестовых данных с известными датами рождения

Граничные случаи и типичные ошибки

Самая частая ошибка — деление разности дат на 365 или 365,25. На границе дня рождения такой расчёт ошибается на год, а для людей старшего возраста погрешность накапливается из-за високосных лет. Второй типовой дефект — забытая поправка на день рождения: сотрудник, родившийся в декабре, весь год отображается на год старше.

Отдельные сложные случаи: дата рождения 29 февраля (в невисокосный год день рождения условно наступает 28 февраля или 1 марта — определите правило заранее и зафиксируйте его в функции), пустая дата рождения, дата рождения в будущем из-за ошибки ввода. Для последнего случая полезно добавить проверку: если дата рождения больше даты расчёта, возвращать признак ошибки, а не отрицательный возраст.

Ещё один риск — часовые пояса и время в дате. Если дата рождения хранится с временем, сравнение дней может сработать неожиданно. Приводите даты к началу дня функцией НачалоДня() перед сравнением.

Типичные ошибки
01
Деление разности дат на 365 — погрешность на високосных годах и ошибка на границе дня рождения
02
Отсутствие поправки на наступление дня рождения — возраст завышен на год для части людей
03
Игнорирование пустой даты рождения — в отчёте появляются значения в тысячи лет
04
Использование текущей даты вместо даты отчёта — отчёт за прошлый период показывает неверный возраст
05
Сравнение дат с временем без приведения к началу дня — сбой сравнения дней

Проверка результата

Проверяйте функцию на контрольных примерах с известным результатом. Возьмите несколько дат рождения: день рождения сегодня, день рождения завтра, 29 февраля, 1 января, пустая дата. Для каждого случая посчитайте ожидаемый возраст вручную и сравните с результатом функции или запроса.

Для запросов удобно сделать тестовую таблицу в консоли запросов и прогнать вариант на ней. В отчётах на СКД проверьте, что возраст корректно меняется при смене периода отчёта, а не остаётся привязанным к текущей дате.

Контрольные точки

Как проверить результат

День рождения — сегодня
Норма

Возраст увеличился на 1 по сравнению со вчерашним днём

Тревожный признак

Возраст не изменился или изменился вчера

День рождения — завтра
Норма

Возраст ещё не увеличился

Тревожный признак

Возраст уже на год больше

Пустая дата рождения
Норма

Поле пустое или NULL

Тревожный признак

Показывается возраст в сотни или тысячи лет

Смена периода отчёта
Норма

Возраст пересчитывается на дату отчёта

Тревожный признак

Возраст всегда считается на сегодня

Часто задаваемые вопросы

Как вычислить возраст в месяцах или днях, а не в годах?

Используйте РАЗНОСТЬДАТ с типом МЕСЯЦ или ДЕНЬ — для полных месяцев и дней поправка на день рождения не нужна, если вас устраивает календарная разность. Для «полных месяцев жизни» применяйте тот же приём с поправкой: разность месяцев минус 1, если день рождения в текущем месяце ещё не наступил.

Как обработать дату рождения 29 февраля?

В невисокосный год функция День(ДатаРождения) вернёт 29, и сравнение с 28 февраля даст «день рождения ещё не наступил», а с 1 марта — «наступил». Определите правило заранее: чаще днём рождения в невисокосный год считают 28 февраля или 1 марта. При необходимости добавьте в функцию отдельную ветку для этого случая.

Можно ли вычислить возраст без программирования, в пользовательском режиме?

Да, если в конфигурации есть подходящий отчёт или произвольный отчёт с консолью компоновки. В ЗУП возраст сотрудников доступен в типовых кадровых отчётах. В универсальном отчёте можно добавить вычисляемое поле с выражением разности дат — но корректную поправку на день рождения в выражении СКД задать сложнее, надёжнее через запрос.

Почему РАЗНОСТЬДАТ в годах даёт неверный возраст без поправки?

РАЗНОСТЬДАТ(Дата1, Дата2, ГОД) считает разность календарных годов: для дат 01.12.1990 и 01.01.2026 она вернёт 35, хотя полных лет — 34. Функция не учитывает, наступил ли день рождения в текущем году, поэтому поправка через ВЫБОР обязательна.

Как вывести возраст строкой с правильным склонением («год», «года», «лет»)?

В конфигурациях на БСП используйте функции склонения числительных из общих модулей работы со строками — они подбирают форму слова по числу. В самописной конфигурации напишите простую функцию: последняя цифра 1 (кроме 11) — «год», 2–4 (кроме 12–14) — «года», иначе — «лет».

Где хранить дату рождения, чтобы возраст был доступен везде?

Стандартное место — справочник «Физические лица» с реквизитом «Дата рождения». Возраст хранить не нужно: он меняется каждый день, поэтому его всегда вычисляют на дату расчёта. Хранение возраста в реквизите — ошибка проектирования, данные устаревают и требуют постоянного пересчёта.

Итог

Что важно запомнить

Возраст в 1С вычисляют, а не хранят: разность годов минус поправка на ненаступивший день рождения. В типовых конфигурациях используйте функции БСП, в запросах — РАЗНОСТЬДАТ с ВЫБОР, дату расчёта передавайте параметром и всегда обрабатывайте пустую дату рождения.