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

Разработка и Конфигурация · 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. 1
    Определите, какие два поля или параметра содержат даты
  2. 2
    Выберите единицу измерения под задачу: дни для просрочки, месяцы для стажа, годы для возраста
  3. 3
    Добавьте в список выборки выражение РАЗНОСТЬДАТ(Дата1, Дата2, Единица) с псевдонимом
  4. 4
    При необходимости продублируйте выражение в секции ГДЕ для фильтрации
  5. 5
    Выполните запрос в консоли запросов и сверьте результат с ручным расчётом на 2–3 записях

Порядок аргументов и знак результата

Самая частая ошибка — перепутанные местами даты. Запомнить направление помогает формулировка: «сколько единиц нужно добавить к Дате1, чтобы получить Дату2». Если Дата2 позже — результат положительный, если раньше — отрицательный.

Для просрочек логичен вариант РАЗНОСТЬДАТ(ПлановаяДата, ТекущаяДата, ДЕНЬ). Для «сколько осталось до события» — наоборот: РАЗНОСТЬДАТ(ТекущаяДата, ДатаСобытия, ДЕНЬ). Смешение этих двух сценариев в одном отчёте приводит к тому, что часть строк показывает отрицательные значения, и пользователи отчёта трактуют их неверно.

Если знак не важен, можно обернуть результат в условие через ВЫБОР и привести к модулю, но обычно проще выбрать правильный порядок аргументов сразу.

Типичные ошибки
01
Перепутаны даты местами — просрочка показывается отрицательным числом, фильтр > 0 ничего не находит
02
Единица в кавычках ("ДЕНЬ") — запрос падает с ошибкой, единица должна быть ключевым словом
03
Ожидание округления вместо усечения: между 10:00 и 09:00 следующего дня 0 полных дней, хотя интуитивно ждут 1
04
Деление дней на 30 или 365 вместо единиц МЕСЯЦ и ГОД — накапливается погрешность на длинных периодах
05
Сравнение поля типа Дата с параметром без приведения типа — NULL или неожиданные результаты

Особенности: усечение, 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 требует явной обработки, а для регламентированных расчётов результат нужно сверять с алгоритмами конфигурации.