Разработка и Конфигурация · 10 мин
Как сложить две даты в 1С
Как сложить две даты в 1С: прибавление секунд, дней, месяцев к дате, функция ДобавитьКДате, разность дат и типичные ошибки при работе с датами в коде 1С.
Встроенный язык 1С не позволяет напрямую «сложить две даты» — операция «дата плюс дата» лишена смысла и вызовет ошибку. Зато можно прибавить к дате интервал: определённое количество секунд, дней, месяцев или лет. Именно эта задача и стоит за бытовой формулировкой «сложить даты»: например, рассчитать срок оплаты как дату документа плюс 14 дней или дату окончания договора как дату начала плюс 12 месяцев.
Для решения используются два подхода. Первый — арифметика с секундами: к значению типа «Дата» можно прибавить число, и оно будет интерпретировано как количество секунд. Второй — функция глобального контекста ДобавитьКДате(), которая корректно работает с календарными периодами: месяцами, кварталами, годами. Выбор зависит от того, какой интервал нужно прибавить.
Отдельная обратная задача — узнать разность между двумя датами, то есть сколько секунд, дней или месяцев прошло от одной даты до другой. Для этого применяется вычитание дат и функция РазностьДат(). Все три операции рассмотрены ниже с примерами кода и типичными ошибками.
Почему нельзя сложить две даты напрямую
Значение типа «Дата» в 1С — это момент времени с точностью до секунды, например 15.03.2026 10:30:00. Сложение двух таких значений не имеет физического смысла: нельзя «прибавить» 15 марта к 20 июня. Поэтому выражение вида Дата1 + Дата2 приведёт к ошибке исполнения или неверному результату в зависимости от контекста.
Корректная постановка задачи всегда одна из двух: либо «к дате А прибавить интервал N», либо «найти разницу между датой А и датой Б». Прежде чем писать код, определите, какая из двух задач у вас на самом деле. В большинстве прикладных сценариев — сроки оплаты, окончания договоров, даты отгрузки — речь идёт о прибавлении интервала.
Прибавление к дате секунд, часов и дней
Самый простой способ — арифметическая операция. К значению типа «Дата» прибавляется число, и платформа трактует его как секунды:
ДатаДокумента = Дата(2026, 3, 15, 10, 0, 0);
// Прибавить 1 час (3600 секунд)
НоваяДата = ДатаДокумента + 3600;
// Прибавить 1 день (86400 секунд)
СледующийДень = ДатаДокумента + 86400;
// Прибавить 14 дней
СрокОплаты = ДатаДокумента + 14 * 86400;
Чтобы не считать секунды вручную и сделать код читаемым, заведите константу или вычисляйте произведение на месте: КоличествоДней 24 60 * 60. Такой код легче проверять и меньше риск опечатки в числе 86400.
Аналогично работает вычитание числа из даты — интервал отматывается назад. Операция безопасна при переходе через границы месяца и года: платформа сама корректно пересчитает календарную дату, например 31 января минус 86400 секунд даст 30 января.
СекундВДне = 86400;
СрокОплаты = ДатаДокумента + 14 * СекундВДне; // дата документа + 14 днейПрибавление месяцев, кварталов и лет: функция ДобавитьКДате
Арифметика с секундами не подходит для месяцев и лет, потому что их длительность непостоянна: в месяце может быть 28–31 день, в году — 365 или 366 дней. Для календарных периодов предназначена функция ДобавитьКДате():
// Синтаксис: ДобавитьКДате(Дата, ТипПериода, Количество)
// Прибавить 3 месяца
ДатаОкончания = ДобавитьКДате(ДатаНачала, "Месяц", 3);
// Прибавить 1 год
ДатаГодовщины = ДобавитьКДате(ДатаНачала, "Год", 1);
// Отнять 2 квартала (отрицательное количество)
ПрошлыйПериод = ДобавитьКДате(ДатаНачала, "Квартал", -2);
Второй параметр — строка с типом периода. Поддерживаются значения: «Секунда», «Минута», «Час», «День», «Неделя», «Месяц», «Квартал», «Полугодие», «Год». Третий параметр — целое число, может быть отрицательным для движения в прошлое.
Важный нюанс — поведение на концах месяцев. Если прибавить месяц к 31 января, результатом будет 28 (или 29) февраля, а не 2–3 марта: платформа «обрезает» день до последнего дня целевого месяца. Учитывайте это при расчёте повторяющихся платежей и договорных сроков.
Как вычислить разность между двумя датами
Обратная задача — узнать, сколько времени прошло между двумя датами. Вычитание одной даты из другой возвращает число секунд:
РазностьВСекундах = ДатаОкончания - ДатаНачала;
РазностьВДнях = РазностьВСекундах / 86400;
Для календарных периодов используется функция РазностьДат():
// Сколько полных месяцев между датами
КоличествоМесяцев = РазностьДат(ДатаНачала, ДатаОкончания, "Месяц");
// Сколько полных дней
КоличествоДней = РазностьДат(ДатаНачала, ДатаОкончания, "День");
Обратите внимание: РазностьДат() считает именно полные периоды. Между 15 января и 14 февраля функция с типом «Месяц» вернёт 0, потому что полный месяц ещё не прошёл. Если нужно округление вверх или учёт неполных периодов, реализуйте его дополнительной логикой.
Работа с датами в запросах
В языке запросов 1С доступны те же приёмы, но синтаксис другой. Для прибавления интервала используется функция ДОБАВИТЬКДАТЕ, для разности — РАЗНОСТЬДАТ:
ВЫБРАТЬ
Счет.Дата КАК ДатаСчета,
ДОБАВИТЬКДАТЕ(Счет.Дата, ДЕНЬ, 14) КАК СрокОплаты,
РАЗНОСТЬДАТ(Счет.Дата, &ТекущаяДата, ДЕНЬ) КАК ДнейПрошло
ИЗ
Документ.СчетНаОплату КАК Счет
Тип периода в запросе указывается без кавычек: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ПОЛУГОДИЕ, ГОД. Вычисления в запросе предпочтительнее, если результат нужен в выборке по многим документам: это быстрее, чем обход выборки с расчётом в цикле.
Где выполнять расчёт дат
Подходит для расчёта при записи документа, в обработчиках, при работе с одним объектом. Гибче, легче отлаживать.
Подходит для массовых выборок, отчётов и динамических списков. Быстрее на больших объёмах, но сложнее отладка.
Подходит для отчётов на компоновке данных, когда расчёт нужен только для вывода пользователю.
Типичные ошибки и как их избежать
Большинство проблем при работе с датами связано не с самими функциями, а с невнимательностью к типам и граничным случаям. Ниже — ошибки, которые встречаются чаще всего.
Особое внимание уделите пустым датам. Если реквизит не заполнен, его значение — 01.01.0001, и расчёт «срок оплаты» от такой даты даст дату в далёком прошлом без какого-либо предупреждения. Перед вычислением добавляйте проверку:
Если ЗначениеЗаполнено(ДатаДокумента) Тогда
СрокОплаты = ДатаДокумента + 14 * 86400;
Иначе
СрокОплаты = Дата(1, 1, 1); // или обработка исключительной ситуации
КонецЕсли;
Проверка результата расчёта
После реализации расчёта проверьте его на граничных случаях, а не только на «удобных» датах. Минимальный набор проверок:
Как проверить результат
28 или 29 февраля (последний день месяца)
Дата в марте при расчёте через ДобавитьКДате без специальной обработки
28 февраля невисокосного года
Ошибка или 1 марта без явной логики переноса
0 полных дней, корректное число часов
1 день из-за разного времени в датах
Ветка обработки пустой даты срабатывает
Результат около 01.01.0001 попадает в данные
Для отладки удобно выводить исходную дату, интервал и результат через Сообщить() или в окно «Вычислить выражение» (Shift+F9) в конфигураторе. Проверяйте расчёт на датах 28–31 числа, на границах года и на датах с ненулевым временем.
- 1Определите, что прибавляется: секунды/дни или месяцы/годы.
- 2Для секунд и дней используйте Дата + N * 86400, для месяцев и лет — ДобавитьКДате().
- 3Добавьте проверку заполненности исходной даты.
- 4Протестируйте на концах месяцев, високосном феврале и датах с временем.
- 5Если расчёт нужен в выборке по многим документам — перенесите его в запрос через ДОБАВИТЬКДАТЕ.
Частые вопросы
Как прибавить к дате рабочие дни, а не календарные?
Штатной функции для рабочих дней нет. Обычно используют регистр сведений с производственным календарём (в типовых конфигурациях — «Регламентированный производственный календарь»): в цикле или запросе отсчитывают нужное количество дней, отмеченных как рабочие. Простым прибавлением секунд эта задача не решается.
Что вернёт выражение Дата1 + Дата2?
Платформа попытается выполнить сложение, но для двух значений типа «Дата» операция не имеет смысла и приведёт к ошибке исполнения. Складывать можно только дату с числом (секундами) или использовать ДобавитьКДате() для календарных периодов.
Как отнять от даты несколько дней?
Вычтите из даты число секунд: ДатаДокумента - 7 * 86400 отнимет неделю. Для месяцев и лет используйте ДобавитьКДате() с отрицательным количеством, например ДобавитьКДате(Дата, "Месяц", -1).
Почему разность двух дат в днях даёт дробное число?
Вычитание дат возвращает секунды, и если в датах есть время, при делении на 86400 получится дробь. Чтобы получить целые дни, используйте Цел() или РазностьДат() с типом «День», либо предварительно обрежьте время функцией НачалоДня().
Как прибавить интервал к текущей дате?
Получите текущую дату функцией ТекущаяДата() (на клиенте — ТекущаяДата(), на сервере она же возвращает дату сеанса) и примените к ней нужный расчёт: ТекущаяДата() + 3 * 86400 или ДобавитьКДате(ТекущаяДата(), "Месяц", 1).
Работает ли ДобавитьКДате в запросах и СКД?
Да, в языке запросов есть аналогичная функция ДОБАВИТЬКДАТЕ с типом периода без кавычек (ДЕНЬ, МЕСЯЦ, ГОД и др.). В СКД её можно использовать в вычисляемых полях и выражениях ресурсов наравне с другими функциями языка запросов.
Что важно запомнить
Две даты сложить нельзя — к дате прибавляют интервал. Секунды и дни — арифметикой (в сутках 86400 секунд), месяцы и годы — функцией ДобавитьКДате(), разность — вычитанием или РазностьДат(). Перед расчётом проверяйте заполненность даты и тестируйте граничные случаи: концы месяцев и високосный февраль.