Разработка и Конфигурация · 8 мин
Как в 1С из даты вычесть секунду
Как в 1С вычесть секунду из даты: арифметика с типом Дата, функция ДобавитьМесяц, работа в запросах с РАЗНОСТЬДАТ и ДОБАВИТЬКДАТЕ, типичные ошибки.
В языке 1С дата хранится с точностью до секунды, и самый простой способ вычесть секунду — обычное арифметическое вычитание: НоваяДата = ИсходнаяДата - 1;. Единица в таком выражении означает именно одну секунду, потому что при сложении и вычитании даты с числом платформа трактует число как количество секунд.
Эта задача встречается чаще, чем кажется: при подборе границы периода «по конец дня включительно», при построении интервалов без пересечений, при работе с последовательностями документов и при сравнении моментов времени. Ошибка в одну секунду способна включить лишний документ в отчёт или, наоборот, потерять его.
Ниже разобраны все рабочие способы: встроенный язык, язык запросов, границы периодов, а также ограничения и типичные ошибки, которые приводят к неверным результатам.
Вычитание секунды во встроенном языке
Тип «Дата» в 1С поддерживает арифметические операции с числами. Выражение Дата - Число возвращает новую дату, смещённую назад на указанное количество секунд. Результат — тоже значение типа «Дата», исходная переменная не изменяется.
ИсходнаяДата = Дата(2026, 5, 15, 12, 0, 0);
НоваяДата = ИсходнаяДата - 1; // 15.05.2026 11:59:59
Если нужно вычесть больше одной секунды, число просто умножается: минута — 60 секунд, час — 3600, сутки — 86400. Например, ИсходнаяДата - 86400 вернёт ту же дату минус одни сутки.
Обратная операция — вычитание двух дат — возвращает число секунд между ними: Разница = Дата2 - Дата1;. Это удобно для проверки результата: разница между исходной и полученной датой должна равняться единице.
Вычитание секунды в запросе
В языке запросов арифметика с датами напрямую недоступна — нельзя написать Дата - 1. Вместо этого используется функция ДОБАВИТЬКДАТЕ с отрицательным значением:
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(&Дата, СЕКУНДА, -1) КАК ДатаМинусСекунда
Первый параметр — исходная дата или поле даты, второй — единица измерения (СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ и так далее), третий — целое количество единиц, которое может быть отрицательным.
Для проверки разницы между датами в запросе служит функция РАЗНОСТЬДАТ(Дата1, Дата2, СЕКУНДА) — она возвращает число секунд между двумя моментами. С её помощью легко убедиться, что смещение выполнено корректно.
Практический пример: документы строго раньше заданного момента
ВЫБРАТЬ
Реализация.Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Дата <= ДОБАВИТЬКДАТЕ(&Граница, СЕКУНДА, -1)
Такой отбор выбирает документы, дата которых меньше заданной границы, не прибегая к оператору «меньше» по составному моменту времени. Учтите, что у документов с одинаковой датой порядок определяется ссылкой, поэтому для строгой хронологии лучше использовать тип «МоментВремени».
Типовой сценарий: конец дня и границы периода
Самая частая причина вычитать секунду — получить последний момент предыдущего дня или сформировать правую границу интервала вида «с начала месяца по конец месяца включительно». Классический приём: КонецПериода = НачалоДня(СледующийДень) - 1;.
Однако для конца дня есть штатная функция КонецДня(Дата), которая возвращает 23:59:59 указанной даты. Она читабельнее и не требует ручного вычитания. Аналогично существуют НачалоДня, КонецМесяца, НачалоМесяца, КонецГода и другие функции границ.
Сравнение вариантов
Универсально, работает с любой датой и любым смещением в секундах. Требует аккуратности при пересчёте минут и часов.
Лучший вариант для границы «по конец дня». Не подходит для произвольного смещения.
Единственный способ сместить дату прямо в запросе. Работает только с целыми единицами заданного типа.
Для смещения на месяцы и годы, где секундная арифметика неприменима из-за разной длины месяцев.
Почему нельзя вычитать месяцы и дни через секунды
Вычитание секунд корректно для коротких интервалов, но опасно для длинных. Месяц содержит разное число дней (28–31), а в сутках при переходе на летнее время в некоторых регионах может быть не 86400 секунд с точки зрения локального времени. Поэтому Дата - 30 * 86400 — не то же самое, что «минус месяц».
Для календарных смещений используйте функцию ДобавитьМесяц(Дата, -1) — она корректно обрабатывает конец месяца: из 31 марта получится 28 или 29 февраля, а не несуществующая дата. После смещения на месяц секундную корректировку можно применить уже арифметикой.
Работа с границами и моментом времени
При построении интервалов документов часто нужна не просто дата, а граница с контролем включительности. Тип «Граница» позволяет указать вид: ВидГраницы.Включая или ВидГраницы.Исключая. Это избавляет от ручного вычитания секунды при отборах по регистрам.
ГраницаИнтервала = Новый Граница(МоментВремениДокумента, ВидГраницы.Исключая);
Если же вы работаете только с датами документов (без момента времени), помните: несколько документов могут иметь одинаковую дату с точностью до секунды. Вычитание секунды отсечёт все документы с этой датой целиком, а не только «более поздние». Для строгого порядка используйте метод документа МоментВремени().
Проверка результата
Простейшая проверка — вычислить разность: Разница = ИсходнаяДата - НоваяДата; должна дать ровно 1. Если получилось другое число, где-то в цепочке вычислений дата была дополнительно преобразована, например функцией НачалоДня.
При отладке выводите обе даты через Сообщить() или в табло отладчика в полном формате с временем. Частая ситуация: разработчик видит только дату без времени в форме и не замечает, что смещение уже выполнено ранее в коде.
Как проверить результат
Равна 1 секунде
0, 60 или другое число — где-то лишнее преобразование
Дата заполнена
Пустая дата 01.01.0001 — вычитание даст некорректный результат
Время сместилось на секунду назад, день меняется только при переходе через полночь
Сброс времени в 00:00:00 — значит, применялось НачалоДня
Частые вопросы
Можно ли вычесть из даты полсекунды или миллисекунды?
Нет. Тип «Дата» в 1С хранит значения с точностью до одной секунды, дробная часть отсутствует. Для измерений с миллисекундами используйте ТекущаяУниверсальнаяДатаВМиллисекундах() и числовой тип.
Что будет, если вычесть секунду из 01.01.0001 00:00:00?
Получится значение за нижней границей допустимого диапазона дат. Такая дата некорректно отображается и может вызвать ошибки при записи в базу или обмене. Перед вычитанием проверяйте заполненность даты.
Как вычесть секунду в запросе, если дата — параметр?
Передайте дату параметром и примените функцию: ДОБАВИТЬКДАТЕ(&Дата, СЕКУНДА, -1). Альтернатива — вычесть секунду в коде до выполнения запроса и передать уже готовую дату, что часто проще и читабельнее.
Чем отличается вычитание секунды от функции КонецДня?
КонецДня(Дата) всегда возвращает 23:59:59 указанной даты независимо от исходного времени. Вычитание секунды смещает ровно на одну секунду от текущего значения. Для границы «конец дня» предпочтительнее КонецДня — она не зависит от того, что было во входном параметре.
Почему после вычитания секунды документ всё равно попадает в отбор?
Вероятная причина — у документа та же дата с точностью до секунды, что и у границы, и отбор построен по дате, а не по моменту времени. Несколько документов могут иметь одинаковую дату. Используйте МоментВремени() или тип Граница с видом Исключая.
Как вычесть минуту, час или сутки?
Тем же вычитанием числа секунд: минута — 60, час — 3600, сутки — 86400. Например, Дата - 3600 вернёт дату на час раньше. Для месяцев и лет используйте ДобавитьМесяц с отрицательным аргументом.
Что важно запомнить
Секунда вычитается простой арифметикой: Дата - 1. В запросах — ДОБАВИТЬКДАТЕ с отрицательным значением. Для конца дня используйте КонецДня, для месяцев — ДобавитьМесяц, для строгой хронологии документов — момент времени и границы. Всегда проверяйте заполненность исходной даты перед вычитанием.