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

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

Как получить вчерашнюю дату в 1С

Как получить вчерашнюю дату в 1С: работа с ТекущаяДатаСеанса, ДобавитьКДате, НачалоДня. Готовые примеры кода, типичные ошибки и проверка результата.

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

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

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

Базовый способ: вычитание секунд из текущей даты

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

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

Результат сохранит то же время суток, что и текущий момент. Если код выполнился в 14:32:15, то получится вчерашняя дата со временем 14:32:15. Для сравнений по дате без времени это неудобно, поэтому обычно дополнительно отсекают время функцией НачалоДня():

ВчерашняяДата = НачалоДня(ТекущаяДатаСеанса()) - 86400;

Такой вариант возвращает начало вчерашнего дня — 00:00:00. Это удобно для отбора документов за вчера: левая граница периода уже готова, а правую получают функцией КонецДня(ВчерашняяДата), которая даст 23:59:59 того же дня.

bsl
ВчерашняяДата = НачалоДня(ТекущаяДатаСеанса()) - 86400;
НачалоВчера = НачалоДня(ВчерашняяДата);
КонецВчера = КонецДня(ВчерашняяДата);
Сообщить("Вчера: " + Формат(ВчерашняяДата, "ДЛФ=D"));

Способ через ДобавитьКДате: когда он предпочтительнее

Функция ДобавитьКДате выполняет арифметику с учётом календаря, а не секунд. Синтаксис: ДобавитьКДате(Дата, Тип, Количество), где тип — единица измерения (ДЕНЬ, МЕСЯЦ, ГОД и другие), а количество может быть отрицательным.

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

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

Обратите внимание: функция возвращает дату с тем же временем суток. Чтобы получить именно начало вчерашнего дня, комбинируйте её с НачалоДня:

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

Сравнение вариантов

Вычитание 86400 секунд

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

ДобавитьКДате с типом ДЕНЬ

Календарная арифметика, удобна при масштабировании логики на недели и месяцы. Запись чуть длиннее.

ВЫБОР в запросе или ДобавитьКДате в выражении СКД

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

ТекущаяДата или ТекущаяДатаСеанса: что выбрать

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

Функция ТекущаяДатаСеанса() всегда возвращает время, согласованное с сервером, с учётом часового пояса сеанса. Именно её рекомендуется использовать в прикладном коде: в отчётах, обменах, регламентных заданиях и при записи дат в базу. Это исключает ситуацию, когда документы пользователя из другого региона попадают «не в тот» день.

Вчерашняя дата в запросах и отчётах СКД

В языке запросов нет прямого аналога ТекущаяДатаСеанса, поэтому дату вычисляют в коде и передают параметром. Это самый управляемый способ:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ

| Продажи.Номенклатура,

| СУММА(Продажи.СуммаОборот) КАК Сумма

|ИЗ РегистрНакопления.Продажи.Обороты(&НачалоВчера, &КонецВчера, , ) КАК Продажи

|СГРУППИРОВАТЬ ПО Продажи.Номенклатура";

ВчерашняяДата = НачалоДня(ТекущаяДатаСеанса()) - 86400;

Запрос.УстановитьПараметр("НачалоВчера", НачалоДня(ВчерашняяДата));

Запрос.УстановитьПараметр("КонецВчера", КонецДня(ВчерашняяДата));

В СКД аналогичный подход — параметры НачалоПериода и КонецПериода заполняются вычисляемыми выражениями или в событии ПриКомпоновкеРезультата. Для отчёта «за вчера», который запускается регламентным заданием ночью, важно решить, в какой момент фиксируется дата: при формировании отчёта, а не при его разработке.

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

Проверка результата и типичные ошибки

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

Распространённая ошибка — сравнение дат документов с вчерашней датой без учёта времени. Условие Документ.Дата = ВчерашняяДата почти никогда не сработает, потому что у документов дата содержит время. Корректно сравнивать через период: Документ.Дата МЕЖДУ &НачалоВчера И &КонецВчера или НачалоДня(Документ.Дата) = &ВчерашняяДата.

Типичные ошибки
01
Сравнение даты документа на равенство с вчерашней датой без отсечения времени — условие никогда не выполняется
02
Использование ТекущаяДата() на клиенте в клиент-серверной базе — разные часовые пояса дают разное вчера
03
Вычитание 86400 из даты с временем без НачалоДня — получается вчера с текущим временем, что ломает отборы за день
04
Вычисление даты в момент разработки отчёта вместо момента его формирования — период застывает

Граничные случаи: переход через месяц, год и полночь

Оба способа — и вычитание секунд, и ДобавитьКДате — корректно переносят дату через границу месяца и года: от 1 января получится 31 декабря прошлого года. Платформа выполняет календарную арифметику самостоятельно, вручную обрабатывать високосные годы не требуется.

Тонкий момент — регламентные задания, запускаемые около полуночи. Если задание стартует в 23:59, а расчёт выполняется после 00:00, «вчера» сместится на день относительно ожиданий. Для таких сценариев дату лучше вычислять один раз в начале процедуры и сохранять в переменную, а не вызывать ТекущаяДатаСеанса() повторно в разных местах кода.

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

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

Значение переменной с вчерашней датой
Норма

Вчерашний календарный день, время 00:00:00

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

Сегодняшняя дата или время отлично от 00:00:00

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

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

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

Нулевая дата или дата внутри текущего месяца

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

Попадают все документы вчерашнего дня до 23:59:59

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

Теряются документы, проведённые вечером

Запуск из разных часовых поясов
Норма

Результат одинаков для всех пользователей

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

У части пользователей смещён период

FAQ: частые вопросы о вчерашней дате в 1С

Как получить не только дату, но и время «ровно сутки назад»?

Вычтите 86400 секунд из ТекущаяДатаСеанса() без применения НачалоДня: ТекущаяДатаСеанса() - 86400. Получится вчерашняя дата с тем же временем суток, что и сейчас. Такой вариант подходит для скользящих интервалов, например «данные за последние 24 часа».

Можно ли вычислить вчерашнюю дату прямо в запросе без параметров?

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

Чем отличается НачалоДня от КонецДня при работе с вчерашней датой?

НачалоДня возвращает 00:00:00 указанной даты, КонецДня — 23:59:59. Для отбора за весь вчерашний день нужны обе границы: период МЕЖДУ НачалоДня(Вчера) И КонецДня(Вчера). Если использовать только начало дня, документы, проведённые днём и вечером, в выборку не попадут.

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

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

Почему в файловой базе всё работает, а в клиент-серверной дата смещается?

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

Итог

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

Вчерашняя дата вычисляется как НачалоДня(ТекущаяДатаСеанса()) - 86400 или через ДобавитьКДате с типом ДЕНЬ. Используйте ТекущаяДатаСеанса вместо ТекущаяДата, отсекайте время для отборов за день, передавайте дату в запросы параметром и вычисляйте её один раз в начале процедуры.