Разработка и Конфигурация · 10 мин
Как получить конец дня в 1С
Как получить конец дня в 1С: функция КонецДня(), работа с датами в запросах, типичные ошибки с границами периода и примеры кода для разработчика.
В языке 1С дата хранится с точностью до секунды, поэтому «конец дня» — это не абстрактное понятие, а конкретное значение: 23:59:59 нужной календарной даты. Получить это значение встроенными средствами можно одной функцией — КонецДня(), и она доступна как в коде модулей, так и в языке запросов. Проблемы возникают не с самой функцией, а с тем, как её результат сравнивается с датами документов и как строятся границы периодов в отчётах.
Типичная ситуация: разработчик фильтрует документы условием Дата <= &КонецПериода, передаёт туда дату без времени (то есть 00:00:00) и теряет все документы, проведённые в течение последнего дня. Причина именно в том, что «голая» дата в 1С — это начало суток, а не их конец. Ниже разобраны все способы корректно получить конец дня, использовать его в запросах и проверить результат.
Функция КонецДня() во встроенном языке
Основной инструмент — встроенная функция КонецДня(Дата). Она принимает значение типа Дата и возвращает дату с временем 23:59:59 того же дня. Симметричная функция НачалоДня(Дата) возвращает 00:00:00. Обе доступны на клиенте и на сервере, не требуют контекста и работают в любой конфигурации.
ДатаДокумента = ТекущаяДатаСеанса();
КонецТекущегоДня = КонецДня(ДатаДокумента); // например, 15.03.2026 23:59:59
НачалоТекущегоДня = НачалоДня(ДатаДокумента); // 15.03.2026 0:00:00
Обратите внимание на источник даты: для получения «сегодня» в серверном коде корректно использовать ТекущаяДатаСеанса(), а не устаревшую ТекущаяДата(), которая на сервере возвращает дату сервера без учёта часового пояса сеанса и помечена как устаревшая. Из-за разницы часовых поясов «конец дня» по времени сервера и по времени пользователя могут оказаться разными календарными датами.
Если нужна дата произвольного дня, её можно сконструировать функцией Дата(Год, Месяц, День) и передать в КонецДня():
КонецЯнваря31 = КонецДня(Дата(2026, 1, 31)); // 31.01.2026 23:59:59
Конец дня в языке запросов
В запросах прямого аналога КонецДня() нет — вместо неё используется функция КОНЕЦПЕРИОДА(&Дата, ДЕНЬ). Первый параметр — дата или параметр запроса, второй — тип периода (СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД и другие). Для дня функция вернёт 23:59:59.
ВЫБРАТЬ
Реализация.Ссылка,
Реализация.Дата
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ) И КОНЕЦПЕРИОДА(&Дата, ДЕНЬ)
Такой запрос выберет все документы за один календарный день независимо от времени их проведения. Функция НАЧАЛОПЕРИОДА() работает зеркально и возвращает 00:00:00. Использование этих функций предпочтительнее ручной арифметики: запрос остаётся читаемым, а оптимизатор СУБД корректно обрабатывает такие условия.
КонецДня = КонецДня(ТекущаяДатаСеанса()); // 23:59:59 сегодня
// В запросе: ГДЕ Док.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ) И КОНЕЦПЕРИОДА(&Дата, ДЕНЬ)Конец дня в параметрах виртуальных таблиц
При обращении к виртуальным таблицам регистров (Остатки, Обороты, ОстаткиИОбороты) границы периода передаются через параметры. Здесь есть нюанс: если передать в параметр «Конец периода» значение КонецДня(Дата), движения, совершённые ровно в 23:59:59, будут учтены, но регистраторы с типичным временем документа попадают в выборку корректно. Однако более надёжный способ — использовать тип Граница с явным указанием включения.
ГраницаКонца = Новый Граница(КонецДня(Период), ВидГраницы.Включая);
Запрос.УстановитьПараметр("КонецПериода", ГраницаКонца);
Конструкция Новый Граница(Значение, ВидГраницы.Включая) гарантирует, что все движения до конца дня включительно попадут в результат, даже если по какой-то причине время движения окажется на границе. Это особенно важно для остатков: остаток «на конец дня» должен включать все документы этого дня.
Получение конца дня от произвольной даты и сдвиг дат
Часто нужен конец не сегодняшнего, а произвольного дня: вчерашнего, завтрашнего или даты из реквизита документа. Для сдвига дат в 1С применяется функция ДобавитьКДате(Дата, ТипСдвига, Количество). Она корректно обрабатывает переходы через месяцы и годы, в отличие от прибавления секунд числом.
КонецВчера = КонецДня(ДобавитьКДате(ТекущаяДатаСеанса(), "ДЕНЬ", -1));
КонецНедели = КонецНедели(ТекущаяДатаСеанса()); // воскресенье 23:59:59
Кроме КонецДня() существует семейство функций границ периодов: КонецЧаса(), КонецНедели(), КонецМесяца(), КонецКвартала(), КонецГода() и симметричные им функции начала. Все они возвращают 23:59:59 последнего дня соответствующего периода, что удобно для отчётов за месяц или квартал.
Конец дня для даты из строки или реквизита
Если дата приходит извне — из файла обмена, веб-сервиса или пользовательского ввода в виде строки — сначала преобразуйте её в тип Дата, а затем применяйте КонецДня(). Строковые сравнения дат в 1С недопустимы: «31.12.2026» как строка при сравнении даст лексикографический, а не хронологический порядок.
Типичные ошибки при работе с границей дня
Самая распространённая ошибка — передача в запрос даты без времени в качестве верхней границы. Условие Дата <= &КонецПериода, где параметр равен 15.03.2026 0:00:00, отсекает весь день 15 марта. Пользователь видит в отчёте «потерянные» документы, хотя физически они в базе есть.
Вторая ошибка — использование конструкции вида КонецДня(Дата) + 1 с последующим сравнением «строго меньше». Это рабочий приём (получается 00:00:00 следующего дня), но он менее читаем, чем КонецДня() с «меньше или равно», и при смешивании обоих подходов в одном коде легко получить двойной учёт граничной секунды.
Третья группа ошибок связана с часовыми поясами. Если пользователь работает в часовом поясе, отличном от сервера, «конец дня» документа, введённого пользователем, и конец дня по серверному времени могут различаться. В распределённых системах и при обмене данными это приводит к попаданию документа не в тот отчётный день.
Как проверить результат
Проверить значение, которое вернула функция, проще всего выводом в сообщение или в консоль кода с форматированием:
Сообщить(Формат(КонецДня(ТекущаяДатаСеанса()), "ДЛФ=DT"));
Формат ДЛФ=DT выводит дату с временем, и вы сразу видите, что время равно 23:59:59. Если выводится 00:00:00 — значит, вместо КонецДня() где-то использована исходная дата или НачалоДня().
Для проверки запроса возьмите тестовый документ, проведённый в середине дня (например, в 14:30), и убедитесь, что он попадает в выборку за этот день. Затем проверьте граничный случай: документ с ручной установкой времени 23:59:59. Оба должны присутствовать в результате.
Как проверить результат
Время равно 23:59:59 нужной даты
Время 00:00:00 — применена не та функция или дата без времени
Документы за весь день, включая вечерние, в выборке
Пропадают документы после 00:00 последнего дня
Учтены все движения дня, включая последний документ
Остаток не сходится с отчётом за день на сумму поздних документов
Выбор подхода под задачу
Для простого сравнения в коде достаточно КонецДня(). Для запросов по таблицам документов — КОНЕЦПЕРИОДА(&Дата, ДЕНЬ). Для виртуальных таблиц регистров — объект Граница с видом «Включая». Для отчётов на СКД период обычно задаётся стандартными параметрами НачалоПериода и КонецПериода, и СКД сама подставляет границы, но при ручной доработке запроса набора данных действуют те же правила.
Как выбрать действие
Что важно запомнить
Конец дня — это 23:59:59, и в 1С его даёт функция КонецДня() в коде и КОНЕЦПЕРИОДА(Дата, ДЕНЬ) в запросах. Для виртуальных таблиц регистров используйте Границу с видом «Включая». Главная ошибка — передача даты без времени как верхней границы периода.
Частые вопросы
Чем КонецДня() отличается от КОНЕЦПЕРИОДА()?
КонецДня() — функция встроенного языка, работает только с днями. КОНЕЦПЕРИОДА() — функция языка запросов, принимает тип периода (день, месяц, год и т.д.) и универсальнее. Для дня обе возвращают 23:59:59.
Почему в отчёт не попадают документы последнего дня?
Почти всегда причина в том, что в качестве конца периода передана дата без времени — то есть 00:00:00. Замените параметр на КонецДня(Дата) или используйте КОНЕЦПЕРИОДА(&Дата, ДЕНЬ) в запросе.
Можно ли получить конец дня прибавлением секунд к началу дня?
Технически да: НачалоДня(Дата) + 86399. Но это менее читаемо и чревато ошибками при сдвиге на другой день. Встроенная КонецДня() предпочтительнее.
Как получить конец вчерашнего дня?
КонецДня(ДобавитьКДате(ТекущаяДатаСеанса(), "ДЕНЬ", -1)). Функция ДобавитьКДате корректно обработает переход через границу месяца и года.
Учитывает ли КонецДня() часовой пояс пользователя?
Функция сама по себе работает с переданной датой и пояс не знает. Часовой пояс определяется тем, как получена исходная дата: ТекущаяДатаСеанса() учитывает пояс сеанса, а серверная дата — нет.
Что вернёт КонецДня(), если передать дату со временем?
Время будет отброшено, и функция вернёт 23:59:59 того же календарного дня, к которому относится переданная дата.