Разработка и Конфигурация · 10 мин
Как в 1С к дате прибавить часы
Как в 1С прибавить часы к дате: сложение с секундами, функция ДобавитьКДате, работа с часовыми поясами. Примеры кода, типичные ошибки и проверка результата.
Дата в 1С хранится с точностью до секунды, поэтому «прибавить часы» всегда означает одно и то же действие: добавить к значению типа Дата нужное количество секунд. Час — это 3600 секунд, и простейший рабочий вариант выглядит так: НоваяДата = СтараяДата + Часы * 3600;. Этот приём работает во всех версиях платформы и не требует никаких дополнительных библиотек.
Второй штатный способ — функция ДобавитьКДате(), которая умеет добавлять не только часы, но и минуты, дни, месяцы и годы с корректной обработкой переходов через границы периодов. Выбор между двумя подходами зависит от задачи: для простого сдвига в пределах суток достаточно сложения, а для универсального механизма сдвигов удобнее специализированная функция.
Ниже разобраны оба способа с примерами кода, показано, как прибавлять часы в запросах, как учитывать часовые пояса и какие ошибки чаще всего приводят к неверному результату.
Как устроен тип Дата в 1С и почему часы складывают через секунды
Тип Дата в платформе 1С содержит календарную дату и время с точностью до секунды. Внутренне это значение, к которому можно прибавлять и вычитать числа — и число всегда интерпретируется как количество секунд. Поэтому выражение Дата + 1 сдвигает дату ровно на одну секунду, а не на один день, как ошибочно ожидают многие начинающие разработчики.
Из этого правила вытекает простая арифметика: одна минута — 60 секунд, один час — 3600 секунд, одни сутки — 86400 секунд. Чтобы прибавить, например, 5 часов к текущей дате, достаточно написать ТекущаяДатаСеанса() + 5 * 3600. При выходе за границу суток платформа сама корректно перенесёт значение на следующий день, месяц или год — отдельно обрабатывать переход не нужно.
Вычитание двух дат тоже возвращает результат в секундах. Это удобно для контроля: если нужно проверить, что сдвиг выполнен правильно, вычтите исходную дату из итоговой и разделите на 3600 — должно получиться исходное число часов.
Способ 1: сложение даты с числом секунд
Самый короткий и универсальный метод — прямое сложение. Он работает в любом контексте: на клиенте, на сервере, в тонком и веб-клиенте, в любой версии платформы 8.x. Пример:
ИсходнаяДата = ТекущаяДатаСеанса();
КоличествоЧасов = 8;
НоваяДата = ИсходнаяДата + КоличествоЧасов * 3600;
Для читаемости кода константу 3600 часто выносят в именованную переменную или функцию. Если сдвиг в часах используется в нескольких местах модуля, удобно оформить небольшую функцию-обёртку:
Функция ПрибавитьЧасы(Дата, Часы)
Возврат Дата + Часы * 3600;
КонецФункции
Отрицательное значение часов работает симметрично: Дата + (-3) * 3600 отнимет три часа. Это позволяет использовать одну и ту же конструкцию и для сдвига назад, не вводя отдельную операцию вычитания.
Ограничение способа — он сдвигает строго на физические секунды. Если требуется «календарная» логика (например, прибавить месяц с учётом разного числа дней), сложение не подходит — понадобится ДобавитьКДате().
Способ 2: функция ДобавитьКДате()
Встроенная функция ДобавитьКДате(Дата, Тип, Количество) добавляет к дате заданное число единиц указанного типа. Для часов второй параметр принимает значение "Час" (или "Hour" в английском синтаксисе):
НоваяДата = ДобавитьКДате(ИсходнаяДата, "Час", 6);
Функция корректно обрабатывает переходы через границы суток, месяцев и лет. Например, добавление 5 часов к 22:00 даст 03:00 следующего дня без дополнительного кода. Отрицательное количество отнимает часы.
Заодно ДобавитьКДате() поддерживает типы Секунда, Минута, День, Неделя, Месяц, Квартал, Год, поэтому её удобно применять в универсальных механизмах, где единица сдвига задаётся настройкой. Для простого «плюс N часов» оба способа равнозначны по результату; разница лишь в читаемости и универсальности кода.
Сравнение вариантов
Подходит для простого сдвига на часы или минуты; работает везде; не решает календарные задачи вроде добавления месяцев.
Удобна, когда единица сдвига задаётся параметром или нужны месяцы и годы; чуть длиннее запись.
Единственный вариант, когда сдвиг нужно выполнить на стороне СУБД без обхода выборки в коде.
Как прибавить часы к дате в запросе
В языке запросов 1С сложение даты с числом недоступно, поэтому используется функция ДОБАВИТЬКДАТЕ(Дата, Тип, Количество). Тип указывается ключевым словом без кавычек: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ и так далее.
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(Заказы.ДатаОтгрузки, ЧАС, 12) КАК Дедлайн
ИЗ
Документ.ЗаказПокупателя КАК Заказы
Такой приём полезен, когда сдвинутая дата нужна прямо в выборке — например, для расчёта крайнего срока, фильтрации по окну времени или соединения таблиц по интервалу. Количество может быть и выражением, в том числе отрицательным.
Учитывайте, что сдвиг выполняется на сервере СУБД, и значения дат в базе хранятся, как правило, в едином часовом поясе сеанса записи. Если в запросе сравниваются даты из разных источников, убедитесь, что все они приведены к одному поясу, иначе сдвиг даст обманчиво «правильный», но фактически неверный результат.
НоваяДата = ДобавитьКДате(ТекущаяДатаСеанса(), "Час", 4);Часовые пояса: когда простое сложение даёт неверный результат
Функция ТекущаяДата() возвращает время компьютера, на котором выполняется код, поэтому в клиент-серверном режиме результат на клиенте и на сервере может различаться. Для прикладной логики рекомендуется ТекущаяДатаСеанса() — она приводится к часовому поясу сеанса и даёт согласованные значения.
Если нужно получить время в другом часовом поясе — например, московское время при сервере в другом регионе — используются функции работы с датами и поясами: МестноеВремя(), УниверсальноеВремя(), ТекущаяУниверсальнаяДата(). Прибавление часов к универсальному времени безопасно, а вот «ручной» сдвиг локального времени на разницу поясов ломается при переводе часов или смене правил пояса.
Проверка результата и типичные ошибки
Проверить сдвиг проще всего разностью дат: вычтите исходное значение из итогового и разделите на 3600. Если получили исходное количество часов без дробной части — сдвиг выполнен верно. Для визуального контроля выведите обе даты через Формат(Дата, "ДЛФ=DT"), чтобы видеть и день, и время.
Частая ошибка — прибавление часов к дате с «обрезанным» временем. Например, функция НачалоДня(Дата) возвращает 00:00:00, и если разработчик ожидал текущее время, а получил полночь, итоговый сдвиг окажется не тем. Перед сложением всегда проверяйте, какое именно время содержит исходное значение.
Вторая распространённая проблема — пустая дата (01.01.0001 00:00:00) в реквизите. Прибавление часов к пустой дате выполнится без ошибки, но результат будет бессмысленным. Перед расчётом стоит проверять ЗначениеЗаполнено(Дата) и обрабатывать пустое значение отдельно.
Как проверить результат
Целое число, равное количеству добавленных часов
Дробное значение или ноль — сдвиг выполнен неверно
Ожидаемое время (например, текущее)
00:00:00 там, где должно быть реальное время
Дата корректно перешла на следующие сутки
Время изменилось, а день остался прежним
Практические сценарии использования
Типовая задача — расчёт крайнего срока: например, реакция на заявку в течение 4 рабочих часов. Если учёт не завязан на производственный календарь, достаточно ДатаПоступления + 4 * 3600. Если же часы должны быть именно рабочими, простым сложением не обойтись — потребуется график работы и цикл по интервалам.
Другой сценарий — округление и нормализация времени перед сдвигом. Например, чтобы получить «следующий час от начала текущего», комбинируют НачалоЧаса() и сложение: НачалоЧаса(ТекущаяДатаСеанса()) + 3600. Аналогично работают КонецЧаса(), НачалоМинуты() и родственные функции.
При обмене данными со внешними системами часы часто добавляют для приведения времени к формату контрагента. Здесь важно зафиксировать в коде, в каком поясе хранятся даты в базе, и выполнять сдвиг один раз в одном месте — размазанные по модулям поправки «плюс N часов» быстро приводят к двойным сдвигам.
Что важно запомнить
Часы к дате в 1С прибавляют через секунды: Дата + Часы * 3600, либо функцией ДобавитьКДате(Дата, "Час", N), а в запросах — ДОБАВИТЬКДАТЕ(Дата, ЧАС, N). Перед расчётом проверяйте время в исходной дате, пустые значения и часовой пояс; правильность сдвига контролируйте разностью дат.
Частые вопросы
Как отнять часы от даты в 1С?
Используйте отрицательное количество: Дата - Часы * 3600 или ДобавитьКДате(Дата, "Час", -Часы). Оба варианта корректно обрабатывают переход через полночь в обратную сторону.
Почему Дата + 1 не прибавляет день?
Арифметика с датами в 1С работает в секундах, поэтому Дата + 1 добавляет одну секунду. Для суток используйте 86400 секунд или ДобавитьКДате(Дата, "День", 1).
Как прибавить часы к дате в запросе 1С?
Примените функцию языка запросов ДОБАВИТЬКДАТЕ: ДОБАВИТЬКДАТЕ(Поле.Дата, ЧАС, 3). Тип интервала пишется без кавычек, количество может быть отрицательным или вычисляемым выражением.
Чем ТекущаяДата() отличается от ТекущаяДатаСеанса() при расчётах?
ТекущаяДата() возвращает время того компьютера, где выполняется код, а ТекущаяДатаСеанса() — время, приведённое к часовому поясу сеанса. В клиент-серверном режиме для прикладных расчётов надёжнее ТекущаяДатаСеанса(), иначе результаты на клиенте и сервере могут различаться.
Как прибавить только рабочие часы, а не календарные?
Простым сложением это не решается: потребуется график работы (производственный календарь или регистр с интервалами) и цикл, который проходит по рабочим периодам, накапливая нужное количество часов. Готовой встроенной функции для рабочих часов в платформе нет.
Что будет, если прибавить часы к пустой дате?
Ошибки не возникнет: пустая дата (01.01.0001 00:00:00) просто сдвинется на указанное число секунд. Такой результат обычно бессмысленен и может испортить отборы и отчёты, поэтому перед расчётом проверяйте реквизит через ЗначениеЗаполнено().