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

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

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

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

Задача вычислить количество дней между двумя датами возникает в 1С постоянно: при расчёте сроков оплаты, стажа, просрочки по договору, длительности отпуска или отгрузки. У этой задачи есть несколько решений, и выбор зависит от того, где выполняется расчёт — в коде встроенного языка, в запросе или в СКД — и какие именно дни нужны: календарные или рабочие.

Ключевой момент, который часто упускают: в 1С дата хранится с точностью до секунды, поэтому «наивное» вычитание дат даёт результат в секундах, а не в днях. Если не учесть это, легко получить значение в 86400 раз больше ожидаемого или дробное число при разном времени в датах.

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

Вычитание дат в коде: базовый способ

Самый простой метод — вычесть одну дату из другой. Результат операции «Дата1 - Дата2» во встроенном языке 1С — это число секунд между моментами времени. Чтобы получить дни, результат делят на 86400 (количество секунд в сутках).

Пример кода:

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

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

КоличествоДней = (ДатаОкончания - ДатаНачала) / 86400;

// Результат: 15

Важно понимать семантику: так считается разность между моментами, то есть сколько полных суток прошло с одной даты до другой. Если даты включают время, результат может быть дробным. Например, разница между 10.01.2026 15:00:00 и 12.01.2026 09:00:00 составит 1,75 дня. Для целочисленного результата применяют Цел() или Окр() в зависимости от бизнес-логики.

Если нужно посчитать дни «включительно» (например, период с 10 по 15 января — это 6 календарных дней, а не 5), к результату прибавляют единицу. Это частый источник расхождений с расчётами «на бумаге», поэтому правило включения границ должно быть зафиксировано в требованиях.

bsl
КоличествоДней = Цел((КонецДня(ДатаОкончания) - НачалоДня(ДатаНачала)) / 86400) + 1;

Функция РАЗНОСТЬДАТ в запросе

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

Пример запроса:

ВЫБРАТЬ

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

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

ИЗ

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

ГДЕ

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

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

Нюанс: если в поле даты хранится пустая дата (01.01.0001), РАЗНОСТЬДАТ вернёт огромное число, которое «загрязнит» отчёт. Такие случаи отсекают условием вида «Заказ.ДатаОтгрузки <> ДАТАВРЕМЯ(1,1,1)» или через ВЫБОР с проверкой.

Расчёт рабочих дней по производственному календарю

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

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

Пример логики запроса: выбрать из регистра строки, где дата попадает в интервал, и вид дня — рабочий (или предпраздничный, если он считается), затем посчитать количество строк через КОЛИЧЕСТВО. Если в вашей конфигурации используется поле «ВидДня» со ссылкой на перечисление, отбор строится по нему.

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

Сравнение вариантов

Вычитание дат в коде

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

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

Удобно для отчётов и отборов; считает только полные единицы, чувствительна к пустым датам

Производственный календарь

Единственный корректный способ для рабочих дней; требует заполненного календаря на нужный период

Цикл с ДеньНедели()

Подходит для грубой оценки без календаря; игнорирует праздники и переносы

Обратная задача: прибавить дни к дате

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

Первый — арифметика с секундами: НоваяДата = ИсходнаяДата + N * 86400. Способ работает, но при прибавлении месяцев или лет ведёт себя неочевидно из-за разной длины месяцев.

Второй — функция ДобавитьКДате(Дата, Тип, Количество), которая корректно работает с месяцами, кварталами и годами: ДобавитьКДате(ДатаНачала, "Месяц", 3). Для дней оба способа эквивалентны, но ДобавитьКДате читается лучше и единообразна для любых единиц.

В запросах аналог — функция ДОБАВИТЬКДАТЕ(Дата, ДЕНЬ, N). Она полезна, когда нужно отобрать документы, у которых срок наступает в ближайшие N дней, без выгрузки данных в код.

Порядок действий для расчёта рабочих дней
  1. 1
    Убедитесь, что производственный календарь заполнен на весь нужный период
  2. 2
    Напишите запрос к регистру данных календаря с отбором по интервалу дат
  3. 3
    Добавьте условие на вид дня: только рабочие (и предпраздничные, если требуется)
  4. 4
    Используйте КОЛИЧЕСТВО для подсчёта строк результата
  5. 5
    Проверьте расчёт на коротком периоде с известным количеством рабочих дней

Типичные ошибки и как их избежать

Самая распространённая ошибка — забыть разделить разность дат на 86400 и использовать секунды как дни. Внешне это проявляется как огромные числа в отчётах, и замечают её обычно сразу. Коварнее ситуация с дробными днями: если время в датах не совпадает, Цел() отбрасывает часть суток, и итог расходится на день с расчётом пользователя.

Вторая группа ошибок связана с границами периода. Один разработчик считает период «с 1 по 10 число» как 9 дней (разность), другой — как 10 (включительно). Перед реализацией уточните у постановщика задачи, включается ли последний день, и зафиксируйте это в комментарии к коду.

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

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

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

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

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

Для расчётов по производственному календарю дополнительно проверьте, что календарь заполнен на весь анализируемый период. Незаполненный календарь на будущий год — типовая причина, почему «вдруг» перестали считаться сроки в январе.

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

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

Разность дат в коде
Норма

Целое число дней, совпадающее с ручным подсчётом по календарю

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

Число в десятки тысяч раз больше ожидаемого — забыто деление на 86400

Расчёт в запросе
Норма

Нет строк с аномально большими значениями, пустые даты отфильтрованы

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

Значения в тысячи дней — в выборку попала пустая дата 01.01.0001

Рабочие дни по календарю
Норма

Для недели без праздников результат 5, для праздничного периода — меньше или 0

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

Результат равен календарным дням — календарь не заполнен или неверный отбор по виду дня

Граничные случаи
Норма

Одинаковые даты и обратный порядок дат обрабатываются предсказуемо

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

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

Частые вопросы

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

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

Чем отличается РАЗНОСТЬДАТ от простого вычитания дат?

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

Как учесть, что последний день периода тоже входит в расчёт?

Прибавьте единицу к результату разности: период с 10 по 15 число при включении обеих границ составляет 6 дней, а не 5. Главное — согласовать это правило с постановщиком задачи и применять единообразно во всех расчётах.

Почему расчёт рабочих дней вдруг перестал работать в новом году?

Наиболее вероятная причина — производственный календарь не заполнен на новый период. Проверьте наличие записей в регистре данных календаря на нужные даты и заполните календарь штатной обработкой конфигурации.

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

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

Как прибавить к дате несколько рабочих дней, а не календарных?

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

Итог

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

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