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

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

Как получить разность дат в днях в 1С

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

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

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

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

Функция РазностьДат — основной способ

Функция РазностьДат встроена в платформу и возвращает разность между двумя датами в указанных единицах. Синтаксис: РазностьДат(Дата1, Дата2, ЕдиницаИзмерения). Первый параметр — вычитаемая дата, второй — уменьшаемая, третий — строка с единицей: "Секунда", "Минута", "Час", "День", "Месяц", "Квартал", "Год".

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

Результат — целое число. Если ДатаОкончания меньше ДатыНачала, функция вернёт отрицательное значение, что удобно для контроля корректности введённого периода. Важно помнить: функция считает разность по календарным границам единицы измерения, а не по полным суткам. Например, между 23:00 одного дня и 01:00 следующего разность в днях будет равна 1, хотя прошло всего два часа.

Это поведение критично для расчётов просрочек и начислений. Если бизнес-логика требует считать именно полные сутки, РазностьДат с единицей "День" может дать результат на единицу больше ожидаемого, и способ нужно менять.

Вычитание дат и пересчёт секунд в дни

Оператор вычитания для двух значений типа Дата возвращает число — разность в секундах. Чтобы получить дни, результат делят на 86400 (количество секунд в сутках). Этот способ даёт «физическую» разность по времени, в отличие от календарной логики РазностьДат.

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

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

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

Проблема этого подхода — время в составе дат. Если дата начала содержит 15:30, а дата окончания — 09:00, «календарная» разность и «секундная» разойдутся. Поэтому перед вычитанием даты часто нормализуют: НачалоДня(ДатаНачала) и НачалоДня(ДатаОкончания) — тогда оба способа дадут одинаковый результат.

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

Как учитывать границы периода: включать или нет последний день

Частый источник расхождений — вопрос, входит ли последний день периода в расчёт. При вычислении длительности отпуска с 1 по 10 число обычно ожидают 10 дней, но обе формулы выше дадут 9. Причина проста: разность считает интервалы между датами, а не количество календарных дней в диапазоне.

Чтобы включить обе границы, добавьте к результату единицу: КоличествоДней = РазностьДат(ДатаНачала, ДатаОкончания, "День") + 1. Но применяйте это только там, где бизнес-правило явно требует включения последнего дня — например, в кадровых расчётах длительности отпуска или больничного.

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

Маршрут решения

Как выбрать формулу

Нужна календарная разность без учёта времениРазностьДат(Дата1, Дата2, "День")
Нужны полные физические суткиЦел((Дата2 - Дата1) / 86400)
Последний день периода входит в расчётДобавьте + 1 к результату
Расчёт в отчёте на СКД или запросеИспользуйте РАЗНОСТЬДАТ в тексте запроса

Разность дат в запросе: РАЗНОСТЬДАТ

В языке запросов 1С есть аналогичная функция РАЗНОСТЬДАТ(Дата1, Дата2, Единица). Единицы задаются ключевыми словами без кавычек: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, ГОД. Это правильный способ считать разность прямо в выборке, не перебирая результат в цикле.

ВЫБРАТЬ

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

ИЗ

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

Поведение РАЗНОСТЬДАТ в запросе аналогично РазностьДат в коде: считаются календарные границы единиц измерения. Если в полях дат хранится время, результат может отличаться от ожидаемого «по суткам». При необходимости применяйте в запросе функции НАЧАЛОПЕРИОДА(Дата, ДЕНЬ) к обоим операндам.

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

Особые случаи: пустые даты, рабочие дни, месяцы и годы

Проверка пустых дат

Пустая дата в 1С — это 01.01.0001 00:00:00. Если один из реквизитов не заполнен, разность даст огромное число дней и испортит итоги отчёта. Перед расчётом всегда проверяйте: Если ЗначениеЗаполнено(ДатаНачала) И ЗначениеЗаполнено(ДатаОкончания) Тогда ... — иначе выводите пусто или ноль по правилам отчёта.

Рабочие дни вместо календарных

Ни РазностьДат, ни вычитание не умеют исключать выходные и праздники. Для расчёта рабочих дней используют производственный календарь: в типовых конфигурациях это регистр сведений «Данные производственного календаря» и функции общего модуля КалендарныеГрафики. В самописной конфигурации придётся хранить календарь самостоятельно и считать дни запросом по регистру.

Разность в месяцах и годах

Единицы "Месяц" и "Год" тоже считают календарные границы: между 31 января и 1 февраля разность в месяцах равна 1. Для расчёта полных лет (возраст, стаж) обычно берут РазностьДат с единицей "Год" и дополнительно проверяют, наступила ли дата годовщины в текущем году, при необходимости вычитая единицу.

Типичные ошибки
01
Деление секунд на 86400 без отсечения времени — результат «плывёт» на сутки
02
Отсутствие проверки пустых дат — в отчёте появляются числа в сотни тысяч дней
03
Добавление +1 к разности там, где методика этого не требует — расхождение пени и просрочек с контрагентами
04
Ожидание, что РазностьДат исключит выходные — функция работает только с календарём
05
Расчёт в цикле по выборке вместо РАЗНОСТЬДАТ в запросе — низкая скорость отчёта

Проверка результата и отладка

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

Отдельно проверьте граничные ситуации: даты с ненулевым временем, пустая дата окончания, дата окончания раньше даты начала. Для последнего случая решите, что должен показывать отчёт — отрицательное число, ноль или предупреждение пользователю.

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

Контрольные точки

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

Одинаковые даты начала и окончания
Норма

Результат 0 (или 1, если последний день включается)

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

Отрицательное число или ошибка

Соседние календарные дни без времени
Норма

Разность 1 день

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

0 или 2 — проверьте границы и время

Даты с временем 23:00 и 01:00 следующего дня
Норма

Осознанно выбранный вами результат по методике

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

Случайное значение, не учтённое в регламенте

Пустая дата окончания
Норма

Пусто, ноль или сообщение по правилам отчёта

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

Число в сотни тысяч дней

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

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

Оператор вычитания дат в 1С возвращает разность в секундах. Чтобы получить дни, разделите результат на 86400 и отбросьте дробную часть функцией Цел, либо используйте РазностьДат с единицей "День".

Как посчитать дни между датами, включая последний день?

Добавьте единицу к результату: РазностьДат(Дата1, Дата2, "День") + 1. Применяйте это только если методика расчёта явно требует включения конечной даты, например при подсчёте дней отпуска.

Можно ли получить разность дат в запросе без цикла?

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

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

Штатные функции разности дат этого не умеют. Нужен производственный календарь: в типовых конфигурациях — регистр «Данные производственного календаря» и функции модуля КалендарныеГрафики, в самописных — собственный регистр с днями и запрос по нему.

Что делать, если дата окончания раньше даты начала?

РазностьДат вернёт отрицательное число. Определите поведение по методике: показать отрицательное значение, заменить нулём или выдать пользователю сообщение о некорректном периоде.

Влияет ли время в составе даты на результат?

Да. РазностьДат считает календарные границы, поэтому между 23:00 и 01:00 следующего дня разность в днях равна 1. Чтобы результат не зависел от времени, нормализуйте даты функциями НачалоДня или КонецДня перед расчётом.

Итог

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

Для разности дат в днях используйте РазностьДат(Дата1, Дата2, "День") в коде и РАЗНОСТЬДАТ в запросах. Вычитание дат даёт секунды — делите на 86400. Отсекайте время, проверяйте пустые даты и заранее решайте, входит ли последний день периода в расчёт.