Разработка и Конфигурация · 12 мин
Как в запросе 1С посчитать разность дат
Как использовать функцию РАЗНОСТЬДАТ в запросе 1С: синтаксис, единицы измерения, примеры расчёта разности дат в днях, месяцах, годах и типичные ошибки.
Вычисление разности между двумя датами — одна из самых частых задач при написании запросов в 1С: возраст сотрудника, срок хранения товара, просрочка оплаты, стаж работы, количество дней до окончания договора. Для этого в языке запросов 1С есть встроенная функция РАЗНОСТЬДАТ, которая работает на стороне СУБД и не требует обхода выборки в коде.
Функция универсальна: она принимает две даты и единицу измерения, а возвращает целое число — количество полных периодов между датами. Однако у неё есть особенности, которые часто приводят к ошибкам: порядок аргументов, отрицательный результат, округление, различия между типами ДАТА и ДАТАВРЕМЯ.
Ниже разобран синтаксис функции, все допустимые единицы измерения, практические примеры для типовых задач (просрочка, стаж, возраст), а также альтернативные способы, когда РАЗНОСТЬДАТ не подходит.
Синтаксис функции РАЗНОСТЬДАТ
Общий вид вызова функции в тексте запроса:
РАЗНОСТЬДАТ(<Дата1>, <Дата2>, <ЕдиницаИзмерения>)
Первый и второй параметры — выражения типа Дата или ДатаВремя: поля таблиц, параметры запроса, литералы вида ДАТАВРЕМЯ(2026, 1, 15) или результат функции &ТекущаяДата. Третий параметр — ключевое слово единицы измерения без кавычек.
Функция возвращает целое число — количество полных единиц между датами. Важно понимать направление вычисления: считается разница «от Даты1 к Дате2». Если вторая дата раньше первой, результат будет отрицательным. Это удобно для определения просрочки, но требует внимания при сортировке и сравнениях.
Пример простейшего запроса:
ВЫБРАТЬ
РАЗНОСТЬДАТ(ДАТАВРЕМЯ(2026, 1, 1), ДАТАВРЕМЯ(2026, 3, 15), ДЕНЬ) КАК ДнейМежду
Результат — 74 дня. Дробная часть отбрасывается: между 01.01.2026 10:00 и 02.01.2026 09:00 при единице ДЕНЬ результат будет 0, а не 1, потому что полных суток не прошло.
Допустимые единицы измерения
Третий параметр функции задаётся ключевым словом и определяет, в чём измеряется разность. Доступны семь единиц:
| Единица | Что считает | Типичное применение |
|---|---|---|
| СЕКУНДА | Полные секунды | Длительность операций, обменов, замеры времени |
| МИНУТА | Полные минуты | Время обработки заказа, длительность звонков |
| ЧАС | Полные часы | Смены, время доставки, SLA |
| ДЕНЬ | Полные сутки | Просрочка оплаты, срок хранения, отпуска |
| МЕСЯЦ | Полные месяцы | Стаж, срок действия договора, отсрочка платежа |
| КВАРТАЛ | Полные кварталы | Плановые периоды, отчётность |
| ГОД | Полные годы | Возраст, общий стаж, амортизация |
Ключевое слово пишется без кавычек и без амперсанда — это не параметр и не строка. Запись РАЗНОСТЬДАТ(&Д1, &Д2, "ДЕНЬ") вызовет ошибку исполнения запроса.
Обратите внимание на семантику «полных» периодов для месяцев и лет: между 31.01 и 01.03 разница в месяцах — 1, хотя календарно прошло 30 дней. Функция опирается на календарные границы, а не на эквивалент в днях.
Практические примеры для типовых задач
Просрочка оплаты по заказам
Классическая задача — найти заказы, по которым истёк срок оплаты. Считаем разность между плановой датой оплаты и текущей датой:
ВЫБРАТЬ
Заказы.Номер КАК Номер,
Заказы.ДатаОплаты КАК ДатаОплаты,
РАЗНОСТЬДАТ(Заказы.ДатаОплаты, &ТекущаяДата, ДЕНЬ) КАК ДнейПросрочки
ИЗ
Документ.ЗаказПокупателя КАК Заказы
ГДЕ
РАЗНОСТЬДАТ(Заказы.ДатаОплаты, &ТекущаяДата, ДЕНЬ) > 0
Здесь первая дата — плановая, вторая — текущая. Пока срок не наступил, результат отрицательный или нулевой; как только оплата просрочена, значение станет положительным и покажет число дней задержки.
Возраст сотрудника и стаж работы
Для кадровых отчётов возраст считают в годах, а стаж — в месяцах и годах:
ВЫБРАТЬ
Сотрудники.Ссылка КАК Сотрудник,
РАЗНОСТЬДАТ(Сотрудники.ДатаРождения, &ТекущаяДата, ГОД) КАК ВозрастЛет,
РАЗНОСТЬДАТ(Сотрудники.ДатаПриема, &ТекущаяДата, МЕСЯЦ) КАК СтажМесяцев
ИЗ
Справочник.Сотрудники КАК Сотрудники
Стаж в месяцах удобно хранить именно в месяцах: деление дней на 30 даёт погрешность, а РАЗНОСТЬДАТ с единицей МЕСЯЦ корректно учитывает разную длину месяцев.
Длительность выполнения операции
Если в регистре фиксируются моменты начала и окончания операции, длительность считают в секундах или минутах:
ВЫБРАТЬ
Операции.НомерОперации КАК Операция,
РАЗНОСТЬДАТ(Операции.ДатаНачала, Операции.ДатаОкончания, СЕКУНДА) КАК ДлительностьСек
ИЗ
РегистрСведений.Операции КАК Операции
- 1Определите, какие два поля или параметра содержат даты
- 2Выберите единицу измерения под задачу: дни для просрочки, месяцы для стажа, годы для возраста
- 3Добавьте в список выборки выражение РАЗНОСТЬДАТ(Дата1, Дата2, Единица) с псевдонимом
- 4При необходимости продублируйте выражение в секции ГДЕ для фильтрации
- 5Выполните запрос в консоли запросов и сверьте результат с ручным расчётом на 2–3 записях
Порядок аргументов и знак результата
Самая частая ошибка — перепутанные местами даты. Запомнить направление помогает формулировка: «сколько единиц нужно добавить к Дате1, чтобы получить Дату2». Если Дата2 позже — результат положительный, если раньше — отрицательный.
Для просрочек логичен вариант РАЗНОСТЬДАТ(ПлановаяДата, ТекущаяДата, ДЕНЬ). Для «сколько осталось до события» — наоборот: РАЗНОСТЬДАТ(ТекущаяДата, ДатаСобытия, ДЕНЬ). Смешение этих двух сценариев в одном отчёте приводит к тому, что часть строк показывает отрицательные значения, и пользователи отчёта трактуют их неверно.
Если знак не важен, можно обернуть результат в условие через ВЫБОР и привести к модулю, но обычно проще выбрать правильный порядок аргументов сразу.
Особенности: усечение, NULL и типы данных
Функция усекает, а не округляет. Разница в 1 день 23 часа при единице ДЕНЬ даст 1, а не 2. Если бизнес-логика требует «любая часть суток считается днём», добавьте к результату корректировку через ВЫБОР с проверкой остатка в часах.
Если один из аргументов — NULL (например, незаполненная дата оплаты), результат тоже будет NULL. Такие строки не пройдут фильтр сравнения и могут «потеряться» в отчёте. Используйте ЕСТЬNULL(РАЗНОСТЬДАТ(...), -1) или явную проверку Поле ЕСТЬ NULL, чтобы обработать незаполненные даты осознанно.
Поля типа «дата без времени» интерпретируются как начало суток (00:00:00). Если одно поле хранит только дату, а другое — дату со временем, разница в секундах и минутах может оказаться неожиданной. Для корректного сравнения приведите оба значения к одному виду, например через НАЧАЛОПЕРИОДА(Поле, ДЕНЬ).
Альтернативы РАЗНОСТЬДАТ
Не всегда разность дат нужно считать именно функцией. В простых случаях достаточно сравнения дат операторами >, <, МЕЖДУ — например, для отбора документов за период вычислять разность не требуется вовсе.
Для сдвига даты (а не разности) используется ДОБАВИТЬКДАТЕ(Дата, Единица, Количество) — например, вычислить плановую дату отгрузки как дату заказа плюс 14 дней. Часто РАЗНОСТЬДАТ и ДОБАВИТЬКДАТЕ применяются в паре: одна проверяет условие, другая формирует дату.
Если нужен человекочитаемый вид «2 года 3 месяца 5 дней», одной функцией не обойтись: считают годы, затем месяцы от остатка, затем дни, комбинируя несколько вызовов РАЗНОСТЬДАТ и ДОБАВИТЬКДАТЕ, либо выполняют расчёт уже в коде на встроенном языке после выполнения запроса.
Сравнение подходов
Быстро на больших выборках, считается на СУБД; ограничение — только целые периоды и фиксированный набор единиц
Подходит для фильтрации по периоду; не даёт числового значения разницы
Гибкость любых форматов и округлений; медленнее и требует обхода выборки
Решает обратную задачу — сдвиг даты; разность не вычисляет
Проверка корректности результата
Перед включением выражения в рабочий отчёт проверьте его в консоли запросов на контрольных примерах. Возьмите 2–3 записи, посчитайте разность вручную по календарю и сравните с результатом запроса — это сразу выявит перепутанный порядок аргументов и неверную единицу.
Отдельно проверьте граничные случаи: совпадающие даты (должно быть 0), даты в обратном порядке (отрицательное значение), пустая дата (NULL), переход через конец месяца и високосный февраль при единице МЕСЯЦ.
Как проверить результат
Просрочка положительная, остаток дней отрицательный или наоборот — единообразно по отчёту
В одном отчёте встречаются и положительные, и отрицательные значения без объяснения
Одинаковые даты дают 0, соседние даты — 1 день
Соседние даты дают 0 или 2
NULL обработан явно (ЕСТЬNULL или отбор)
Строки с незаполненными датами пропадают из отчёта
Стаж в месяцах совпадает с ручным подсчётом по календарю
Расхождение на 1–2 месяца из-за деления дней на 30
Если выражение РАЗНОСТЬДАТ используется и в списке выборки, и в условии ГДЕ, удобнее вынести запрос во временную таблицу с вычисленным полем, а фильтровать уже по нему — текст становится короче, а план запроса часто не меняется, так как платформа вычисляет выражение один раз.
Частые вопросы
Как посчитать разность дат в днях между текущей датой и датой документа?
Используйте РАЗНОСТЬДАТ(Документ.Дата, &ТекущаяДата, ДЕНЬ), передав текущую дату параметром. Параметр устанавливается перед выполнением запроса: Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДатаСеанса()). Предпочтительно использовать ТекущаяДатаСеанса(), чтобы избежать проблем с часовыми поясами сервера.
Почему РАЗНОСТЬДАТ возвращает отрицательное число?
Потому что вторая дата раньше первой. Функция считает, сколько периодов нужно добавить к первой дате, чтобы получить вторую. Поменяйте аргументы местами или учитывайте знак в логике отчёта — отрицательное значение само по себе не ошибка, а информация о направлении интервала.
Можно ли получить разность в месяцах с дробной частью?
Напрямую нет — функция возвращает только целые периоды. Приближённый вариант: посчитать дни и разделить на среднюю длину месяца, но это даёт погрешность. Точный способ — взять целые месяцы через РАЗНОСТЬДАТ, а остаток дней вычислить отдельно от даты, сдвинутой через ДОБАВИТЬКДАТЕ на эти месяцы.
Как учесть только рабочие дни, а не календарные?
РАЗНОСТЬДАТ считает только календарные периоды и не знает о производственном календаре. Для рабочих дней нужно соединиться с регистром сведений календаря (в типовых конфигурациях это регистр на базе графиков работы) и посчитать количество рабочих дней между датами через СУММ по признаку рабочего дня.
Работает ли РАЗНОСТЬДАТ в СКД и в произвольных выражениях отчётов?
Да, функция доступна в тексте запроса набора данных СКД. В вычисляемых полях и ресурсах СКД используется уже язык выражений компоновки, где РАЗНОСТЬДАТ недоступна — там разность считают либо в запросе набора данных, либо через арифметику над датами в секундах.
Что вернёт функция, если даты равны или одна из них не заполнена?
При равных датах результат — 0 для любой единицы измерения. Если хотя бы один аргумент NULL, результат будет NULL, и такая строка не пройдёт условия сравнения. Обрабатывайте этот случай через ЕСТЬNULL или проверку на NULL, чтобы строки с пустыми датами не терялись в отчёте.
Что важно запомнить
РАЗНОСТЬДАТ(Дата1, Дата2, Единица) возвращает целое число полных периодов между датами; порядок аргументов определяет знак результата. Единица пишется ключевым словом без кавычек, NULL требует явной обработки, а для регламентированных расчётов результат нужно сверять с алгоритмами конфигурации.