Разработка и Конфигурация · 11 мин
1С: как сложить даты в запросе
Как сложить даты в запросе 1С: функция ДОБАВИТЬКДАТЕ, РАЗНОСТЬДАТ, прибавление дней и месяцев, примеры кода, типичные ошибки и проверка результата.
В языке запросов 1С нельзя написать Дата + 5 — оператор «плюс» для дат не поддерживается, и конструктор запроса вернёт ошибку. Для арифметики с датами предусмотрены специальные функции: ДОБАВИТЬКДАТЕ прибавляет к дате заданное количество секунд, минут, часов, дней, месяцев или лет, а РАЗНОСТЬДАТ вычисляет интервал между двумя датами. Именно через них выполняется любое «сложение» дат в запросах 1С:Предприятия 8.x.
Типичная задача выглядит так: нужно отобрать документы за последние 30 дней, рассчитать дату окончания договора, сдвинуть период отчёта или получить записи регистра, актуальные на дату, смещённую от текущей. Во всех этих случаях решение строится на одной конструкции — ДОБАВИТЬКДАТЕ(ИсходнаяДата, ТипИнтервала, Количество). Количество может быть отрицательным, поэтому та же функция используется и для вычитания.
Ниже разобраны синтаксис функции, допустимые типы интервалов, примеры запросов для типовых сценариев, ограничения платформы и способы проверить корректность результата. Материал ориентирован на разработчиков и консультантов, работающих с консолью запросов, СКД и встроенным языком.
Синтаксис функции ДОБАВИТЬКДАТЕ
Функция имеет три обязательных параметра: исходная дата, тип интервала и числовое количество единиц этого интервала. Результат — новое значение типа «Дата». Формат записи:
ДОБАВИТЬКДАТЕ(ИсходнаяДата, ДЕНЬ, 10)
Первый параметр — поле типа «Дата», параметр запроса или выражение, возвращающее дату (например, &ТекущаяДата). Второй параметр — ключевое слово без кавычек. Третий — целое число; дробные значения платформа отбрасывает по правилам приведения к целому, поэтому «прибавить полтора месяца» напрямую не получится.
Если вместо константы нужно вычисляемое количество, его можно передать параметром запроса или получить из другого поля выборки. Это удобно, когда срок хранится в справочнике: ДОБАВИТЬКДАТЕ(Договоры.ДатаНачала, ДЕНЬ, Договоры.СрокДействияДней).
Допустимые типы интервалов
Платформа поддерживает фиксированный набор типов интервалов. Набор одинаков для ДОБАВИТЬКДАТЕ и РАЗНОСТЬДАТ, что упрощает парные вычисления «прибавить — измерить».
| Интервал | Что прибавляет | Типичное применение |
|---|---|---|
| СЕКУНДА | Секунды | Точные сдвиги времени, журналы событий |
| МИНУТА | Минуты | Расписания, слоты записи |
| ЧАС | Часы | Рабочие смены, дедлайны |
| ДЕНЬ | Календарные дни | Сроки оплаты, отборы за период |
| НЕДЕЛЯ | 7 дней | Еженедельные отчёты |
| ДЕКАДА | 10-дневный период месяца | Специфика учётных политик |
| МЕСЯЦ | Календарные месяцы | Договоры, подписки |
| КВАРТАЛ | 3 месяца | Квартальная отчётность |
| ПОЛУГОДИЕ | 6 месяцев | Полугодовые периоды |
| ГОД | Календарные годы | Годовые договоры, гарантии |
Важно понимать различие между «днём» и «месяцем» при переходе через конец месяца. Прибавление одного месяца к 31 января даст последнее число февраля, а не 2–3 марта: платформа корректирует результат до существующей даты. Если нужен строгий сдвиг на фиксированное число суток, используйте ДЕНЬ.
Примеры: прибавление и вычитание дней, месяцев, лет
Отбор документов за последние N дней
Классическая задача — выбрать заказы, созданные не раньше чем 30 дней назад от заданной даты. Вычитание выполняется отрицательным количеством:
ВЫБРАТЬ
Заказ.Ссылка,
Заказ.Дата
ИЗ
Документ.ЗаказПокупателя КАК Заказ
ГДЕ
Заказ.Дата >= ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, -30)
Расчёт даты окончания договора
Если договор действует 12 месяцев с даты начала, конечная дата вычисляется прямо в поле выборки:
ВЫБРАТЬ
Договоры.Ссылка,
Договоры.ДатаНачала,
ДОБАВИТЬКДАТЕ(Договоры.ДатаНачала, МЕСЯЦ, 12) КАК ДатаОкончания
ИЗ
Справочник.ДоговорыКонтрагентов КАК Договоры
На практике день окончания часто должен быть «минус один день» от годовщины. Тогда комбинируют два вызова: сначала прибавляют год, затем вычитают день — либо вкладывают функции друг в друга: ДОБАВИТЬКДАТЕ(ДОБАВИТЬКДАТЕ(ДатаНачала, ГОД, 1), ДЕНЬ, -1).
Сдвиг границы периода в отчёте
В СКД параметр «КонецПериода» нередко нужно расширить до конца дня. Так как дата без времени интерпретируется как начало суток, безопасный приём — прибавить сутки и использовать строгое неравенство: Дата < ДОБАВИТЬКДАТЕ(&КонецПериода, ДЕНЬ, 1). Это исключает потерю документов, проведённых в последние секунды дня.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДОБАВИТЬКДАТЕ(&ДатаНачала, МЕСЯЦ, &СрокМесяцев) КАК ДатаОкончания";
Запрос.УстановитьПараметр("ДатаНачала", ТекущаяДатаСеанса());
Запрос.УстановитьПараметр("СрокМесяцев", 6);
Результат = Запрос.Выполнить().Выгрузить();Разница между датами: функция РАЗНОСТЬДАТ
Обратная операция — узнать, сколько дней, месяцев или лет между двумя датами. Для этого служит РАЗНОСТЬДАТ(Дата1, Дата2, ТипИнтервала), возвращающая целое число. Если вторая дата раньше первой, результат будет отрицательным.
ВЫБРАТЬ
Задачи.Ссылка,
РАЗНОСТЬДАТ(Задачи.ДатаСоздания, &ТекущаяДата, ДЕНЬ) КАК ДнейВРаботе
ИЗ
Задача.ЗадачаИсполнителя КАК Задачи
ГДЕ
НЕ Задачи.Выполнена
Связка двух функций позволяет строить проверки вида «срок истекает через 7 дней»: сравнивается РАЗНОСТЬДАТ(&ТекущаяДата, ДатаОкончания, ДЕНЬ) с порогом. Учтите, что РАЗНОСТЬДАТ считает полные интервалы: между 10:00 и 18:00 одного дня разница в часах равна 8, а в днях — 0.
Сравнение вариантов
Подходит для отборов, вычисляемых полей и СКД; выполняется на сервере СУБД, быстро и без обхода выборки.
Дата + 86400 (секунды в сутках) работает вне запроса; удобно для одиночных вычислений, но требует ручного контроля перехода через месяцы.
Подходят, когда нужна не сдвинутая, а выровненная дата — начало месяца, конец недели и т.п.
Ограничения и типичные ошибки
Первая частая ошибка — попытка сложить две даты или прибавить к дате число оператором «+». Язык запросов этого не допускает, и запрос просто не выполнится. Вторая — путаница между датой и строкой: если поле хранит дату как строку (такое встречается в обменах), сначала её нужно привести к дате во встроенном языке, либо передавать параметром уже готовое значение.
Третья группа ошибок связана с пустыми датами. Если поле не заполнено, оно содержит значение ДАТАВРЕМЯ(1,1,1), и прибавление месяца к такой дате даст 1 февраля 0001 года — формально корректный, но бессмысленный результат. Перед вычислением отфильтруйте пустые даты условием Дата <> ДАТАВРЕМЯ(1,1,1) или обработайте их через ВЫБОР КОГДА ... ИНАЧЕ.
Проверка корректности результата
Самый надёжный способ отладки — консоль запросов в режиме предприятия. Выполните запрос с реальными параметрами и добавьте в выборку рядом исходную дату, вычисленную дату и разность между ними через РАЗНОСТЬДАТ. Если прибавляли 30 дней, а РАЗНОСТЬДАТ показывает 30 — сдвиг корректен.
Отдельно проверьте граничные случаи: переход через конец месяца, високосный февраль, дату 31-го числа и пустые значения. Именно на этих точках логика чаще всего ломается.
Как проверить результат
РАЗНОСТЬДАТ(Исходная, Результат, ДЕНЬ) равна N
Разница отличается или результат в году 0001
31.01 + 1 месяц даёт последний день февраля
Дата «перескакивает» на март или пуста
Отфильтрованы или обработаны через ВЫБОР
В выборке появляются даты 0001 года
Документы последнего дня попадают в выборку
Последние часы периода теряются
Пошаговый порядок внедрения вычисления дат в запрос
- 1Определите, какой интервал соответствует бизнес-правилу: дни, месяцы или годы — они не взаимозаменяемы.
- 2Напишите выражение ДОБАВИТЬКДАТЕ с параметром запроса для количества, чтобы не править текст при смене срока.
- 3Добавьте защиту от пустых дат: отбор или конструкцию ВЫБОР КОГДА.
- 4Выполните запрос в консоли на тестовых данных и сверьте 3–5 значений с ручным расчётом.
- 5Проверьте граничные даты: конец месяца, високосный год, начало периода.
- 6Перенесите проверенный текст в модуль или схему СКД и повторно выполните отчёт.
Если вычисление используется в условии соединения таблиц, убедитесь, что обе стороны приведены к сопоставимой точности: например, сравнивать «дату документа» и «дату регистра плюс день» корректно только когда обе выражены в одинаковых единицах — иначе соединение даст пропуски или дубли.
В отчётах на СКД выносите количество дней или месяцев в параметр, а не «зашивайте» числом в текст запроса. Когда учётная политика изменит срок с 30 на 45 дней, правка займёт минуту и не потребует вмешательства разработчика.
FAQ
Можно ли в запросе 1С прибавить к дате число через знак «+»?
Нет. Оператор сложения для типа «Дата» в языке запросов не определён — запрос завершится ошибкой. Используйте ДОБАВИТЬКДАТЕ с нужным типом интервала. Оператор «+» с датами работает только во встроенном языке, где к дате прибавляются секунды.
Как вычесть из даты 3 месяца в запросе?
Вызовите ДОБАВИТЬКДАТЕ с отрицательным количеством: ДОБАВИТЬКДАТЕ(&Дата, МЕСЯЦ, -3). Отдельной функции вычитания в языке запросов нет.
Что вернёт ДОБАВИТЬКДАТЕ, если исходная дата — 31 января, а интервал — 1 месяц?
Платформа вернёт последний день февраля (28 или 29 число в зависимости от високосности), поскольку 31 февраля не существует. Если нужен сдвиг ровно на 31 сутки, используйте интервал ДЕНЬ.
Как прибавить к дате полтора месяца?
Напрямую — никак: количество должно быть целым. Комбинируйте вызовы, например ДОБАВИТЬКДАТЕ(ДОБАВИТЬКДАТЕ(&Дата, МЕСЯЦ, 1), ДЕНЬ, 15), либо пересчитайте интервал в дни по бизнес-правилу вашей учётной системы.
Чем ДОБАВИТЬКДАТЕ отличается от НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА?
ДОБАВИТЬКДАТЕ смещает дату на заданную величину, а НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА выравнивают дату на границу периода — например, на первое число месяца или 23:59:59 последнего дня. Это разные операции, и они часто применяются вместе.
Работает ли ДОБАВИТЬКДАТЕ в СКД и в консоли запросов?
Да, функция является частью языка запросов и доступна везде, где выполняется запрос: в консоли, в наборах данных СКД, в виртуальных таблицах и в параметризуемых условиях.
Что важно запомнить
Сложение дат в запросе 1С выполняется только через ДОБАВИТЬКДАТЕ с ключевым словом интервала и целым количеством; отрицательное значение заменяет вычитание. Для разницы дат применяйте РАЗНОСТЬДАТ. Всегда обрабатывайте пустые даты и проверяйте граничные случаи — конец месяца и високосный год — перед использованием запроса в рабочей базе.