Разработка и Конфигурация · 11 мин
Как вычислить возраст в 1С: практические способы и примеры
Способы вычислить возраст в 1С: функции БСП, запрос с РАЗНОСТЬДАТ, расчет на дату в СКД. Примеры кода, типичные ошибки и проверка результата.
Возраст сотрудника, клиента или контрагента требуется в кадровых отчётах, печатных формах, проверках условий документов и отборах. В 1С нет единой встроенной функции «Возраст()», поэтому задачу решают несколькими способами: через функции общих модулей Библиотеки стандартных подсистем (БСП), через язык запросов с функцией РАЗНОСТЬДАТ или собственным алгоритмом на встроенном языке. Выбор зависит от того, где нужен результат — в коде, в запросе, в СКД или в произвольном отчёте.
Главная сложность — корректный учёт дня рождения. Простое деление разности дат на 365 даёт ошибку в 1 день на каждый високосный год, а на больших выборках это сотни неверных значений. Правильный подход всегда сравнивает месяц и день рождения с текущей датой и уменьшает результат на единицу, если день рождения в этом году ещё не наступил.
Ниже разобраны рабочие варианты: готовые функции типовых конфигураций, запрос к справочнику физических лиц, расчёт на произвольную дату, вычисление возраста в СКД и проверка граничных случаев — 29 февраля, пустая дата рождения, возраст на дату документа.
Как устроен правильный алгоритм расчёта возраста
Возраст в полных годах — это количество прошедших дней рождения между датой рождения и датой расчёта. Формально: берём разность годов и проверяем, наступил ли в текущем году день рождения. Если месяц рождения больше текущего месяца, либо месяцы равны, но день рождения больше текущего дня, — вычитаем единицу.
Такой алгоритм корректно обрабатывает високосные годы, потому что оперирует календарными месяцами и днями, а не количеством дней между датами. Деление разности дат на 365 или 365,25 — распространённая ошибка: она даёт сбой на границах дат рождения и накапливает погрешность.
Отдельный вопрос — дата, на которую считается возраст. В кадровых отчётах это обычно текущая дата или конец периода отчёта, в документах — дата документа, в проверках совершеннолетия — дата операции. Всегда передавайте дату расчёта явным параметром, а не зашивайте ТекущаяДатаСеанса() внутрь функции: иначе отчёт за прошлый период покажет неверные данные.
Расчёт возраста на встроенном языке 1С
Универсальная функция на встроенном языке выглядит так:
Функция ВозрастВГодах(ДатаРождения, ДатаРасчета) Экспорт
Если Не ЗначениеЗаполнено(ДатаРождения) Тогда
Возврат Неопределено;
КонецЕсли;
Возраст = Год(ДатаРасчета) - Год(ДатаРождения);
Если Месяц(ДатаРасчета) < Месяц(ДатаРождения)
Или (Месяц(ДатаРасчета) = Месяц(ДатаРождения)
И День(ДатаРасчета) < День(ДатаРождения)) Тогда
Возраст = Возраст - 1;
КонецЕсли;
Возврат Возраст;
КонецФункции
Функция принимает дату рождения и дату расчёта, возвращает целое число полных лет либо Неопределено для пустой даты. Такой вариант подходит для модулей форм, печатных форм, проверок при записи документа и любых серверных процедур.
Расчёт с учётом месяцев и дней
Иногда нужен возраст вида «35 лет 4 месяца 12 дней» — например, для медицинских документов или персональных карточек. В этом случае последовательно вычисляют годы, затем месяцы остатка и дни, каждый раз сдвигая опорную дату. В типовых конфигурациях для представления возраста строкой часто используются функции склонения и разбора периодов из общих модулей работы с датами.
Возраст = Год(ДатаРасчета) - Год(ДатаРождения);
Если Месяц(ДатаРасчета) < Месяц(ДатаРождения)
Или (Месяц(ДатаРасчета) = Месяц(ДатаРождения) И День(ДатаРасчета) < День(ДатаРождения)) Тогда
Возраст = Возраст - 1;
КонецЕсли;Готовые функции в типовых конфигурациях (БСП)
В конфигурациях на Библиотеке стандартных подсистем (ЗУП, УТ, ERP, Бухгалтерия) уже есть инструменты для работы с датами и возрастом. Перед написанием собственной функции проверьте общие модули: в них есть процедуры разбора периодов, расчёта разности дат в годах, месяцах и днях, а также представления возраста строкой с правильным склонением («год», «года», «лет»).
В ЗУП возраст физического лица нередко доступен в готовых отчётах и в данных кадрового учёта без дополнительного программирования. Если задача — вывести возраст в списке сотрудников или в отчёте, сначала проверьте настройки типового отчёта: возможно, достаточно добавить поле или включить группировку.
Использовать типовые механизмы предпочтительнее собственных: они учитывают склонения, пустые даты и уже протестированы на граничных случаях. Собственную функцию пишите, когда типовой функциональности нет или конфигурация самописная.
Как выбрать способ расчёта
Вычисление возраста в запросе
В запросе возраст вычисляют через РАЗНОСТЬДАТ и поправку на день рождения. Пример для справочника физических лиц с реквизитом «ДатаРождения»:
ВЫБРАТЬ
ФизическиеЛица.Ссылка КАК ФизическоеЛицо,
РАЗНОСТЬДАТ(ФизическиеЛица.ДатаРождения, &ДатаРасчета, ГОД)
- ВЫБОР
КОГДА МЕСЯЦ(&ДатаРасчета) < МЕСЯЦ(ФизическиеЛица.ДатаРождения)
ИЛИ МЕСЯЦ(&ДатаРасчета) = МЕСЯЦ(ФизическиеЛица.ДатаРождения)
И ДЕНЬ(&ДатаРасчета) < ДЕНЬ(ФизическиеЛица.ДатаРождения)
ТОГДА 1
ИНАЧЕ 0
КОНЕЦ КАК Возраст
ИЗ
Справочник.ФизическиеЛица КАК ФизическиеЛица
ГДЕ
ФизическиеЛица.ДатаРождения <> ДАТАВРЕМЯ(1, 1, 1)
Обратите внимание: РАЗНОСТЬДАТ(…, ГОД) возвращает разность календарных годов без учёта месяца и дня, поэтому поправка через ВЫБОР обязательна. Условие ГДЕ отсекает записи с пустой датой рождения — иначе в результат попадут фиктивные значения в тысячи лет.
Дату расчёта передавайте параметром &ДатаРасчета. Не используйте в запросе функции текущей даты без параметра, если отчёт может строиться за прошлый период, — результат будет зависеть от дня запуска, а не от данных отчёта.
Возраст в СКД
В системе компоновки данных тот же запрос помещается в набор данных, а поле «Возраст» становится доступным для группировок, отборов и ресурсов. Альтернатива — вычисляемое поле с выражением на языке выражений СКД, но запросный вариант работает быстрее на больших выборках, потому что расчёт выполняется на стороне СУБД.
- 1Откройте схему компоновки данных отчёта и перейдите в набор данных
- 2Добавьте в запрос вычисление возраста через РАЗНОСТЬДАТ с поправкой ВЫБОР
- 3Передайте дату расчёта параметром, свяжите его с периодом отчёта
- 4Проверьте поле на закладке настроек: добавьте в группировку или ресурсы
- 5Запустите отчёт на тестовых данных с известными датами рождения
Граничные случаи и типичные ошибки
Самая частая ошибка — деление разности дат на 365 или 365,25. На границе дня рождения такой расчёт ошибается на год, а для людей старшего возраста погрешность накапливается из-за високосных лет. Второй типовой дефект — забытая поправка на день рождения: сотрудник, родившийся в декабре, весь год отображается на год старше.
Отдельные сложные случаи: дата рождения 29 февраля (в невисокосный год день рождения условно наступает 28 февраля или 1 марта — определите правило заранее и зафиксируйте его в функции), пустая дата рождения, дата рождения в будущем из-за ошибки ввода. Для последнего случая полезно добавить проверку: если дата рождения больше даты расчёта, возвращать признак ошибки, а не отрицательный возраст.
Ещё один риск — часовые пояса и время в дате. Если дата рождения хранится с временем, сравнение дней может сработать неожиданно. Приводите даты к началу дня функцией НачалоДня() перед сравнением.
Проверка результата
Проверяйте функцию на контрольных примерах с известным результатом. Возьмите несколько дат рождения: день рождения сегодня, день рождения завтра, 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С вычисляют, а не хранят: разность годов минус поправка на ненаступивший день рождения. В типовых конфигурациях используйте функции БСП, в запросах — РАЗНОСТЬДАТ с ВЫБОР, дату расчёта передавайте параметром и всегда обрабатывайте пустую дату рождения.