Разработка и Конфигурация · 10 мин
Как найти разность дат в 1С: полное руководство
Разбираем, как найти разность дат в 1С: функция РазностьДат, параметры ТипРазностиДат, вычитание дат в запросах и коде, типичные ошибки и примеры.
Расчёт разности дат — одна из самых частых задач при разработке и доработке конфигураций 1С: подсчёт стажа сотрудника, срока годности товара, просрочки оплаты, длительности отпуска. Встроенный язык 1С предлагает два принципиально разных подхода: прямое вычитание дат через оператор минус и функцию РазностьДат с указанием единицы измерения. Выбор между ними определяет точность и смысл результата.
Ошибки в расчётах дат приводят к реальным последствиям: неверно начисленной зарплате, неправильному сроку оплаты в договоре, некорректным данным в отчётах для руководства. Поэтому важно понимать не только синтаксис, но и логику работы каждого способа, а также граничные случаи — високосные годы, разную длину месяцев, отсутствие времени у даты.
Материал рассчитан на разработчиков, внедренцев и продвинутых пользователей, работающих с конфигуратором 1С:Предприятие 8.x. Примеры кода применимы как к типовым конфигурациям (Бухгалтерия, Управление торговлей, ЗУП), так и к самописным решениям.
Два способа вычислить разность дат: вычитание и функция РазностьДат
Первый способ — обычное вычитание одной даты из другой оператором «минус». Результатом будет число секунд между датами. Это важно запомнить: 1С хранит дату с точностью до секунды, и вычитание возвращает именно секунды, а не дни. Чтобы получить дни, результат делят на 86400 (количество секунд в сутках).
ДатаНачала = '20260110';
ДатаОкончания = '20260125';
РазностьВСекундах = ДатаОкончания - ДатаНачала; // 1296000
РазностьВДнях = РазностьВСекундах / 86400; // 15
Второй способ — встроенная функция РазностьДат. Она принимает три параметра: начальную дату, конечную дату и тип разности (единица измерения результата). Функция сразу возвращает значение в нужных единицах и корректно обрабатывает календарные особенности — например, разную длину месяцев при расчёте в месяцах.
КоличествоДней = РазностьДат(ДатаНачала; ДатаОкончания; ТипРазностиДат.День); // 15
КоличествоМесяцев = РазностьДат(ДатаНачала; ДатаОкончания; ТипРазностиДат.Месяц);
Сравнение подходов
Возвращает секунды. Подходит для точных интервалов и измерения длительности операций. Требует ручного пересчёта в дни и часы.
Возвращает результат сразу в нужной единице: день, месяц, квартал, год, час, минута, секунда. Удобна для календарных расчётов, но округляет неполные периоды в меньшую сторону.
Параметры функции РазностьДат и типы единиц измерения
Третий параметр функции задаётся системным перечислением ТипРазностиДат. Доступные значения: Секунда, Минута, Час, День, Месяц, Квартал, Год. Выбор единицы влияет не только на масштаб результата, но и на логику округления.
Функция считает количество полных периодов между датами. Например, между 15 января и 10 марта при типе «Месяц» результат будет 1, а не 2, потому что полных месяцев прошёл только один. Это частый источник ошибок при расчёте стажа и сроков: разработчик ожидает «округление вверх», а получает целое число полных периодов.
| Тип разности | Что возвращает | Типичное применение |
|---|---|---|
| Секунда | Число секунд между датами | Замеры производительности, точные интервалы |
| Минута, Час | Число полных минут или часов | Учёт рабочего времени, длительность операций |
| День | Число полных суток | Просрочка оплаты, срок хранения |
| Месяц | Число полных месяцев | Стаж, абонентский период |
| Квартал, Год | Число полных кварталов или лет | Возраст, отчётные периоды |
Если начальная дата больше конечной, функция вернёт отрицательное число. Это удобно для определения просрочки: положительное значение показывает, сколько дней прошло после наступления срока.
Расчёт разности дат в запросах 1С
В языке запросов 1С действует своя функция РАЗНОСТЬДАТ с аналогичным синтаксисом: РАЗНОСТЬДАТ(Дата1, Дата2, Единица). Она применяется прямо в тексте запроса и позволяет фильтровать и группировать данные без обхода выборки в коде, что существенно быстрее на больших объёмах.
ВЫБРАТЬ
Заказы.Ссылка,
РАЗНОСТЬДАТ(Заказы.ДатаОтгрузки, &ТекущаяДата, ДЕНЬ) КАК ДнейПросрочки
ИЗ
Документ.ЗаказПокупателя КАК Заказы
ГДЕ
РАЗНОСТЬДАТ(Заказы.ДатаОтгрузки, &ТекущаяДата, ДЕНЬ) > 5
Такой запрос выберет заказы, отгруженные более пяти дней назад. Обратите внимание: в запросах тип разности указывается ключевым словом без кавычек — ДЕНЬ, МЕСЯЦ, ГОД, ЧАС, МИНУТА, СЕКУНДА. Логика округления та же, что и во встроенном языке: считаются полные периоды.
Типовые сценарии: просрочка, стаж, срок годности
Просрочка оплаты по договору
Задача: определить, сколько дней прошло после плановой даты оплаты. Если дата оплаты в будущем — просрочки нет. Здесь удобно сравнить даты напрямую, а разность считать только при положительном результате.
Если ТекущаяДатаСеанса() > ДатаОплаты Тогда
ДнейПросрочки = РазностьДат(ДатаОплаты; ТекущаяДатаСеанса(); ТипРазностиДат.День);
Иначе
ДнейПросрочки = 0;
КонецЕсли;
Расчёт возраста или стажа в полных годах
Для возраста используйте тип разности «Год»: функция вернёт количество полных лет, что корректно учитывает, наступил ли день рождения в текущем году. При вычитании дат и делении на 365 такая точность не гарантируется из-за високосных лет.
Возраст = РазностьДат(ДатаРождения; ТекущаяДатаСеанса(); ТипРазностиДат.Год);
Срок годности товара
При работе со сроками годности дату часто хранят без времени, а сравнение ведут с началом текущего дня. Используйте функцию НачалоДня, чтобы время суток не искажало результат: иначе товар, у которого срок истекает сегодня, может быть ошибочно посчитан просроченным уже с утра.
- 1Определите, в каких единицах нужен результат: секунды, дни, месяцы, годы
- 2Выберите способ: вычитание для секунд, РазностьДат для календарных единиц
- 3Приведите даты к нужной точности: НачалоДня(), если время не важно
- 4Выполните расчёт и проверьте знак результата на граничных данных
- 5Протестируйте на датах разной длины месяца и на високосном феврале
Типичные ошибки и граничные случаи
Самая распространённая ошибка — забыть, что вычитание дат возвращает секунды. Начинающие разработчики выводят «Дата2 - Дата1» и удивляются числу вроде 1296000 вместо ожидаемых 15 дней. Вторая по частоте ошибка — ожидать от РазностьДат округления в большую сторону: функция всегда возвращает только полные периоды.
Отдельная группа проблем связана с пустыми датами. Незаполненный реквизит типа «Дата» содержит значение '00010101' — 1 января года 1. Разность с такой датой даст огромное число, которое «молча» попадёт в отчёт. Перед расчётом всегда проверяйте заполненность через ЗначениеЗаполнено().
Ещё один нюанс — даты с временем. Разность между 10:00 понедельника и 09:00 вторника при типе «День» равна нулю, потому что полные сутки не прошли. Если бизнес-логика оперирует календарными днями, предварительно обрежьте время функцией НачалоДня.
Проверка результата и отладка
Проверять расчёты дат удобно на контрольных примерах с заранее известным ответом. Возьмите интервал ровно в месяц (с 1-го по 1-е число), интервал через високосный февраль и интервал, где конечная дата меньше начальной. Если на всех трёх примерах результат совпадает с ожиданием — логика, скорее всего, верна.
Для отладки в конфигураторе используйте точку останова и табло: вычислите выражение РазностьДат с реальными значениями переменных прямо во время остановки. В тонком клиенте без конфигуратора поможет внешняя обработка «Консоль кода» из стандартных инструментов разработчика или временное сообщение через Сообщить().
Как проверить результат
Результат равен 1
Результат 0 или 2 — проверьте порядок аргументов
Расчёт пропускается или выдаётся понятное сообщение
Огромное число дней от '00010101' попадает в отчёт
После НачалоДня считаются календарные дни
Результат зависит от часов и минут
Отрицательное значение обрабатывается осознанно
Минус попадает в документы без контроля
Часто задаваемые вопросы
Чем отличается вычитание дат от функции РазностьДат?
Вычитание (Дата2 - Дата1) возвращает число секунд между датами и требует ручного пересчёта в нужные единицы. РазностьДат сразу возвращает количество полных периодов — дней, месяцев, лет — и корректно учитывает календарную специфику, например разную длину месяцев. Для прикладных расчётов в днях и месяцах предпочтительнее РазностьДат.
Как посчитать разность дат в запросе 1С?
Используйте функцию РАЗНОСТЬДАТ(Дата1, Дата2, ДЕНЬ) прямо в тексте запроса. Единица измерения указывается ключевым словом: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, КВАРТАЛ, ГОД. Функцию можно применять и в полях выборки, и в условии ГДЕ для фильтрации записей по длительности интервала.
Почему РазностьДат возвращает на единицу меньше, чем ожидается?
Функция считает только полные периоды. Между 15 января и 10 марта полный месяц прошёл один, поэтому при типе «Месяц» результат будет 1. Если бизнес-логика требует считать начатые периоды, добавьте к результату единицу вручную или пересчитайте в днях и поделите с округлением вверх.
Как правильно посчитать возраст сотрудника в 1С?
Используйте РазностьДат(ДатаРождения; ТекущаяДатаСеанса(); ТипРазностиДат.Год). Функция вернёт количество полных лет и корректно учтёт, наступил ли день рождения в текущем году. Делить разность в днях на 365 не следует — из-за високосных лет возраст периодически будет определяться неверно.
Что делать, если одна из дат не заполнена?
Пустая дата в 1С равна '00010101', и разность с ней даст огромное некорректное число. Перед расчётом проверяйте обе даты функцией ЗначениеЗаполнено() и при пустом значении либо пропускайте расчёт, либо выводите понятное сообщение пользователю. В запросах аналогичная проверка — сравнение с ДАТАВРЕМЯ(1,1,1).
Как учесть только календарные дни без времени?
Приведите обе даты к началу дня функцией НачалоДня перед расчётом. Без этого разность между 10:00 одного дня и 09:00 следующего при типе «День» будет равна нулю, поскольку полные сутки не прошли. Обрезка времени делает результат независимым от часов и минут.
Что важно запомнить
Для разности дат в 1С есть два инструмента: вычитание дат даёт секунды, функция РазностьДат — полные периоды в нужной единице измерения. В запросах используйте РАЗНОСТЬДАТ. Всегда проверяйте заполненность дат, при необходимости обрезайте время через НачалоДня и помните, что РазностьДат округляет неполные периоды в меньшую сторону.