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

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

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

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

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

Самый простой способ — обычное вычитание дат, но у него есть важная особенность: результат получается в секундах, а не в днях. Для корректного результата используют функцию РазностьДат из общих модулей БСП либо пересчитывают секунды в дни вручную. Ниже разобраны все рабочие варианты с примерами кода, ограничениями и типичными ошибками.

Способ 1. Вычитание дат с пересчётом секунд в дни

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

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

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

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

КоличествоДней = РазностьВСекундах / 86400; // 26

Если даты содержат время, результат может оказаться дробным. Например, разница между 15.01.2026 10:00:00 и 17.01.2026 16:00:00 даст 2,25 дня. Если нужны целые календарные дни, предварительно обрежьте время функцией НачалоДня():

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

Обратите внимание: разность между началом дня 15 января и началом дня 17 января равна 2, хотя «включительно» дат три. Если по логике задачи обе граничные даты должны учитываться (например, период отпуска с 15 по 17 января — это 3 дня), добавьте к результату единицу.

Способ 2. Функция РазностьДат из БСП

В конфигурациях на базе Библиотеки стандартных подсистем (УТ 11, ERP, Бухгалтерия 3.0, ЗУП 3.1 и других) доступна функция ОбщегоНазначения.РазностьДат() или аналогичные процедуры в модуле КалендарныеДаты. Она возвращает разность в заданных единицах и корректно работает с границами периодов.

Также в типовых конфигурациях встречается функция из модуля работы с датами:

КоличествоДней = КалендарныеДаты.РазностьДат(ДатаНачала, ДатаОкончания);

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

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

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

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(Календарь.ДатаКалендаря) КАК РабочихДней

|ИЗ

| РегистрСведений.ДанныеПроизводственногоКалендаря КАК Календарь

|ГДЕ

| Календарь.ДатаКалендаря МЕЖДУ &ДатаНачала И &ДатаОкончания

| И Календарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)";

Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);

Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания);

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

Способ 4. Расчёт в запросе функцией РАЗНОСТЬДАТ

Язык запросов 1С имеет собственную функцию РАЗНОСТЬДАТ(Дата1, Дата2, Единица), которая возвращает разность в секундах, минутах, часах, днях, месяцах и годах. Это удобно, когда расчёт нужен прямо в выборке, например для отчёта по просроченной задолженности:

ВЫБРАТЬ

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

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

ИЗ

Документ.РеализацияТоваровУслуг КАК Заказы

ГДЕ

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

Учтите, что РАЗНОСТЬДАТ в запросе считает по полным единицам: разница в 1 день и 23 часа при единице ДЕНЬ даст 1, а не 2. Для расчётов «с округлением вверх» добавляйте корректировку в выражении или обрабатывайте результат уже в коде.

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

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

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

РазностьДат из БСП

Подходит для типовых конфигураций, единая логика во всех модулях. Ограничение: состав функций зависит от версии БСП.

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

Подходит для отчётов и отборов без выгрузки данных в код. Ограничение: считает только полные единицы, нет учёта рабочих дней.

Запрос к производственному календарю

Единственный корректный способ считать рабочие дни. Ограничение: требует заполненного календаря и зависит от конфигурации.

Добавление дней к дате и обратная задача

Обратная задача — определить дату, которая наступит через заданное число дней. Встроенная функция ДобавитьКДате() (в новых версиях платформы) или простое сложение с секундами решают её для календарных дней:

ДатаОплаты = ДатаДокумента + 10 * 86400; // +10 календарных дней

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

Порядок действий для типовой задачи
  1. 1
    Определите, какие дни нужны: календарные или рабочие по графику.
  2. 2
    Для календарных дней используйте (НачалоДня(Дата2) - НачалоДня(Дата1)) / 86400.
  3. 3
    Для рабочих дней постройте запрос к регистру производственного календаря.
  4. 4
    Проверьте, нужно ли включать обе граничные даты — при необходимости добавьте 1.
  5. 5
    Протестируйте расчёт на граничных случаях: одинаковые даты, переход через месяц и год, даты с временем.

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

После внедрения расчёта проверьте его на контрольных примерах с известным ответом. Удобные тестовые пары: разница между 01.01 и 02.01 (1 день), между 28.02 и 01.03 в високосном и обычном годах (2 и 1 день соответственно), одинаковые даты (0 или 1 в зависимости от логики включения границ).

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

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

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

Разница между соседними днями
Норма

Результат равен 1 (или 2 при включении обеих границ)

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

86400, 0 или дробное число

Переход через високосный февраль
Норма

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

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

Разница на день меньше ожидаемой

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

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

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

7 дней — считаются календарные, 0 — календарь пуст

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

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

Потому что результат вычитания дат в 1С — это секунды, а не дни. Разделите значение на 86400, чтобы получить дни. Если нужны целые дни без влияния времени, предварительно примените НачалоДня() к обеим датам.

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

Рассчитайте обычную разность между началами дней и прибавьте единицу: (НачалоДня(Дата2) - НачалоДня(Дата1)) / 86400 + 1. Так период с 15 по 17 января даст 3 дня. Правило включения границ согласуйте с методологией конкретного расчёта.

Как учесть только рабочие дни между датами?

Простым вычитанием это не решается. Нужен запрос к регистру производственного календаря с отбором по виду дня «Рабочий» за нужный период. Проверьте, что календарь заполнен на весь расчётный интервал, иначе результат будет занижен.

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

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

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

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

Расчёт работал, а в январе стал возвращать ноль. В чём причина?

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

Итог

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

Вычитание дат в 1С даёт секунды — делите на 86400 и обрезайте время через НачалоДня. Для рабочих дней используйте только производственный календарь и следите за его заполнением. Граничные даты, високосные годы и правило включения последнего дня проверяйте на контрольных примерах до запуска расчёта в работу.