Разработка и Конфигурация · 10 мин
Как сложить дату и время в 1С
Как сложить дату и время в 1С: прибавление секунд, дней и месяцев к дате, функции ДобавитьМесяц, работа с типом Дата, примеры кода и типичные ошибки.
В языке 1С нет отдельной арифметики «дата плюс дата», но сложение даты и времени решается стандартными средствами: оператором прибавления секунд, функцией ДобавитьМесяц и преобразованием строк в тип Дата. Понимание того, как платформа хранит дату, избавляет от большинства ошибок при расчётах сроков, графиков и периодов.
Тип Дата в 1С всегда содержит и дату, и время с точностью до секунды. Это значит, что «сложить дату и время» обычно означает одну из трёх задач: прибавить к дате определённое количество времени, объединить отдельно хранящиеся дату и время в одно значение или вычислить разницу между двумя моментами. Ниже разобраны все три сценария с примерами кода.
Как 1С хранит дату и время
Значение типа Дата в платформе — это единая величина, включающая календарную дату и время суток. Даже если вы видите в форме только «12.05.2026», внутри хранится и время, по умолчанию 00:00:00. Поэтому сравнение двух дат оператором «=» может неожиданно не сработать, если у одной из них время отлично от полуночи.
При арифметических операциях с датой единица измерения — секунда. Выражение Дата1 + 60 прибавляет одну минуту, Дата1 + 86400 — одни сутки. Вычитание двух дат (Дата2 - Дата1) возвращает разницу в секундах, что удобно для расчёта длительности.
Прибавление секунд, минут, часов и дней к дате
Самый простой способ сдвинуть дату — прибавить нужное количество секунд. Чтобы не держать в голове пересчёт, удобно умножать: 60 секунд в минуте, 3600 в часе, 86400 в сутках.
ИсходнаяДата = ТекущаяДата();
// Прибавить 15 минут
Через15Минут = ИсходнаяДата + 15 * 60;
// Прибавить 3 часа
Через3Часа = ИсходнаяДата + 3 * 3600;
// Прибавить 7 дней
ЧерезНеделю = ИсходнаяДата + 7 * 86400;
Такой подход корректно переносит результат через границы суток, месяцев и лет: платформа сама пересчитает календарную составляющую. Вычитание работает симметрично — ИсходнаяДата - 86400 вернёт тот же момент сутки назад.
Прибавление месяцев и лет: функция ДобавитьМесяц
Прибавлять месяцы через секунды нельзя: месяцы имеют разную длину, и «30 дней» не равно «одному месяцу». Для этого в языке есть функция ДобавитьМесяц(Дата, ЧислоМесяцев). Отрицательный второй аргумент отнимает месяцы.
// Прибавить 3 месяца
НоваяДата = ДобавитьМесяц(ИсходнаяДата, 3);
// Отнять 1 год (12 месяцев)
ГодНазад = ДобавитьМесяц(ИсходнаяДата, -12);
Важная особенность: если исходный день не существует в целевом месяце (например, 31 января плюс один месяц), функция вернёт последний день целевого месяца — в данном случае конец февраля. Учитывайте это при расчётах платежей и договорных сроков, где «тот же день через месяц» и «конец месяца» могут иметь разные юридические последствия.
Как объединить отдельные дату и время в одно значение
Частая практическая задача: дата хранится в одном реквизите (например, «ДатаОтгрузки»), а время — в другом («ВремяОтгрузки» в виде строки или числа). Сложить их напрямую оператором «+» нельзя — нужно собрать итоговое значение через функцию Дата() либо прибавить время к началу дня.
// Вариант 1: через функцию Дата с явными компонентами
ИтоговаяДата = Дата(Год(ДатаОтгрузки), Месяц(ДатаОтгрузки), День(ДатаОтгрузки),
ЧасВремя, МинутаВремя, 0);
// Вариант 2: прибавить секунды к началу дня
СекундСПолуночи = ЧасВремя 3600 + МинутаВремя 60;
ИтоговаяДата = НачалоДня(ДатаОтгрузки) + СекундСПолуночи;
Второй вариант короче и надёжнее, если время задано числом часов и минут. Если время хранится строкой вида «14:30», её сначала нужно разобрать: найти позицию двоеточия функцией СтрНайти(), извлечь части через Лев()/Сред() и преобразовать в числа функцией Число().
- 1Проверьте, в каком виде хранится время: число часов/минут или строка
- 2Если строка — разберите её на часы и минуты и преобразуйте в числа
- 3Возьмите НачалоДня() от даты, чтобы отсечь случайное время
- 4Прибавьте часы <em> 3600 + минуты </em> 60 + секунды
- 5Проверьте результат выводом в формате с временем: Формат(Результат, "ДЛФ=DT")
Вычисление разницы между датами
Обратная задача — узнать, сколько времени прошло между двумя моментами. Вычитание дат возвращает секунды, которые затем переводятся в нужные единицы делением.
РазницаСек = ДатаОкончания - ДатаНачала;
ЧасовМежду = Цел(РазницаСек / 3600);
ДнейМежду = Цел(РазницаСек / 86400);
Для разницы в календарных единицах (полных месяцах, кварталах) простое деление не подходит из-за разной длины месяцев. В типовых конфигурациях для этого есть функции общих модулей работы с датами, а в запросах — функция РАЗНОСТЬДАТ(), которая умеет считать разницу в заданной единице: секундах, минутах, часах, днях, месяцах.
Способы арифметики с датами
Подходит для минут, часов и точных интервалов. Ограничение: не подходит для месяцев и лет из-за разной длины месяцев.
Правильный способ прибавлять месяцы и годы. Учитывайте переход 31-го числа на последний день короткого месяца.
Оптимально для вычисления разницы между датами прямо в запросе без выборки данных в код.
Работа с датами в запросах
В языке запросов доступны свои инструменты: ДОБАВИТЬКДАТЕ(Дата, Тип, Количество) для сдвига даты и РАЗНОСТЬДАТ(Дата1, Дата2, Тип) для разницы. Тип задаётся ключевым словом: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, ГОД.
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(Заказ.ДатаОтгрузки, ДЕНЬ, 3) КАК ПлановаяДата,
РАЗНОСТЬДАТ(Заказ.Дата, &ТекущаяДата, ДЕНЬ) КАК ДнейСЗаказа
ИЗ
Документ.ЗаказПокупателя КАК Заказ
Использование функций запроса предпочтительнее постобработки в коде, когда данные нужны для отбора или сортировки: условие по вычисленному полю выполняется на стороне СУБД и не требует выгрузки лишних записей.
Типичные ошибки и проверка результата
Самая частая проблема — сравнение дат «в лоб», когда одна дата содержит время, а другая нет. Условие ДатаДокумента = ДатаОтбора не выполнится, если у документа время 10:25:00, а у отбора 00:00:00. Решение — сравнивать через НачалоДня() или использовать диапазон от начала до конца дня.
Вторая группа ошибок связана с пустыми датами. Пустая дата в 1С — это 01.01.0001 00:00:00, и арифметика с ней даст технически корректный, но бессмысленный результат. Перед расчётами проверяйте заполненность через ЗначениеЗаполнено().
Часовые пояса — отдельный источник расхождений в распределённых базах. Функция ТекущаяДата() возвращает время сервера при выполнении на сервере. Если пользователи работают в разных поясах, для унификации используют универсальное время или явно фиксируют пояс сеанса.
Как проверить результат
Формат(Результат, "ДЛФ=DT") показывает ожидаемые дату и время
Время 00:00:00 там, где должны быть часы и минуты — время потеряно при сборке
31.01 + 1 месяц даёт конец февраля — ожидаемое поведение ДобавитьМесяц
Результат попадает в март — вероятно, месяц прибавляли секундами
Сравнение через НачалоДня() срабатывает для одного календарного дня
Одинаковые на вид даты не равны — у одной есть время
Что важно запомнить
Дата в 1С — это дата плюс время с точностью до секунды. Секунды, минуты, часы и дни прибавляйте оператором «+», месяцы и годы — функцией ДобавитьМесяц, в запросах используйте ДОБАВИТЬКДАТЕ и РАЗНОСТЬДАТ. Перед расчётами проверяйте заполненность дат и не забывайте про время при сравнениях.
Частые вопросы
Как прибавить к дате один рабочий день, пропуская выходные?
Встроенной функции для рабочих дней нет. Обычно используют производственный календарь (регистр сведений в типовых конфигурациях): в цикле прибавляют по одному дню и проверяют, является ли день рабочим по календарю, пока не наберётся нужное количество рабочих дней.
Чем отличается ТекущаяДата() от ТекущаяДатаСеанса()?
ТекущаяДата() возвращает время того компьютера, где выполняется код (на сервере — время сервера). ТекущаяДатаСеанса() учитывает часовой пояс сеанса пользователя, поэтому для документов и отчётов, привязанных к локальному времени пользователя, предпочтительнее она.
Можно ли сложить две даты между собой?
Нет, операция «дата + дата» не имеет смысла и платформой не поддерживается. Складывать можно дату и число секунд. Если нужно объединить дату из одного значения и время из другого, берите НачалоДня() первой даты и прибавляйте секунды, прошедшие с начала дня второй.
Как получить из даты только время?
Вычтите из даты её начало дня: ВремяВСекундах = МояДата - НачалоДня(МояДата). Результат — число секунд с полуночи, которое можно разложить на часы и минуты делением на 3600 и 60. Для отображения используйте форматирование с шаблоном времени.
Почему ДобавитьМесяц(31.01, 1) не даёт 28 или 29 февраля «того же числа»?
Потому что 31 февраля не существует. Функция в таких случаях возвращает последний день целевого месяца. Если для бизнес-логики критичен именно день месяца (например, ежемесячный платёж 31-го), это поведение нужно обрабатывать отдельно в коде.
Как в запросе отобрать документы за конкретный день, если у дат есть время?
Используйте диапазон: условие Дата >= НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ) И Дата <= КОНЕЦПЕРИОДА(&Дата, ДЕНЬ). Это надёжнее, чем сравнение на равенство, которое не сработает из-за отличающегося времени.