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

Разработка и Конфигурация · 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, хотя прошли всего сутки. Это важно учитывать при расчёте стажа или сроков: функция отражает календарную логику, а не фактическую длительность.

Если первая дата больше второй, результат будет отрицательным. Перед вызовом полезно проверить порядок дат сравнением или использовать Макс() и Мин(), если знак разницы не важен.

bsl
РазницаДней = РазностьДат(НачалоДня(Дата1), НачалоДня(Дата2), ТипЕдиницыИзмеренияИнтерваловДат.День);

Оператор РАЗНОСТЬДАТ в запросах

В языке запросов 1С для вычисления разницы дат служит оператор РАЗНОСТЬДАТ(Дата1, Дата2, Единица). Единица задаётся ключевым словом без кавычек: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, КВАРТАЛ, ГОД.

ВЫБРАТЬ

Заказ.Ссылка КАК Заказ,

РАЗНОСТЬДАТ(Заказ.Дата, &ТекущаяДата, ДЕНЬ) КАК ДнейСМоментаЗаказа

ИЗ

Документ.ЗаказПокупателя КАК Заказ

ГДЕ

РАЗНОСТЬДАТ(Заказ.Дата, &ТекущаяДата, ДЕНЬ) > 30

Оператор удобен для отбора просроченных документов прямо в запросе, без постобработки в коде. Это быстрее, чем выгружать даты и считать разницу в цикле, особенно на больших таблицах.

Ограничение: РАЗНОСТЬДАТ нельзя применять к произвольным выражениям в некоторых контекстах, а параметр текущей даты нужно передавать в запрос явно через УстановитьПараметр — обращение к ТекущаяДатаСеанса() внутри текста запроса недоступно.

Сравнение способов

Вычитание дат

Быстро и просто, но результат в секундах; подходит только для точных интервалов и требует ручного пересчёта

РазностьДат

Календарные единицы в коде; подходит для стажа, сроков, возраста; недоступна в запросах

РАЗНОСТЬДАТ

Работает в запросах и СКД, позволяет фильтровать данные на стороне СУБД; требует передачи текущей даты параметром

Практические сценарии расчётов

Количество дней между датами документов

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

Функция ДнейПросрочки(ДатаОтгрузки)

Возврат РазностьДат(НачалоДня(ДатаОтгрузки),

НачалоДня(ТекущаяДатаСеанса()),

ТипЕдиницыИзмеренияИнтерваловДат.День);

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

Возраст или стаж в годах

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

МесяцевВсего = РазностьДат(ДатаРождения, ТекущаяДатаСеанса(),

ТипЕдиницыИзмеренияИнтерваловДат.Месяц);

ПолныхЛет = Цел(МесяцевВсего / 12);

Добавление интервала к дате

Обратная задача — получить дату через заданное число месяцев или дней — решается функцией ДобавитьМесяц для месяцев и сложением с секундами для дней: НоваяДата = Дата + 30 * 86400. ДобавитьМесяц корректно обрабатывает конец месяца: к 31 января плюс один месяц даст последний день февраля.

Проверка результата и типичные ошибки

После написания расчёта проверьте его на граничных случаях: одинаковые даты (результат должен быть 0), даты в обратном порядке (отрицательное значение), переход через конец месяца и через високосный год. Для отладки выводите промежуточные значения через Сообщить() или в журнал регистрации.

Отдельно проверьте поведение при пустых датах. Пустая дата в 1С — это '00010101', и разность с ней даст огромное число. Перед расчётом добавляйте проверку ЗначениеЗаполнено(Дата) или сравнение с '00010101'.

Типичные ошибки
01
Деление секунд на 2592000 для получения месяцев — месяцы разной длины, результат неточен; используйте РазностьДат
02
Игнорирование времени внутри даты — дробные дни и неверное округление; приводите даты через НачалоДня
03
Расчёт с пустой датой '00010101' — получается огромное число; проверяйте заполненность
04
Использование ТекущаяДата() на сервере — ошибка компиляции; применяйте ТекущаяДатаСеанса()
05
Ожидание полных лет от РазностьДат с единицей Год — функция считает календарные границы, а не полные периоды
Контрольные точки

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

Одинаковые даты на входе
Норма

Разница равна 0 в любой единице

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

Ненулевое значение — где-то подмешалось время

Даты в обратном порядке
Норма

Отрицательное число или контролируемая обработка

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

Ошибка или неожиданно большое положительное число

Пустая дата
Норма

Расчёт пропущен или возвращён 0 по условию

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

Результат в сотни тысяч дней

Переход через конец месяца
Норма

31.01 + 1 месяц = конец февраля

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

Дата сдвинута на 30 фиксированных дней

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

Как получить разницу между датами в днях в запросе 1С?

Используйте РАЗНОСТЬДАТ(Дата1, Дата2, ДЕНЬ) в секции ВЫБРАТЬ или ГДЕ. Текущую дату передавайте параметром через Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДатаСеанса()), так как в тексте запроса функции встроенного языка недоступны.

Почему при вычитании дат получается большое число?

Результат вычитания двух дат — это секунды, а не дни. Разделите значение на 86400, чтобы получить дни. Если число огромное даже после деления, проверьте, не участвует ли в расчёте пустая дата '00010101'.

Как посчитать полные года между датами (возраст, стаж)?

Вычислите разницу в месяцах через РазностьДат с единицей Месяц и разделите на 12 с помощью Цел(). Это надёжнее, чем единица Год, которая считает календарные границы и может завысить результат, если день рождения в текущем году ещё не наступил.

Можно ли использовать РазностьДат в СКД?

В вычисляемых полях СКД доступен язык выражений компоновки, где РазностьДат поддерживается с теми же параметрами. В тексте запроса источника данных применяйте РАЗНОСТЬДАТ — это эффективнее, так как расчёт выполняется на стороне СУБД.

Как прибавить к дате несколько месяцев?

Используйте ДобавитьМесяц(Дата, КоличествоМесяцев) — функция корректно обрабатывает конец месяца и високосные годы. Для дней и часов простое сложение с секундами допустимо: Дата + КоличествоДней * 86400.

Чем отличается ТекущаяДата() от ТекущаяДатаСеанса()?

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

Итог

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

Вычитание дат даёт секунды, РазностьДат — календарные единицы в коде, РАЗНОСТЬДАТ — то же в запросах. Приводите даты к началу дня, проверяйте пустые значения и используйте ТекущаяДатаСеанса() на сервере.