Разработка и Конфигурация · 9 мин
Как найти разницу между датами в 1С
Как найти разницу между датами в 1С: вычитание дат, функция РазностьДат, запросы с РАЗНОСТЬДАТ, разница в днях, месяцах и годах с примерами кода.
Задача вычислить разницу между двумя датами возникает в 1С постоянно: посчитать стаж сотрудника, определить просрочку оплаты по документу, рассчитать срок хранения товара или длительность отпуска. В зависимости от контекста — модуль объекта, запрос, СКД или форма — применяются разные механизмы, и у каждого есть свои особенности.
Платформа 1С:Предприятие 8 предлагает три основных подхода: простое арифметическое вычитание дат, встроенная функция РазностьДат и оператор РАЗНОСТЬДАТ в языке запросов. Простое вычитание возвращает результат в секундах, что часто становится источником ошибок, а РазностьДат и РАЗНОСТЬДАТ работают с календарными единицами — днями, месяцами, годами.
Важно понимать, что тип Дата в 1С хранит значение с точностью до секунды. Даже если в документе отображается только день, внутри может быть записано время, и это влияет на результат вычислений. Ниже разобраны все рабочие способы с примерами кода и типичными ошибками.
Вычитание дат: разница в секундах
Самая простая операция — вычесть одну дату из другой знаком минус. Результатом будет число — количество секунд между двумя моментами времени. Это поведение встроено в платформу и работает в любом модуле.
ДатаНачала = '20260101120000';
ДатаОкончания = '20260115120000';
РазницаВСекундах = ДатаОкончания - ДатаНачала; // 1209600
РазницаВДнях = РазницаВСекундах / 86400; // 14
Чтобы перевести секунды в дни, результат делят на 86400 (60 × 60 × 24). Для часов делитель — 3600, для минут — 60. Если нужно целое число дней без дробной части, используйте функцию Цел() или Окр() в зависимости от требуемого округления.
Главная ловушка этого способа — время внутри даты. Если ДатаНачала содержит 09:00, а ДатаОкончания — 18:00, то при делении получится дробное значение. Для расчётов по календарным дням даты предварительно приводят к началу дня функцией НачалоДня().
Функция РазностьДат: разница в календарных единицах
Встроенная функция РазностьДат вычисляет разницу между двумя датами в указанной единице измерения. Синтаксис: РазностьДат(Дата1, Дата2, ТипРазницы), где третий параметр — значение перечисления ТипЕдиницыИзмеренияИнтерваловДат.
РазницаВДнях = РазностьДат(ДатаНачала, ДатаОкончания,
ТипЕдиницыИзмеренияИнтерваловДат.День);
РазницаВМесяцах = РазностьДат(ДатаНачала, ДатаОкончания,
ТипЕдиницыИзмеренияИнтерваловДат.Месяц);
РазницаВГодах = РазностьДат(ДатаНачала, ДатаОкончания,
ТипЕдиницыИзмеренияИнтерваловДат.Год);
Функция считает количество целых календарных границ между датами. Например, между 31 января и 1 февраля разница в месяцах равна 1, хотя прошли всего сутки. Это важно учитывать при расчёте стажа или сроков: функция отражает календарную логику, а не фактическую длительность.
Если первая дата больше второй, результат будет отрицательным. Перед вызовом полезно проверить порядок дат сравнением или использовать Макс() и Мин(), если знак разницы не важен.
РазницаДней = РазностьДат(НачалоДня(Дата1), НачалоДня(Дата2), ТипЕдиницыИзмеренияИнтерваловДат.День);Оператор РАЗНОСТЬДАТ в запросах
В языке запросов 1С для вычисления разницы дат служит оператор РАЗНОСТЬДАТ(Дата1, Дата2, Единица). Единица задаётся ключевым словом без кавычек: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, КВАРТАЛ, ГОД.
ВЫБРАТЬ
Заказ.Ссылка КАК Заказ,
РАЗНОСТЬДАТ(Заказ.Дата, &ТекущаяДата, ДЕНЬ) КАК ДнейСМоментаЗаказа
ИЗ
Документ.ЗаказПокупателя КАК Заказ
ГДЕ
РАЗНОСТЬДАТ(Заказ.Дата, &ТекущаяДата, ДЕНЬ) > 30
Оператор удобен для отбора просроченных документов прямо в запросе, без постобработки в коде. Это быстрее, чем выгружать даты и считать разницу в цикле, особенно на больших таблицах.
Ограничение: РАЗНОСТЬДАТ нельзя применять к произвольным выражениям в некоторых контекстах, а параметр текущей даты нужно передавать в запрос явно через УстановитьПараметр — обращение к ТекущаяДатаСеанса() внутри текста запроса недоступно.
Сравнение способов
Быстро и просто, но результат в секундах; подходит только для точных интервалов и требует ручного пересчёта
Календарные единицы в коде; подходит для стажа, сроков, возраста; недоступна в запросах
Работает в запросах и СКД, позволяет фильтровать данные на стороне СУБД; требует передачи текущей даты параметром
Практические сценарии расчётов
Количество дней между датами документов
Типовая задача — посчитать просрочку оплаты: сколько дней прошло с даты отгрузки до текущего момента. Если считаете в коде, приведите обе даты к началу дня, чтобы время не искажало результат.
Функция ДнейПросрочки(ДатаОтгрузки)
Возврат РазностьДат(НачалоДня(ДатаОтгрузки),
НачалоДня(ТекущаяДатаСеанса()),
ТипЕдиницыИзмеренияИнтерваловДат.День);
КонецФункции
Возраст или стаж в годах
Для расчёта полных лет (возраст сотрудника, стаж работы) РазностьДат с единицей Год даёт количество календарных границ, что не всегда совпадает с полными годами. Надёжнее вычислить разницу в месяцах и разделить на 12 с отбрасыванием дробной части — так учитывается, наступил ли день рождения в текущем году.
МесяцевВсего = РазностьДат(ДатаРождения, ТекущаяДатаСеанса(),
ТипЕдиницыИзмеренияИнтерваловДат.Месяц);
ПолныхЛет = Цел(МесяцевВсего / 12);
Добавление интервала к дате
Обратная задача — получить дату через заданное число месяцев или дней — решается функцией ДобавитьМесяц для месяцев и сложением с секундами для дней: НоваяДата = Дата + 30 * 86400. ДобавитьМесяц корректно обрабатывает конец месяца: к 31 января плюс один месяц даст последний день февраля.
Проверка результата и типичные ошибки
После написания расчёта проверьте его на граничных случаях: одинаковые даты (результат должен быть 0), даты в обратном порядке (отрицательное значение), переход через конец месяца и через високосный год. Для отладки выводите промежуточные значения через Сообщить() или в журнал регистрации.
Отдельно проверьте поведение при пустых датах. Пустая дата в 1С — это '00010101', и разность с ней даст огромное число. Перед расчётом добавляйте проверку ЗначениеЗаполнено(Дата) или сравнение с '00010101'.
Как проверить результат
Разница равна 0 в любой единице
Ненулевое значение — где-то подмешалось время
Отрицательное число или контролируемая обработка
Ошибка или неожиданно большое положительное число
Расчёт пропущен или возвращён 0 по условию
Результат в сотни тысяч дней
31.01 + 1 месяц = конец февраля
Дата сдвинута на 30 фиксированных дней
Часто задаваемые вопросы
Как получить разницу между датами в днях в запросе 1С?
Используйте РАЗНОСТЬДАТ(Дата1, Дата2, ДЕНЬ) в секции ВЫБРАТЬ или ГДЕ. Текущую дату передавайте параметром через Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДатаСеанса()), так как в тексте запроса функции встроенного языка недоступны.
Почему при вычитании дат получается большое число?
Результат вычитания двух дат — это секунды, а не дни. Разделите значение на 86400, чтобы получить дни. Если число огромное даже после деления, проверьте, не участвует ли в расчёте пустая дата '00010101'.
Как посчитать полные года между датами (возраст, стаж)?
Вычислите разницу в месяцах через РазностьДат с единицей Месяц и разделите на 12 с помощью Цел(). Это надёжнее, чем единица Год, которая считает календарные границы и может завысить результат, если день рождения в текущем году ещё не наступил.
Можно ли использовать РазностьДат в СКД?
В вычисляемых полях СКД доступен язык выражений компоновки, где РазностьДат поддерживается с теми же параметрами. В тексте запроса источника данных применяйте РАЗНОСТЬДАТ — это эффективнее, так как расчёт выполняется на стороне СУБД.
Как прибавить к дате несколько месяцев?
Используйте ДобавитьМесяц(Дата, КоличествоМесяцев) — функция корректно обрабатывает конец месяца и високосные годы. Для дней и часов простое сложение с секундами допустимо: Дата + КоличествоДней * 86400.
Чем отличается ТекущаяДата() от ТекущаяДатаСеанса()?
ТекущаяДата() работает только на клиенте и возвращает время компьютера пользователя. ТекущаяДатаСеанса() доступна и на сервере, и на клиенте, возвращает время сеанса с учётом часового пояса информационной базы — для расчётов на сервере используйте именно её.
Что важно запомнить
Вычитание дат даёт секунды, РазностьДат — календарные единицы в коде, РАЗНОСТЬДАТ — то же в запросах. Приводите даты к началу дня, проверяйте пустые значения и используйте ТекущаяДатаСеанса() на сервере.