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

Разработка и Конфигурация · 9 мин

Как в 1С от текущей даты отнять день

Как в 1С от текущей даты отнять день: функция ТекущаяДата, сдвиг на 86400 секунд, ДобавитьКДате, работа с датами в запросах и на форме. Примеры кода и типичные ошибки.

Задача «от текущей даты отнять день» возникает в 1С постоянно: при формировании отчётов за вчерашний день, при расчёте сроков оплаты, при отборе документов за прошлый период. Во встроенном языке 1С дата хранится с точностью до секунды, поэтому вычитание выполняется не специальной функцией «минус день», а арифметикой секунд либо универсальной функцией ДобавитьКДате.

Простейший рабочий вариант — вычесть из текущей даты 86400 секунд (24 × 60 × 60). Это корректно для большинства прикладных задач, но имеет нюансы при переходе через границу месяца и при работе с началом дня. Ниже разобраны все основные способы, их ограничения и типичные ошибки.

Как 1С хранит дату и почему вычитаются секунды

Тип «Дата» в 1С хранит значение с точностью до секунды: год, месяц, день, часы, минуты, секунды. Арифметические операции с датами работают именно в секундах: если к дате прибавить число, оно интерпретируется как количество секунд. Поэтому выражение ТекущаяДата() - 1 отнимет не один день, а одну секунду — это самая частая ошибка начинающих разработчиков.

Чтобы вычесть один полный день, нужно вычесть 86400 секунд (24 часа × 60 минут × 60 секунд). Для читаемости кода константу часто записывают как произведение: 24 60 60 — так сразу видно, что речь идёт о сутках, а компилятор вычислит значение автоматически.

bsl
Вчера = ТекущаяДата() - 86400;
// или нагляднее:
Вчера = ТекущаяДата() - 24 <em> 60 </em> 60;

Способ 1: вычитание секунд из ТекущаяДата()

Функция ТекущаяДата() возвращает текущую дату и время сеанса. В клиент-серверном режиме в серверном коде рекомендуется использовать ТекущаяДатаСеанса(), чтобы избежать расхождений из-за часового пояса клиентского компьютера.

Пример получения вчерашней даты и начала вчерашнего дня:

ТекущаяДатаСеанса = ТекущаяДатаСеанса();

Вчера = ТекущаяДатаСеанса - 86400;

НачалоВчера = НачалоДня(Вчера); // 00:00:00 вчерашнего дня

КонецВчера = КонецДня(Вчера); // 23:59:59 вчерашнего дня

Обратите внимание: если текущее время — 14:30, то ТекущаяДата() - 86400 вернёт вчерашние 14:30, а не начало дня. Для отборов документов за вчерашний день почти всегда нужны именно НачалоДня() и КонецДня(), иначе часть документов выпадет из выборки.

Способ 2: функция ДобавитьКДате

Функция ДобавитьКДате(Дата, ТипЕдиницы, Количество) сдвигает дату на заданное количество единиц: секунд, минут, часов, дней, месяцев, лет. Для вычитания передаётся отрицательное количество.

Вчера = ДобавитьКДате(ТекущаяДатаСеанса(), "ДЕНЬ", -1);

НеделюНазад = ДобавитьКДате(ТекущаяДатаСеанса(), "ДЕНЬ", -7);

МесяцНазад = ДобавитьКДате(ТекущаяДатаСеанса(), "МЕСЯЦ", -1);

Главное преимущество перед вычитанием секунд — корректная работа с месяцами и годами. Выражение Дата - 30 * 86400 не равно «минус один месяц», потому что месяцы имеют разную длину. ДобавитьКДате учитывает календарь: например, от 31 марта минус один месяц даст последний день февраля, а не несуществующую дату.

Для вычитания одного дня оба способа эквивалентны по результату. Выбирайте ДобавитьКДате, если логика может расшириться до недель, месяцев или лет — код останется единообразным.

Сравнение способов

Дата - 86400

Быстро и просто для суток. Не подходит для месяцев и лет из-за разной длины периодов.

ДобавитьКДате(Дата, "ДЕНЬ", -1)

Универсально: дни, недели, месяцы, годы. Корректно обрабатывает границы месяцев. Чуть длиннее запись.

РАЗНОСТЬДАТ и ДОБАВИТЬКДАТЕ в запросе

Используется, когда сдвиг даты нужен прямо в тексте запроса, без выгрузки данных в код.

Вычитание дня в запросе 1С

Если дату нужно сдвинуть внутри запроса — например, отобрать документы за вчерашний день или вычислить дату отгрузки — используется функция языка запросов ДОБАВИТЬКДАТЕ(Дата, ТипЕдиницы, Количество).

ВЫБРАТЬ

Реализация.Ссылка,

Реализация.Дата

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

ГДЕ

Реализация.Дата МЕЖДУ &НачалоВчера И &КонецВчера

Параметры в этом случае вычисляются в коде до выполнения запроса:

Запрос.УстановитьПараметр("НачалоВчера", НачалоДня(ТекущаяДатаСеанса() - 86400));

Запрос.УстановитьПараметр("КонецВчера", КонецДня(ТекущаяДатаСеанса() - 86400));

Передавать границы периода параметрами предпочтительнее, чем вычислять их функциями внутри запроса: так запрос проще отлаживать, а СУБД эффективнее использует индексы по дате.

Отнять день от даты в реквизите или на форме

На практике чаще требуется отнять день не от текущей даты, а от даты документа или реквизита формы. Подход тот же, но важно помнить о типе значения: если реквизит имеет состав даты «Дата» (без времени), время всё равно присутствует и равно 00:00:00, поэтому вычитание секунд работает корректно.

// В модуле объекта документа

ДатаОтгрузки = Дата - 86400;

// В модуле формы

Объект.ДатаПлановойОплаты = ДобавитьКДате(Объект.Дата, "ДЕНЬ", -1);

Если вычитание выполняется в обработчике на клиенте (например, ПриИзменении), функция ДобавитьКДате доступна и в тонком клиенте — серверный вызов не требуется. Это удобно для интерактивных пересчётов без лишних обращений к серверу.

Как проверить результат в конфигураторе
  1. 1
    Откройте обработку или внешнюю обработку с кодом, либо используйте консоль кода
  2. 2
    Выполните: Сообщить(ТекущаяДатаСеанса() - 86400);
  3. 3
    Сравните выведенную дату с текущей — разница должна составлять ровно сутки
  4. 4
    Проверьте граничный случай: подставьте дату 1-го числа месяца и убедитесь, что результат — последний день предыдущего месяца

Граничные случаи и типичные ошибки

Переход через начало месяца и года обрабатывается автоматически: от 1 марта минус 86400 секунд даст 28 (или 29) февраля. Проблемы возникают не в арифметике, а в логике применения.

Рабочие и календарные дни — разные вещи. «Отнять один день» всегда даёт предыдущие календарные сутки. Если нужно получить предыдущий рабочий день с учётом производственного календаря, простой арифметики недостаточно: потребуется обращение к регистру «РегламентированныйПроизводственныйКалендарь» (в типовых конфигурациях) или к справочнику графиков работы.

Ещё один подводный камень — сравнение дат с разным временем. Условие ДатаДокумента = ТекущаяДата() - 86400 почти никогда не выполнится, потому что секунды совпадут только случайно. Сравнивайте через НачалоДня() или используйте диапазон.

Типичные ошибки
01
Вычитание единицы вместо 86400 — отнимается одна секунда, а не день
02
Сравнение дат на равенство без НачалоДня() — из-за различий в секундах условие не срабатывает
03
Использование ТекущаяДата() на клиенте в многочасовом режиме работы — у пользователей разных поясов получаются разные «вчера»
04
Отбор документов за вчера без НачалоДня/КонецДня — часть документов выпадает из выборки
05
Расчёт «минус месяц» через 30 * 86400 — результат смещается из-за разной длины месяцев

Проверка результата

После внедрения кода проверьте три контрольные точки: обычный день, первое число месяца и первое января. Для отладки удобно временно подставить фиксированную дату вместо ТекущаяДатаСеанса():

ТестоваяДата = Дата(2026, 3, 1, 10, 0, 0);

Результат = ТестоваяДата - 86400; // должно получиться 29.02.2026 10:00:00

Если результат используется в отборе документов, откройте полученный отчёт или выборку и убедитесь, что в неё попали документы с 00:00:00 до 23:59:59 вчерашнего дня и не попали документы сегодняшнего.

Контрольные точки

Как проверить результат

Разница с текущей датой
Норма

Ровно 24 часа (сутки)

Тревожный признак

Разница в секундах или несколько суток — ошибка в константе

Первое число месяца
Норма

Получается последний день предыдущего месяца

Тревожный признак

Некорректная или пустая дата

Отбор документов за вчера
Норма

Попадают все документы с 00:00:00 до 23:59:59

Тревожный признак

Выпадают утренние или вечерние документы — не применены НачалоДня/КонецДня

FAQ

Почему ТекущаяДата() - 1 не отнимает день?

Потому что арифметика дат в 1С работает в секундах. Единица — это одна секунда. Для вычитания суток нужно вычесть 86400 или использовать ДобавитьКДате(Дата, "ДЕНЬ", -1).

Как получить начало вчерашнего дня?

Используйте вложенные функции: НачалоДня(ТекущаяДатаСеанса() - 86400). Результат — вчерашняя дата со временем 00:00:00, что удобно для отборов в запросах.

Как отнять день от даты документа, а не от текущей?

Точно так же: ДатаДокумента - 86400 или ДобавитьКДате(ДатаДокумента, "ДЕНЬ", -1). Состав даты реквизита (с временем или без) на результат не влияет.

Чем отличается вычитание 86400 от ДобавитьКДате с параметром "ДЕНЬ"?

Для одного дня результат идентичен. Различия проявляются на месяцах и годах: ДобавитьКДате учитывает календарную длину периода, а умножение секунд — нет. Для дней выбирайте любой вариант, для месяцев и лет — только ДобавитьКДате.

Как получить предыдущий рабочий день, а не календарный?

Простым вычитанием это не решается. Нужно обратиться к производственному календарю (в типовых конфигурациях — регистр сведений с данными календаря) и в цикле сдвигать дату назад, пока не найдётся рабочий день.

Что использовать вместо ТекущаяДата() в клиент-серверном режиме?

В серверном коде — ТекущаяДатаСеанса(). Она возвращает время сервера с учётом часового пояса сеанса, что исключает расхождения между пользователями из разных регионов.

Итог

Что важно запомнить

День в 1С отнимается вычитанием 86400 секунд или функцией ДобавитьКДате с параметром "ДЕНЬ" и значением -1. Для отборов за прошлые сутки всегда применяйте НачалоДня и КонецДня, а в клиент-серверном режиме используйте ТекущаяДатаСеанса(). Для месяцев и лет — только ДобавитьКДате, для рабочих дней — производственный календарь.