Разработка и Конфигурация · 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. Для расчётов «с округлением вверх» добавляйте корректировку в выражении или обрабатывайте результат уже в коде.
Сравнение вариантов
Подходит для простого расчёта календарных дней в коде. Ограничение: дробный результат при наличии времени, нужно обрезать через НачалоДня.
Подходит для типовых конфигураций, единая логика во всех модулях. Ограничение: состав функций зависит от версии БСП.
Подходит для отчётов и отборов без выгрузки данных в код. Ограничение: считает только полные единицы, нет учёта рабочих дней.
Единственный корректный способ считать рабочие дни. Ограничение: требует заполненного календаря и зависит от конфигурации.
Добавление дней к дате и обратная задача
Обратная задача — определить дату, которая наступит через заданное число дней. Встроенная функция ДобавитьКДате() (в новых версиях платформы) или простое сложение с секундами решают её для календарных дней:
ДатаОплаты = ДатаДокумента + 10 * 86400; // +10 календарных дней
Для рабочих дней сложение не сработает: нужно итеративно идти по календарю, пропуская выходные и праздники, либо использовать типовые процедуры из модулей работы с графиками. В ЗУП и ERP для этого есть готовые функции, например определение даты по графику работы сотрудника или организации.
- 1Определите, какие дни нужны: календарные или рабочие по графику.
- 2Для календарных дней используйте (НачалоДня(Дата2) - НачалоДня(Дата1)) / 86400.
- 3Для рабочих дней постройте запрос к регистру производственного календаря.
- 4Проверьте, нужно ли включать обе граничные даты — при необходимости добавьте 1.
- 5Протестируйте расчёт на граничных случаях: одинаковые даты, переход через месяц и год, даты с временем.
Проверка результата и типичные ошибки
После внедрения расчёта проверьте его на контрольных примерах с известным ответом. Удобные тестовые пары: разница между 01.01 и 02.01 (1 день), между 28.02 и 01.03 в високосном и обычном годах (2 и 1 день соответственно), одинаковые даты (0 или 1 в зависимости от логики включения границ).
Ошибки в расчёте дат опасны тем, что не вызывают падения кода — программа работает, но начисляет неверные суммы. Поэтому для финансовых расчётов (пени, проценты по договорам, отпускные) обязательно согласуйте правило учёта граничных дней с методологами или бухгалтерией до написания кода.
Как проверить результат
Результат равен 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 и обрезайте время через НачалоДня. Для рабочих дней используйте только производственный календарь и следите за его заполнением. Граничные даты, високосные годы и правило включения последнего дня проверяйте на контрольных примерах до запуска расчёта в работу.