Работа с датами в 1С:Предприятие — одна из самых частых задач при разработке отчётов, обработок или автоматизации бизнес-процессов. Казалось бы, что может быть проще, чем вычесть из текущей даты один день? Однако даже эта операция таит подводные камни: от особенностей синтаксиса разных версий платформы до нюансов работы с временными зонами и неполными датами. В этой статье разберём 5 способов отнять день от текущей даты — от базовых функций до программных конструкций для сложных сценариев.

Вы узнаете, как правильно использовать встроенные методы ДобавитьДень() и НачалоДня(), почему иногда результат отличается от ожидаемого, и как избежать ошибок при работе с датами в 1С 8.3 и 1С 8.2. А также рассмотрим практические примеры для бухгалтерских отчётов, складских документов и кадрового учёта, где точная работа с датами критически важна.

1. Базовый способ: функция ДобавитьДень() с отрицательным значением

Самый очевидный и рекомендуемый способ — использование встроенной функции ДобавитьДень() с передачей отрицательного числа. Этот метод работает во всех современных версиях платформы 1С:Предприятие 8 и гарантирует корректный результат даже с учётом високосных годов и переходов на зимнее/летнее время.

Пример кода:

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

ВчерашняяДата = ДобавитьДень(ТекущаяДата, -1);

Особенности метода:

  • 🔹 Работает как с полными датами (включая время), так и с датами без времени.
  • 🔹 Автоматически корректирует месяц и год при переходе через границу (например, 1 января минус 1 день = 31 декабря предыдущего года).
  • 🔹 В 1С 8.3.20+ поддерживает миллисекундную точность, если передать дату с временем.
⚠️ Внимание: Если вы работаете с датами в формате ДатаВремя (например, для журналов документов), результат может включать текущее время. Чтобы получить "чистую" дату без времени, оберните результат в НачалоДня():
ВчерашняяДата = НачалоДня(ДобавитьДень(ТекущаяДата(), -1));

2. Альтернативный подход: арифметика с датами через оператор -

Платформа позволяет выполнять арифметические операции непосредственно с типами Дата, используя оператор вычитания. Этот способ лаконичнее, но требует понимания внутреннего представления дат в системе.

Пример:

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

ВчерашняяДата = ТекущаяДата - 86400; // 86400 секунд = 1 день

Когда этот метод уместен:

  • 📌 Для быстрых расчётов в обработках, где критична производительность.
  • 📌 При работе с большими массивами дат (например, в циклах по календарю).
Метод Преимущества Недостатки
ДобавитьДень() Читаемый код, автоматическая корректировка дат Незначительное снижение производительности при массовых операциях
Оператор - Максимальная скорость выполнения Менее наглядно, требует знания внутреннего формата дат
⚠️ Внимание: При вычитании секунд учитывайте переходы на зимнее/летнее время — в эти дни сутки могут содержать 23 или 25 часов. Для бухгалтерских отчётов лучше использовать ДобавитьДень().
📊 Какой способ вычитания дней вы используете чаще?
Встроенную функцию ДобавитьДень()
Оператор вычитания секунд
Другие методы
Не работал с датами в 1С

3. Работа с неполными датами и началом/концом дня

В часто требуется получить не просто "вчерашнюю дату", а начало или конец предыдущих суток. Например, для фильтрации документов за прошлый день в отчётах. Здесь пригодятся комбинации функций НачалоДня(), КонецДня() и ДобавитьДень().

Примеры:

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

НачалоВчера = НачалоДня(ДобавитьДень(ТекущаяДата(), -1));

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

КонецВчера = КонецДня(ДобавитьДень(ТекущаяДата(), -1));

Типичные сценарии применения:

  • 📊 Отбор документов за предыдущий рабочий день в отчётах по продажам.
  • 📋 Автоматическое создание заданий на следующий день в кадровом учёте.
  • 📈 Расчёт аналитики по сменам в производственных модулях.

Учтён ли переход на зимнее/летнее время?|Правильно ли обрабатываются граничные даты (1 января, 31 декабря)?|Совпадает ли результат с ручным расчётом для 3-5 тестовых дат?|Проведена ли валидация для високосных годов?-->

4. Вычитание дней в запросах 1С (Язык запросов)

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

Пример запроса для выборки документов за вчерашний день:

ВЫБРАТЬ

Документ.Ссылка КАК Ссылка,

Документ.Дата КАК Дата

ИЗ

Документ.ЗаказПокупателя КАК Документ

ГДЕ

Документ.Дата МЕЖДУ

НАЧАЛОДНЯ(ДОБАВИТЬКДАТЕ(ТЕКУЩАЯДАТА(), ДЕНЬ, -1))

И

КОНЕЦДНЯ(ДОБАВИТЬКДАТЕ(ТЕКУЩАЯДАТА(), ДЕНЬ, -1));

Ключевые моменты:

  • 🔧 В запросах нельзя использовать ТекущаяДата() — только ТЕКУЩАЯДАТА().
  • 🔧 Функция ДОБАВИТЬКДАТЕ() поддерживает добавление не только дней, но и месяцев, лет.
  • 🔧 Для фильтрации по датам всегда используйте НАЧАЛОДНЯ()/КОНЕЦДНЯ(), чтобы избежать проблем с временем.
Что будет, если не использовать НАЧАЛОДНЯ/КОНЕЦДНЯ в запросах?

Без этих функций сравнение дат может давать неожиданные результаты из-за хранения времени. Например, документ от 23:59:59 "вчера" не попадёт в выборку, если фильтр установлен на "Дата = Вчера" без учёта времени. Это приводит к пропуску документов в отчётах и ошибкам в аналитике.

5. Программное вычитание дней с учётом рабочего календаря

В бизнес-задачах часто требуется отнять не календарный, а рабочий день (исключая выходные и праздники). Для этого в используют Календарь или ПроизводственныйКалендарь.

Пример кода для получения предыдущего рабочего дня:

ПроизвКалендарь = Календари.ПроизводственныйКалендарь();

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

ПредыдущийРабочийДень = ПроизвКалендарь.ПредыдущийРабочийДень(ТекущаяДата);

Где это применяется:

  • 📅 Расчёт сроков доставки в модулях логистики.
  • 💼 Автоматическое продление задач в системах управления проектами.
  • 📉 Корректировка графиков платежей в бухгалтерии (если дата выпадает на выходной).
⚠️ Внимание: Производственный календарь в может отличаться от государственного — например, в некоторых компаниях суббота является рабочим днём. Всегда уточняйте настройки календаря в конкретной базе.
💡

Если в вашей конфигурации нет объекта "ПроизводственныйКалендарь", его можно создать самостоятельно или использовать внешнюю обработку с готовым календарём праздников России.

6. Обработка ошибок и особенности для разных версий 1С

Даже простая операция вычитания дня может давать сбои в зависимости от версии платформы или региональных настроек. Рассмотрим типичные проблемы и их решения.

Проблема 1: В 1С 8.2 функция ДобавитьДень() не поддерживает миллисекунды. Решение: Используйте ДобавитьСекунд() для точной работы с временем.

Проблема 2: При вычитании дня из Неопределённо возникает ошибка. Решение: Всегда проверяйте дату на заполненность:

Если НЕ ЗначениеЗаполнено(ИсходнаяДата) Тогда

Возврат Неопределено;

КонецЕсли;

Проблема 3: В облачных версиях (например, 1С:Fresh) могут быть ограничения на программное изменение дат. Решение: Используйте серверные процедуры или проверяйте права доступа.

Версия 1С Особенности работы с датами Рекомендации
8.2 Нет поддержки миллисекунд в ДобавитьДень() Используйте ДобавитьСекунд(Дата, -86400)
8.3.6–8.3.19 Поддержка миллисекунд, но возможны баги с временными зонами Проверяйте результаты на граничных датах (переход на зимнее время)
8.3.20+ Полная поддержка временных зон и высокоточных операций Можно использовать все описанные методы без ограничений
💡

Для критически важных расчётов (например, в бухгалтерских закрытиях) всегда тестируйте работу с датами на копии базы с реальными данными за прошлые периоды.

FAQ: Частые вопросы по работе с датами в 1С

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

Используйте функцию ДобавитьДень() с параметром -3:

ДатаМинусТриДня = ДобавитьДень(ТекущаяДата(), -3);

Или арифметический оператор:

ДатаМинусТриДня = ТекущаяДата() - (86400 * 3);
Почему при вычитании дня из 1 марта получаю 28 февраля, а не 29?

Это корректное поведение! Функция ДобавитьДень() учитывает реальную продолжительность месяцев. В невисокосный год февраль имеет 28 дней, поэтому 1 марта минус 1 день = 28 февраля. Для високосных годов результат будет 29 февраля.

Можно ли вычесть день из даты в формате строки?

Нет, сначала строку нужно преобразовать в тип Дата:

СтрокаДаты = "2026-12-31";

ДатаИзСтроки = Дата(СтрокаДаты);

Результат = ДобавитьДень(ДатаИзСтроки, -1);

Без преобразования возникнет ошибка несоответствия типов.

Как узнать, сколько дней между двумя датами?

Используйте функцию РазницаДней():

КоличествоДней = РазницаДней(Дата2, Дата1);

Если Дата2 позже Дата1, результат будет положительным.

Почему в отчёте не попадают документы за вчерашний день?

Скорее всего, в условии отбора не учтено время. Всегда используйте конструкцию:

ГДЕ Дата МЕЖДУ НачалоДня(Вчера) И КонецДня(Вчера)

Иначе документы с временем после 00:00 могут быть исключены.