Разработка и Конфигурация · 10 мин
Как посчитать количество дней в периоде в 1С
Как посчитать количество дней в периоде в 1С: функция РазностьДат, вычитание дат в запросе, расчёт календарных и рабочих дней, типовые ошибки и примеры кода.
Задача посчитать количество дней между двумя датами возникает в 1С постоянно: при расчёте сроков оплаты договоров, отпусков, больничных, просрочки задолженности, сроков годности товара. Способ решения зависит от того, где выполняется расчёт — в коде на встроенном языке, в запросе или в СКД — и от того, нужны календарные дни или рабочие.
В простейшем случае достаточно арифметики: дата в 1С хранится с точностью до секунды, поэтому разность двух дат даёт количество секунд, которое делится на 86400. Для расчётов в запросах используется функция РАЗНОСТЬДАТ, а для рабочих дней по производственному календарю — регистры сведений с графиками. Ниже разобраны все основные сценарии с примерами кода.
Как 1С хранит даты и почему это важно для расчёта
Значение типа «Дата» в платформе 1С хранит момент времени с точностью до секунды. Даже если в документе дата выглядит как «15.03.2026», внутри она содержит время — чаще всего 00:00:00, но не всегда: у документов дата включает время проведения, у текущей даты сеанса — реальное время.
Из-за этого прямое вычитание дат может давать неожиданный результат. Разность между 15.03.2026 14:30:00 и 10.03.2026 09:00:00 составит 5 дней и 5,5 часов, то есть 449 400 секунд. При делении на 86400 получится 5,2 — дробное число, которое нужно осознанно округлять или отсекать.
Если время не имеет значения, перед расчётом даты приводят к началу дня функцией НачалоДня(). Это убирает влияние времени и делает результат предсказуемым целым числом.
Расчёт количества дней в коде на встроенном языке
Базовый вариант — вычитание двух дат и деление на количество секунд в сутках. Чтобы избежать дробных значений, даты предварительно нормализуют:
ДатаНачала = НачалоДня(Дата("20260310"));
ДатаОкончания = НачалоДня(Дата("20260315"));
КоличествоДней = (ДатаОкончания - ДатаНачала) / 86400;
// Результат: 5
Обратите внимание: разность между 10 и 15 марта равна 5, а не 6. Если по бизнес-логике обе граничные даты должны входить в период (например, отпуск с 10 по 15 марта — это 6 календарных дней), к результату нужно прибавить единицу:
КоличествоДнейВключительно = (НачалоДня(ДатаОкончания) - НачалоДня(ДатаНачала)) / 86400 + 1;
Вопрос «включать ли границы» — самая частая причина расхождений с ожиданиями пользователей. Уточните требование заранее и зафиксируйте его в комментарии к коду, чтобы при доработках логика не «поплыла».
Как выбрать формулу
Расчёт дней в запросе: функция РАЗНОСТЬДАТ
В языке запросов 1С для вычисления разности дат предназначена функция РАЗНОСТЬДАТ. Она принимает три аргумента: начальную дату, конечную дату и единицу измерения — СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, ГОД.
ВЫБРАТЬ
Реализация.Ссылка КАК Документ,
РАЗНОСТЬДАТ(Реализация.Дата, &ТекущаяДата, ДЕНЬ) КАК ДнейСОтгрузки
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Проведен
Функция считает количество полных единиц между датами. Например, РАЗНОСТЬДАТ в днях между 10.03.2026 23:00 и 11.03.2026 01:00 вернёт 0, потому что полные сутки ещё не прошли. Это поведение отличается от деления секунд на 86400 с округлением — учитывайте его при сопоставлении результатов запроса и кода.
Если нужно посчитать дни между датами в разных строках или таблицах, соедините таблицы в запросе и примените РАЗНОСТЬДАТ к полям обеих. Для сложных условий результат удобно обернуть во временную таблицу и дальше фильтровать, например отбирать только документы с просрочкой более 30 дней.
КоличествоДней = (НачалоДня(ДатаОкончания) - НачалоДня(ДатаНачала)) / 86400;Расчёт рабочих дней по производственному календарю
Календарная разность дат не подходит, когда нужно учесть только рабочие дни: сроки исполнения договора, доставка «в течение 5 рабочих дней», кадровые расчёты. Здесь используется производственный календарь.
В типовых конфигурациях на БСП (1С:ERP, УТ, ЗУП, Бухгалтерия) данные хранятся в регистре сведений «Данные производственного календаря», где для каждой даты указан вид дня — рабочий, предпраздничный, суббота, воскресенье, праздничный. Количество рабочих дней в периоде получают запросом с отбором по виду дня:
ВЫБРАТЬ
КОЛИЧЕСТВО(ДанныеКалендаря.Дата) КАК РабочихДней
ИЗ
РегистрСведений.ДанныеПроизводственногоКалендаря КАК ДанныеКалендаря
ГДЕ
ДанныеКалендаря.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
И ДанныеКалендаря.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
В решениях, где используются индивидуальные графики работы сотрудников (например, «пятидневка», «два через два»), расчёт ведётся по регистрам графиков работы, а не по общему календарю. В ЗУП для этого есть типовые механизмы учёта времени — не дублируйте их собственными запросами без необходимости.
Если производственный календарь в базе не заполнен на нужный период, запрос вернёт ноль или заниженное значение без какой-либо ошибки. Перед расчётами на будущие периоды проверьте, что календарь заполнен и обновлён с учётом переносов выходных.
Расчёт дней в отчётах на СКД и в типовых конфигурациях
В схеме компоновки данных разность дат вычисляется тем же РАЗНОСТЬДАТ в тексте запроса набора данных — либо выражением на языке выражений СКД, если расчёт делается на уровне вычисляемого поля. Первый вариант предпочтительнее: он выполняется на стороне СУБД и не замедляет формирование отчёта.
В типовых конфигурациях часть расчётов уже реализована, и стоит проверить их перед написанием своего кода:
- в УТ и ERP отчёт «Задолженность клиентов» группирует долг по интервалам просрочки, длительность которых задаётся в настройках;
- в ЗУП количество календарных дней отпуска и больничного рассчитывается документами автоматически с учётом праздников;
- в Бухгалтерии сроки уплаты налогов и сдачи отчётности отображаются в календаре бухгалтера.
Если типовой механизм считает не так, как требует ваша методология (например, включает или исключает граничные дни), не переписывайте его внутри типового модуля — вынесите расчёт в расширение или отдельную обработку, иначе изменения пропадут при обновлении.
Проверка результата и граничные случаи
Любой расчёт дней стоит проверить на контрольных примерах до передачи в работу. Минимальный набор тестов: период внутри одного месяца, период через конец месяца, период через конец года, период нулевой длины (даты совпадают) и период с перевёрнутыми датами.
Отдельного внимания требуют ситуации, когда начальная дата позже конечной. В коде разность станет отрицательной, в запросе РАЗНОСТЬДАТ также вернёт отрицательное значение. Если по логике задачи это недопустимо, добавьте явную проверку и сообщение пользователю вместо молчаливого расчёта.
Пустые даты — ещё один источник ошибок. Пустая дата в 1С равна 01.01.0001, и разность с ней даст огромное число дней. Перед расчётом проверяйте заполненность функцией ЗначениеЗаполнено() или сравнением с '00010101'.
Как проверить результат
Результат 5 дней
Дробное число или 6 без обоснования
0 дней (или 1 при включении границ)
Отрицательное значение или ошибка
Расчёт не выполняется, выводится понятное сообщение
Гигантское число дней от 01.01.0001
Количество согласуется с производственным календарём
Результат равен календарным дням или нулю
Частые вопросы
Как посчитать количество дней между датами в 1С без программирования?
В типовых отчётах на СКД можно добавить вычисляемое поле с функцией РАЗНОСТЬДАТ через настройки отчёта, если конфигурация открыта для редактирования пользователем. Проще всего воспользоваться готовым отчётом с интервалами, например «Задолженность клиентов», где периоды просрочки рассчитываются автоматически.
Почему разность дат даёт дробное число?
Потому что даты содержат время, а разность возвращает секунды. Приведите обе даты к началу дня функцией НачалоДня() перед вычитанием — результат станет целым.
Как учесть праздники и выходные при расчёте дней?
Используйте регистр сведений «Данные производственного календаря»: запросом отберите даты периода с нужным видом дня и посчитайте их количество. Календарь должен быть предварительно заполнен и обновлён.
Чем РАЗНОСТЬДАТ в запросе отличается от вычитания дат в коде?
РАЗНОСТЬДАТ считает количество полных единиц (суток, месяцев) между датами и отбрасывает неполный остаток. Вычитание в коде даёт точное число секунд, которое вы округляете самостоятельно. На неполных сутках результаты могут различаться на единицу.
Как посчитать дни, если дата окончания может быть пустой?
Проверьте дату функцией ЗначениеЗаполнено() до расчёта. Если дата пустая, обычно вместо неё подставляют текущую дату сеанса (например, при расчёте просрочки по незакрытому долгу) либо пропускают строку с пояснением.
Можно ли считать дни в периоде с учётом графика сотрудника, а не общего календаря?
Да, в конфигурациях с учётом рабочего времени (ЗУП, ERP) данные по графикам хранятся в отдельных регистрах. Расчёт ведётся по конкретному графику сотрудника; в ЗУП для кадровых задач корректнее использовать типовые механизмы учёта времени.
Что важно запомнить
Календарные дни в коде считаются как (НачалоДня(ДатаОкончания) - НачалоДня(ДатаНачала)) / 86400, в запросе — функцией РАЗНОСТЬДАТ с типом ДЕНЬ. Для рабочих дней используйте производственный календарь, проверяйте пустые даты и заранее решайте, входят ли границы периода в расчёт.