Разработка и Конфигурация · 9 мин
Как из даты вычесть день в 1С: рабочие способы и примеры
Как вычесть день из даты в 1С: операторы сложения с секундами, функция ДобавитьМесяц, работа в запросах с ДОБАВИТЬКДАТЕ. Примеры кода, ошибки и FAQ.
Вычесть день из даты в 1С — типовая задача, которая возникает при расчёте сроков оплаты, периодов отчётности, дат отгрузки и проверки документов «за вчера». Платформа 1С:Предприятие не имеет отдельной функции «минус один день», но предлагает несколько надёжных механизмов: арифметику с секундами, функции работы с датами в запросах и встроенные средства типовых конфигураций.
Ключевой момент, который нужно понять сразу: дата в 1С хранится с точностью до секунды, поэтому все арифметические операции с датами выполняются в секундах. Один день — это 86400 секунд (24 × 60 × 60). Именно на этом принципе строится самый распространённый способ вычитания дня.
Ниже разобраны все практические варианты: вычитание в коде встроенного языка, в запросах, в СКД, а также типичные ошибки с границами месяца и временем «конец дня», которые часто приводят к неверным срокам в документах и отчётах.
Как устроена дата в 1С и почему вычитают секунды
Тип «Дата» в 1С:Предприятие содержит календарную дату и время с точностью до секунды. Когда вы пишете выражение вида Дата1 - Дата2, результатом будет число — разность в секундах. Симметрично, если к дате прибавить или отнять число, оно интерпретируется как количество секунд.
Отсюда следует базовая формула: чтобы вычесть один день, нужно отнять 86400 секунд. Платформа сама корректно обрабатывает переход через границы месяца и года: если из 1 марта вычесть день, получится 28 или 29 февраля в зависимости от високосности года, а из 1 января — 31 декабря предыдущего года.
Способ 1: вычесть день арифметикой в коде
Самый простой и быстрый способ — вычесть из даты число секунд. Код выглядит так:
ИсходнаяДата = ТекущаяДатаСеанса();
ВчерашняяДата = ИсходнаяДата - 86400; // 24 60 60
Для читаемости кода часто записывают множитель явно: ИсходнаяДата - 24 60 60. Это то же самое значение, но при чтении сразу видно, что речь идёт об одних сутках. Некоторые разработчики выносят значение в константу или переменную СекундВДне = 86400, чтобы избежать «магических чисел» в больших модулях.
Важно помнить: если исходная дата содержит время, то результат сохранит то же время. Например, из «15.03 14:30:00» получится «14.03 14:30:00». Если нужна именно полночь вчерашнего дня, дополнительно примените НачалоДня():
НачалоВчера = НачалоДня(ТекущаяДатаСеанса() - 86400);
// Вычесть один день из даты
Вчера = ТекущаяДатаСеанса() - 86400;
НачалоВчера = НачалоДня(Вчера);
КонецВчера = КонецДня(Вчера);Способ 2: вычесть день в запросе через ДОБАВИТЬКДАТЕ
В языке запросов 1С арифметика с секундами недоступна — там используется функция ДОБАВИТЬКДАТЕ(Дата, ТипПериода, Количество). Чтобы вычесть день, передайте отрицательное количество:
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(&Дата, ДЕНЬ, -1) КАК ВчерашняяДата
Функция поддерживает типы периодов СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД. Это удобно, когда нужно сдвинуть дату не только на день, но и, например, на неделю или месяц назад — в коде для месяцев пришлось бы использовать отдельную функцию, а в запросе меняется лишь параметр.
Типовой сценарий — отбор документов за предыдущий день:
ВЫБРАТЬ
Реализация.Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Дата МЕЖДУ ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, -1) И &ТекущаяДата
Способ 3: ДобавитьМесяц и вспомогательные функции
Для сдвига на месяцы существует встроенная функция ДобавитьМесяц(Дата, КоличествоМесяцев). Она корректно обрабатывает разную длину месяцев: ДобавитьМесяц от 31 января с шагом минус один даст 31 декабря, а не несуществующую дату. Для вычитания именно дня она не предназначена, но полезна в связке при расчёте периодов.
Также полезны функции НачалоДня(), КонецДня(), НачалоНедели(), НачалоМесяца(). Частая задача «получить конец вчерашнего дня» решается двумя способами: КонецДня(Дата - 86400) или НачалоДня(Дата) - 1 — отнять одну секунду от начала текущего дня. Оба варианта дают 23:59:59 предыдущих суток.
Сравнение способов вычитания дня
Универсально для кода модулей. Быстро и просто, но нужно помнить про сохранение времени в дате.
Единственный способ внутри запроса и СКД. Читаемо, легко менять период с дня на неделю или месяц.
Подходит для получения конца предыдущего дня. Даёт 23:59:59, удобно для границ периодов отчётов.
Вычитание дня в типовых конфигурациях и СКД
В типовых решениях (1С:Бухгалтерия, Управление торговлей, ERP) в модулях общего назначения встречаются готовые процедуры для работы с датами, однако базовая операция «минус день» почти всегда выполняется через секунды. Если вы дорабатываете типовую конфигурацию, безопаснее использовать те же приёмы, что и код поставщика, — это упрощает обновление.
В схеме компоновки данных вычесть день можно двумя путями: в тексте запроса через ДОБАВИТЬКДАТЕ или в вычисляемом поле. Для вычисляемых полей СКД доступны функции языка выражений, но надёжнее выполнить сдвиг даты ещё в запросе — тогда поле сразу попадёт в набор данных с нужным типом «Дата».
При настройке отчёта «за вчера» удобно использовать стандартные периоды: параметр типа «СтандартныйПериод» с вариантом «Вчера» автоматически даёт границы от 00:00:00 до 23:59:59 предыдущего дня, и ручное вычитание вообще не требуется.
В регламентных заданиях и обменах данными для границы периода чаще используют НачалоДня(ТекущаяДатаСеанса()) - 1, а не КонецДня прошлых суток: так короче и меньше шанс ошибиться с типом значения.
Типичные ошибки и как их избежать
Первая распространённая ошибка — забыть, что дата содержит время. Выражение ДатаДокумента - 86400 сдвинет дату на сутки, но сохранит часы и минуты документа. Если дальше результат сравнивается с границей периода, отбор может «потерять» документы на стыке суток.
Вторая ошибка — ручной разбор даты на год, месяц и день с последующим вычитанием единицы из дня. При дне, равном 1, такой код вернёт несуществующую дату вида «0 марта» или вызовет исключение. Платформа сама умеет переходить через границы месяцев — не дублируйте эту логику вручную.
Третья ошибка — использование операции вычитания даты из даты там, где нужна дата. Выражение Дата1 - Дата2 возвращает число секунд, а не дату. Если результат присвоить реквизиту типа «Дата», получите ошибку несоответствия типов или неожиданное значение.
Проверка результата и граничные случаи
Проверить корректность вычитания проще всего на граничных датах: первое число месяца, 1 января, 1 марта в високосный и невисокосный год. Во всех случаях вычитание 86400 секунд должно дать последний день предыдущего периода. Быстрый тест можно выполнить через команду «Вычислить выражение» в конфигураторе или через консоль кода.
Отдельно проверяйте логику, где от результата зависят деньги или обязательства: сроки оплаты по договору, даты резервирования товара, периоды в кадровых приказах. Ошибка в одни сутки в таких местах приводит к нарушению сроков и расхождениям с контрагентами, поэтому изменения в расчёте дат стоит тестировать на копии базы.
Как проверить результат
Получен последний день предыдущего месяца
Ошибка выполнения или несуществующая дата
Время соответствует задаче: сохранено или сброшено через НачалоДня()
В отбор попадают или теряются документы на границе суток
Выбраны все документы от 00:00:00 до 23:59:59 вчерашнего дня
Документы начала или конца суток отсутствуют в выборке
Что важно запомнить
В коде 1С день вычитается как 86400 секунд, в запросах — через ДОБАВИТЬКДАТЕ с параметром -1. Следите за временем внутри даты и не разбирайте дату на компоненты вручную: платформа сама корректно переходит через границы месяцев и лет.
Частые вопросы
Как вычесть из даты не один, а несколько дней?
Умножьте число секунд в сутках на нужное количество дней: Дата - 3 * 86400 вычтет три дня. В запросе передайте количество параметром: ДОБАВИТЬКДАТЕ(&Дата, ДЕНЬ, -&КоличествоДней).
Как получить вчерашнюю дату без времени?
Используйте НачалоДня(ТекущаяДатаСеанса() - 86400). Результат — полночь предыдущих суток, 00:00:00. Для конца вчерашнего дня примените КонецДня() к тому же выражению.
Чем отличается ТекущаяДата() от ТекущаяДатаСеанса() при вычитании дня?
ТекущаяДатаСеанса() возвращает время сервера с учётом часового пояса сеанса и предпочтительна в клиент-серверном режиме. ТекущаяДата() берёт время компьютера, где выполняется код, что на клиенте может отличаться от серверного времени и сдвинуть «вчера» на сутки у пользователей из других часовых поясов.
Можно ли вычесть день из даты в формуле печатной формы или макета?
В макетах и шаблонах вычисления недоступны — вычислите дату заранее в модуле и передайте готовое значение как параметр области. В схеме СКД сдвиг делайте в запросе через ДОБАВИТЬКДАТЕ.
Что вернёт выражение «дата минус дата» в 1С?
Число — разность между датами в секундах. Чтобы получить разность в днях, разделите результат на 86400. Обратите внимание: наличие времени внутри дат может дать дробное число дней, при необходимости округлите или предварительно примените НачалоДня() к обеим датам.
Как вычесть рабочий день, а не календарный?
Штатных средств для рабочих дней нет — используйте регистр «Регламентированный производственный календарь» (в типовых конфигурациях) или собственный календарь: найдите ближайшую предыдущую дату с видом дня «Рабочий». Простое вычитание 86400 секунд здесь не подойдёт, так как не учитывает выходные и праздники.