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

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

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

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

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

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

Вычитание дат оператором «минус» и результат в секундах

Самый прямой способ — вычесть одну дату из другой обычным арифметическим оператором. В 1С дата хранится как количество секунд от начала отсчёта, поэтому результатом вычитания будет число — разница в секундах.

ДатаНачала = '20260115100000';

ДатаОкончания = '20260120123000';

РазницаВСекундах = ДатаОкончания - ДатаНачала; // число секунд

РазницаВДнях = РазницаВСекундах / 86400; // 86400 = 60*60*24

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

Обратите внимание: если вычесть из меньшей даты большую, результат будет отрицательным. Перед расчётом полезно проверять порядок дат через простое сравнение Если ДатаОкончания < ДатаНачала Тогда.

Функция РазностьДат: разница в днях, месяцах и годах

Для календарных вычислений во встроенном языке 1С предназначена функция РазностьДат(). Она принимает три параметра: начальную дату, конечную дату и тип единицы измерения из перечисления ТипЕдиницыИзмеренияПериодов.

КоличествоДней = РазностьДат(ДатаНачала, ДатаОкончания,

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

КоличествоМесяцев = РазностьДат(ДатаНачала, ДатаОкончания,

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

КоличествоЛет = РазностьДат(ДатаНачала, ДатаОкончания,

ТипЕдиницыИзмеренияПериодов.Год);

Доступны единицы: Секунда, Минута, Час, День, Месяц, Квартал, Год. Функция возвращает целое число полных единиц, укладывающихся между датами. Например, между 15 января и 14 марта разность в месяцах будет равна 1, а не 2, потому что полных двух месяцев не прошло.

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

bsl
ПолныхЛет = РазностьДат(ДатаРождения, ТекущаяДатаСеанса(), ТипЕдиницыИзмеренияПериодов.Год);

Разница между датами в запросах 1С

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

ВЫБРАТЬ

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

РАЗНОСТЬДАТ(Заказ.ДатаОтгрузки, Заказ.ДатаОплаты, ДЕНЬ) КАК ДнейПросрочки

ИЗ

Документ.ЗаказКлиента КАК Заказ

Единицы измерения в запросе задаются ключевыми словами: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, КВАРТАЛ, ГОД. Результат — целое число полных единиц, как и у функции встроенного языка.

Поле с разностью дат можно использовать в условии через вычисляемое выражение, но чаще разность считают в выборке, а фильтрацию выполняют уже по результату — например, в конструкторе СКД или при обходе результата запроса. Помните, что если одна из дат в запросе равна NULL, результат тоже будет NULL, поэтому для необязательных полей стоит применять ЕСТЬNULL.

Расчёт точного возраста и стажа: полные годы, месяцы и дни

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

Функция ВозрастТекстом(ДатаРождения, НаДату)

Лет = РазностьДат(ДатаРождения, НаДату,

ТипЕдиницыИзмеренияПериодов.Год);

ПромежуточнаяДата = ДобавитьМесяц(ДатаРождения, Лет * 12);

Месяцев = РазностьДат(ПромежуточнаяДата, НаДату,

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

ПромежуточнаяДата = ДобавитьМесяц(ПромежуточнаяДата, Месяцев);

Дней = РазностьДат(ПромежуточнаяДата, НаДату,

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

Возврат СтрШаблон("%1 г. %2 мес. %3 дн.", Лет, Месяцев, Дней);

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

Функция ДобавитьМесяц() корректно обрабатывает переходы через границы месяцев и лет, поэтому ручные манипуляции с числами месяца не нужны. Для кадровых расчётов стажа в типовых конфигурациях есть готовые механизмы, но принцип тот же.

Порядок расчёта разности дат
  1. 1
    Определите, где выполняется расчёт: в коде модуля или в запросе
  2. 2
    Выберите способ: оператор «-» для секунд, РазностьДат для календарных единиц, РАЗНОСТЬДАТ для запроса
  3. 3
    Проверьте, что конечная дата не раньше начальной, иначе результат будет отрицательным
  4. 4
    Убедитесь, что обе переменные имеют тип Дата, а не строка или NULL
  5. 5
    Проверьте результат на контрольном примере с известной разницей

Типичные ошибки при вычитании дат

Самая распространённая ошибка — ожидать от оператора «минус» количество дней. Результат в секундах затем ошибочно подставляется в условия вида «просрочка больше 30», хотя сравнивать нужно с 30 × 86400 секунд или использовать РазностьДат.

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

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

Типичные ошибки
01
Использование результата вычитания в секундах как количества дней — условия и отчёты показывают неверные значения
02
Игнорирование времени в составе даты — разница в днях «плывёт» на единицу, лечится через НачалоДня()
03
Отсутствие проверки на пустую дату — результат становится огромным числом или NULL в запросе
04
Ожидание дробного результата от РазностьДат — функция всегда возвращает целое число полных единиц

Проверка результата и выбор подходящего способа

Проверить корректность расчёта проще всего на контрольном примере: возьмите две даты, разницу между которыми легко посчитать вручную, например 1 января и 1 февраля одного года. Разность в днях должна быть 31, в месяцах — 1.

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

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

Оператор «-»

Подходит для точной длительности в секундах; неудобен для календарных расчётов

РазностьДат()

Основной способ в коде: дни, месяцы, годы; возвращает только целые единицы

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

Единственный вариант в языке запросов; требует обработки NULL через ЕСТЬNULL

ДобавитьМесяц + РазностьДат

Комбинация для точного расчёта лет, месяцев и дней, например возраста или стажа

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

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

Разность между 01.01 и 01.02 одного года
Норма

31 день, 1 месяц

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

30 дней или 0 месяцев — ошибка в единицах

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

Результат 0

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

Отрицательное или большое число

Дата с пустым значением
Норма

Расчёт пропущен проверкой ЗначениеЗаполнено

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

Огромное число дней или NULL в отчёте

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

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

Используйте РазностьДат(Дата1, Дата2, ТипЕдиницыИзмеренияПериодов.День). Если нужна разница с учётом времени, вычтите даты оператором «минус» и разделите результат на 86400.

Почему вычитание дат возвращает огромное число?

Оператор «минус» возвращает секунды, а не дни. Также проверьте, не пустая ли одна из дат: пустая дата равна 01.01.0001, и разница с ней исчисляется сотнями тысяч дней.

Как вычесть даты в запросе 1С?

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

Как посчитать полный возраст в годах?

Примените РазностьДат с единицей Год: функция вернёт только полные годы, поэтому день рождения, который ещё не наступил в текущем году, учтён не будет.

Что делать, если даты содержат время, а нужны только календарные дни?

Приведите обе даты к началу дня функцией НачалоДня() перед вычитанием. Тогда время не повлияет на результат, и разница в днях будет точной.

Может ли разность дат быть отрицательной?

Да, если конечная дата раньше начальной. Перед расчётом сравните даты и при необходимости поменяйте их местами или выведите предупреждение пользователю.

Итог

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

В коде 1С используйте оператор «-» для секунд и РазностьДат() для дней, месяцев и лет; в запросах — РАЗНОСТЬДАТ. Всегда проверяйте порядок дат, заполненность значений и наличие времени в составе даты.