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