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

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

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

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

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

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

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

Определите, какие именно дни нужно посчитать

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

Разница «включительно или нет» — источник большинства расхождений. Например, период с 1 по 10 марта при простом вычитании даст 9 дней, а при подсчёте «включая обе даты» — 10. В кадровых документах (отпуска, больничные) обычно считают включительно, в расчётах просрочки — часто со следующего дня после срока оплаты.

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

Способ 1: вычитание дат во встроенном языке

Самый простой способ — вычесть одну дату из другой. В 1С результатом вычитания дат является разность в секундах. Чтобы получить дни, результат делят на 86400 (60 × 60 × 24):

ДатаНачала = НачалоДня(ДатаНачала);

ДатаОкончания = НачалоДня(ДатаОкончания);

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

Если нужно включить обе граничные даты, добавьте единицу: КоличествоДней = (ДатаОкончания - ДатаНачала) / 86400 + 1;. Перед делением убедитесь, что даты приведены к началу дня, иначе получите дробное значение.

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

1c
КоличествоДней = (НачалоДня(ДатаОкончания) - НачалоДня(ДатаНачала)) / 86400; // календарные дни без учёта границ

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

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

ВЫБРАТЬ

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

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

ИЗ

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

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

Если одна из дат может быть пустой (01.01.0001), результат получится некорректным. Добавьте в запрос условие или конструкцию ВЫБОР, отсекающую пустые даты, иначе получите огромные числа, которые испортят отчёт.

Способ 3: рабочие дни через календарные графики

Арифметикой рабочие дни не посчитать: праздники, переносы выходных и разные графики делают простую формулу бессмысленной. В типовых конфигурациях (БП, ЗУП, ERP) для этого есть производственные календари и календарные графики, хранящиеся в регистрах сведений.

Общий подход: сделать запрос к регистру календарного графика, отобрать даты в нужном периоде, где день помечен как рабочий, и посчитать их количество. В конфигурациях на БСП есть готовые функции общего модуля «КалендарныеГрафики», например получение разности дат в рабочих днях по заданному графику.

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

Порядок расчёта рабочих дней
  1. 1
    Убедитесь, что производственный календарь заполнен на весь период расчёта
  2. 2
    Определите, какой график используется: общий календарь или график организации
  3. 3
    Вызовите функцию разности дат по графику (в БСП — модуль КалендарныеГрафики) или постройте запрос к регистру графика
  4. 4
    Проверьте результат на коротком периоде с известным числом рабочих дней
  5. 5
    Обработайте ситуацию, когда календарь не заполнен: выведите понятное сообщение

Прикладные сценарии: просрочка, стаж, сроки доставки

Просрочка оплаты

Просрочка обычно считается от дня, следующего за крайней датой оплаты, до даты фактической оплаты или текущей даты. Формула: ДнейПросрочки = (НачалоДня(ДатаОтсчета) - НачалоДня(СрокОплаты)) / 86400;, где ДатаОтсчета — дата оплаты или ТекущаяДатаСеанса(). Отрицательный и нулевой результат означает, что просрочки нет.

Стаж и возраст

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

Сроки доставки и выполнения

Здесь чаще нужна обратная задача: прибавить к дате N рабочих дней и получить дату результата. Для этого используют функции сдвига даты по календарному графику. Простое прибавление Дата + N * 86400 корректно только для календарных дней.

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

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

Быстро и просто для календарных дней; не подходит для рабочих дней и массовых выборок

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

Оптимально для отчётов и больших выборок; требует контроля пустых дат и времени

Календарные графики

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

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

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

Проверьте граничные случаи: одинаковые даты (результат 0 или 1 в зависимости от логики), период через високосный февраль, период через новый год, пустые даты. Именно на границах всплывают ошибки округления и незаполненных календарей.

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

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

Период 1–10 число одного месяца
Норма

9 дней разности или 10 включительно

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

Дробное число или смещение на день

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

5 рабочих дней при пятидневке

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

7 дней или ноль

Пустая дата в запросе
Норма

Запись отфильтрована или обработана

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

Огромные значения в отчёте

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

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

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

Почему разность дат даёт дробное число?

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

Как прибавить к дате 10 рабочих дней?

Простым прибавлением секунд это не сделать. Используйте функции работы с календарными графиками (в конфигурациях на БСП — общий модуль КалендарныеГрафики), которые сдвигают дату с учётом производственного календаря.

РАЗНОСТЬДАТ возвращает странно большие числа — в чём причина?

Чаще всего одна из дат пустая (01.01.0001). Разность между пустой и реальной датой — тысячи дней. Добавьте в запрос проверку на пустую дату через ВЫБОР или отбор.

Как считать стаж в годах, месяцах и днях?

Одной функцией это не решается из-за разной длины месяцев. В ЗУП используйте штатные механизмы учёта стажей; в собственных разработках считайте последовательно полные годы, затем полные месяцы остатка, затем дни.

Итог

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

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