Разработка и Конфигурация · 9 мин
Как в 1С от текущей даты отнять день
Как в 1С от текущей даты отнять день: функция ТекущаяДата, сдвиг на 86400 секунд, ДобавитьКДате, работа с датами в запросах и на форме. Примеры кода и типичные ошибки.
Задача «от текущей даты отнять день» возникает в 1С постоянно: при формировании отчётов за вчерашний день, при расчёте сроков оплаты, при отборе документов за прошлый период. Во встроенном языке 1С дата хранится с точностью до секунды, поэтому вычитание выполняется не специальной функцией «минус день», а арифметикой секунд либо универсальной функцией ДобавитьКДате.
Простейший рабочий вариант — вычесть из текущей даты 86400 секунд (24 × 60 × 60). Это корректно для большинства прикладных задач, но имеет нюансы при переходе через границу месяца и при работе с началом дня. Ниже разобраны все основные способы, их ограничения и типичные ошибки.
Как 1С хранит дату и почему вычитаются секунды
Тип «Дата» в 1С хранит значение с точностью до секунды: год, месяц, день, часы, минуты, секунды. Арифметические операции с датами работают именно в секундах: если к дате прибавить число, оно интерпретируется как количество секунд. Поэтому выражение ТекущаяДата() - 1 отнимет не один день, а одну секунду — это самая частая ошибка начинающих разработчиков.
Чтобы вычесть один полный день, нужно вычесть 86400 секунд (24 часа × 60 минут × 60 секунд). Для читаемости кода константу часто записывают как произведение: 24 60 60 — так сразу видно, что речь идёт о сутках, а компилятор вычислит значение автоматически.
Вчера = ТекущаяДата() - 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 марта минус один месяц даст последний день февраля, а не несуществующую дату.
Для вычитания одного дня оба способа эквивалентны по результату. Выбирайте ДобавитьКДате, если логика может расшириться до недель, месяцев или лет — код останется единообразным.
Сравнение способов
Быстро и просто для суток. Не подходит для месяцев и лет из-за разной длины периодов.
Универсально: дни, недели, месяцы, годы. Корректно обрабатывает границы месяцев. Чуть длиннее запись.
Используется, когда сдвиг даты нужен прямо в тексте запроса, без выгрузки данных в код.
Вычитание дня в запросе 1С
Если дату нужно сдвинуть внутри запроса — например, отобрать документы за вчерашний день или вычислить дату отгрузки — используется функция языка запросов ДОБАВИТЬКДАТЕ(Дата, ТипЕдиницы, Количество).
ВЫБРАТЬ
Реализация.Ссылка,
Реализация.Дата
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Дата МЕЖДУ &НачалоВчера И &КонецВчера
Параметры в этом случае вычисляются в коде до выполнения запроса:
Запрос.УстановитьПараметр("НачалоВчера", НачалоДня(ТекущаяДатаСеанса() - 86400));
Запрос.УстановитьПараметр("КонецВчера", КонецДня(ТекущаяДатаСеанса() - 86400));
Передавать границы периода параметрами предпочтительнее, чем вычислять их функциями внутри запроса: так запрос проще отлаживать, а СУБД эффективнее использует индексы по дате.
Отнять день от даты в реквизите или на форме
На практике чаще требуется отнять день не от текущей даты, а от даты документа или реквизита формы. Подход тот же, но важно помнить о типе значения: если реквизит имеет состав даты «Дата» (без времени), время всё равно присутствует и равно 00:00:00, поэтому вычитание секунд работает корректно.
// В модуле объекта документа
ДатаОтгрузки = Дата - 86400;
// В модуле формы
Объект.ДатаПлановойОплаты = ДобавитьКДате(Объект.Дата, "ДЕНЬ", -1);
Если вычитание выполняется в обработчике на клиенте (например, ПриИзменении), функция ДобавитьКДате доступна и в тонком клиенте — серверный вызов не требуется. Это удобно для интерактивных пересчётов без лишних обращений к серверу.
- 1Откройте обработку или внешнюю обработку с кодом, либо используйте консоль кода
- 2Выполните: Сообщить(ТекущаяДатаСеанса() - 86400);
- 3Сравните выведенную дату с текущей — разница должна составлять ровно сутки
- 4Проверьте граничный случай: подставьте дату 1-го числа месяца и убедитесь, что результат — последний день предыдущего месяца
Граничные случаи и типичные ошибки
Переход через начало месяца и года обрабатывается автоматически: от 1 марта минус 86400 секунд даст 28 (или 29) февраля. Проблемы возникают не в арифметике, а в логике применения.
Рабочие и календарные дни — разные вещи. «Отнять один день» всегда даёт предыдущие календарные сутки. Если нужно получить предыдущий рабочий день с учётом производственного календаря, простой арифметики недостаточно: потребуется обращение к регистру «РегламентированныйПроизводственныйКалендарь» (в типовых конфигурациях) или к справочнику графиков работы.
Ещё один подводный камень — сравнение дат с разным временем. Условие ДатаДокумента = ТекущаяДата() - 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. Для отборов за прошлые сутки всегда применяйте НачалоДня и КонецДня, а в клиент-серверном режиме используйте ТекущаяДатаСеанса(). Для месяцев и лет — только ДобавитьКДате, для рабочих дней — производственный календарь.