Работа с датами в 1С:Предприятие — одна из самых востребованных задач при разработке отчётов, обработок и автоматизации бизнес-процессов. Чаще всего требуется посчитать разницу между двумя датами: для расчёта просрочек, сроков выполнения заказов, возраста клиентов или длительности проектов. Однако даже опытные программисты иногда сталкиваются с нюансами: как учесть только рабочие дни, как избежать ошибок при переходе на зимнее время, или как получить разницу не в днях, а в часах или месяцах.

В этой статье мы разберём 5 основных способов вычитания дат в 1С 8.3 и 8.2 — от элементарных функций до сложных алгоритмов с учётом производственного календаря. Вы узнаете, как:

  • 📅 Использовать встроенные функции Дата1 - Дата2 и ДеньГода() для базовых расчётов
  • ⏳ Получать разницу в часах, минутах и секундах с учётом временных зон
  • 🏢 Вычитать даты с учётом рабочих дней и праздников (включая региональные)
  • 🔍 Применять запросы для массовой обработки дат в таблицах
  • ⚙️ Писать универсальные функции для повторного использования в коде

Все примеры протестированы на актуальных релизах платформы 1С:Предприятие 8.3.22 и совместимы с большинством конфигураций (Бухгалтерия 3.0, УТ 11, ЗУП 3.1, КА 2.4). Если вы работаете со старыми версиями (8.1 или 8.0), некоторые методы могут требовать адаптации.

📊 Как часто вам приходится работать с датами в 1С?
Ежедневно
Несколько раз в неделю
Редко, по необходимости
Никогда

1. Базовое вычитание дат: функция разницы в днях

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

Пример кода:

ДатаНачала = '2026-05-10 14:30:00';

ДатаОкончания = '2026-05-15 09:15:00';

РазницаВДнях = ДатаОкончания - ДатаНачала;

В переменной РазницаВДнях окажется значение 4.71875 (4 дня, 17 часов и 15 минут). Чтобы получить целое число дней, используйте функцию Цел():

Цел(РазницаВДнях); // Вернёт 4
⚠️ Внимание: При вычитании дат не учитывает рабочие/выходные дни. Если вам нужна разница только по рабочим дням, используйте методы из раздела 4.

Этот метод подходит для:

  • 📊 Расчёта сроков выполнения задач (например, время обработки заказа)
  • 📈 Построения графиков по временным интервалам
  • 🔄 Автоматического определения просроченных документов
ФункцияОписаниеПример результата
Дата1 - Дата2Разница в днях (дробное число)'2026-05-15' - '2026-05-10'5
Цел(Дата1 - Дата2)Целое количество днейЦел('2026-05-15 12:00' - '2026-05-10')5
Окр(Дата1 - Дата2, 2)Округлённая разница (например, до часов)Окр('2026-05-10 18:00' - '2026-05-10 09:00', 2)0.38 (9 часов)

2. Разница в часах, минутах и секундах

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

РазницаВЧасах = (ДатаОкончания - ДатаНачала) * 24;

Для минут и секунд используйте коэффициенты 1440 (минут в дне) и 86400 (секунд в дне) соответственно. Пример:

ДатаНачала = '2026-05-10 10:00:00';

ДатаОкончания = '2026-05-10 16:30:00';

// Разница в часах, минутах и секундах

Часы = (ДатаОкончания - ДатаНачала) * 24; // 6.5

Минуты = (ДатаОкончания - ДатаНачала) * 1440; // 390

Секунды = (ДатаОкончания - ДатаНачала) * 86400; // 23400

Для удобства вывода можно использовать функцию Формат():

Сообщить(Формат(Часы, "Ч=0.00; ЧД=0")); // Выведет "6.50"
💡

Чтобы избежать ошибок при работе с временными зонами, всегда храните даты в формате ДатаВремя (а не Дата), даже если время не используется. Это гарантирует корректные расчёты при переходе на зимнее/летнее время.

Особенности работы с временем:

  • учитывает временные зоны, если они настроены в информационной базе. Например, разница между '2026-03-31 01:00:00' и '2026-03-31 03:00:00' в Москве составит 1 час (из-за перехода на летнее время).
  • ⚡ Для высокоточных расчётов (например, в логистике) используйте Миллисекунды():
Миллисекунды = (ДатаОкончания - ДатаНачала)  86400  1000;
⚠️ Внимание: При работе с серверами в разных временных зонах разница между датами может отличаться на ±N часов. Всегда синхронизируйте серверное время или используйте UTC.

3. Вычитание дат с учётом только рабочих дней

Для расчёта разницы с учётом рабочих дней (исключая выходные и праздники) в есть два подхода:

  1. Использовать встроенный Календарь (доступен в конфигурациях ЗУП, КА, ERP).
  2. Создать собственную функцию с учётом производственного календаря.

Пример с использованием Календаря (для ЗУП 3.1):

Календарь = Календари.РабочийКалендарьОрганизации(Организация);

РазницаВРабочихДнях = Календарь.РазницаВДнях(ДатаНачала, ДатаОкончания);

Если в вашей конфигурации нет готового календаря, напишите универсальную функцию:

Функция РазницаВРабочихДнях(ДатаНачала, ДатаОкончания, МассивПраздников = Неопределено)

Если МассивПраздников = Неопределено Тогда

МассивПраздников = Новый Массив;

// Добавляем стандартные праздники (пример для России)

МассивПраздников.Добавить('2026-01-01'); // Новый год

МассивПраздников.Добавить('2026-05-01'); // Первомай

// ... остальные праздники

КонецЕсли;

ТекущаяДата = НачалоДня(ДатаНачала);

КонецДата = НачалоДня(ДатаОкончания);

РабочиеДни = 0;

Пока ТекущаяДата <= КонецДата Цикл

ДеньНедели = ДеньНедели(ТекущаяДата);

Если ДеньНедели <> 6 И ДеньНедели <> 7 И НЕ МассивПраздников.Найти(Формат(ТекущаяДата, "ДЛФ=Д")) Тогда

РабочиеДни = РабочиеДни + 1;

КонецЕсли;

ТекущаяДата = ТекущаяДата + 86400; // +1 день

КонецЦикла;

Возврат РабочиеДни;

КонецФункции;

Добавить все региональные праздники в массив|Учесть переносы выходных (если есть)|Проверить корректность временных зон|Обработать крайние случаи (например, ДатаНачала > ДатаОкончания)-->

Пример вызова функции:

Праздники = Новый Массив;

Праздники.Добавить('2026-05-09'); // День Победы

РабочиеДни = РазницаВРабочихДнях('2026-05-01', '2026-05-15', Праздники);

// Вернёт 9 (с 1 по 15 мая 2026 года 9 рабочих дней)

Для автоматизации можно загружать праздники из внешних источников (например, с сайта КонсультантПлюс) или использовать готовые обработки из Infostart.

4. Вычитание дат в запросах 1С

Если вам нужно посчитать разницу между датами для большого количества записей (например, в отчёте по просроченным платежам), используйте запросы . Это значительно ускорит обработку данных.

Пример запроса для расчёта количества дней между датой документа и текущей датой:

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

Запрос.Текст =

"ВЫБРАТЬ

| ДокументСсылка КАК Ссылка,

| ДокументДата КАК ДатаДокумента,

| ТЕКУЩАЯДАТА() КАК ТекущаяДата,

| ДЕНЬГОДА(ТЕКУЩАЯДАТА()) - ДЕНЬГОДА(ДокументДата) КАК РазницаВДнях

|ИЗ

| Документ.ЗаказПокупателя КАК Документ

|ГДЕ

| Документ.ПометкаУдаления = ЛОЖЬ

| И Документ.Дата < ТЕКУЩАЯДАТА()";

Результат = Запрос.Выполнить();

Для более сложных расчётов (например, разницы в часах) используйте конструкцию РАЗНИЦАДАТ():

"ВЫБРАТЬ

| РАЗНИЦАДАТ(Документ.ДатаОплаты, Документ.ДатаОтгрузки, ЧАС) КАК РазницаВЧасах

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Документ"

Особенности работы с датами в запросах:

  • 🔹 Функция РАЗНИЦАДАТ() поддерживает параметры ДЕНЬ, ЧАС, МИНУТА, СЕКУНДА.
  • 🔹 Для фильтрации по диапазону дат используйте МЕЖДУ:
  • 🔹 В временных таблицах даты хранятся без учёта временной зоны — это может привести к ошибкам при сравнении.
Как ускорить запрос с датами?

Используйте индексы по полям с датами в регистрах и документах. Например, для таблицы Документ.ЗаказПокупателя создайте индекс по полю Дата. Это ускорит фильтрацию по диапазону дат в 10-100 раз.

Функция запросаОписаниеПример
ТЕКУЩАЯДАТА()Возвращает текущую дату и время на сервереГДЕ Дата < ТЕКУЩАЯДАТА()
НАЧАЛОПЕРИОДА()Возвращает начало дня/недели/месяцаНАЧАЛОПЕРИОДА(Дата, "МЕСЯЦ")
ДОБАВИТЬКДАТЕ()Прибавляет интервал к датеДОБАВИТЬКДАТЕ(Дата, ДЕНЬ, 7)
РАЗНИЦАДАТ()Разница между датами в заданных единицахРАЗНИЦАДАТ(Дата2, Дата1, ЧАС)

5. Учёт временных зон и летнего времени

Если ваша информационная база работает в распределённой инфраструктуре (например, сервер в Москве, а пользователи в Владивостоке), разница между датами может отличаться из-за временных зон. учитывает эти настройки, но есть нюансы:

Пример проблемы: если на сервере (UTC+3) записана дата '2026-05-10 23:00:00', а пользователь в Хабаровске (UTC+10) открывает её в 6:00 следующего дня, то разница между "сейчас" и датой на сервере составит 31 час вместо ожидаемых 7.

Чтобы избежать ошибок:

  1. Настройте временную зону в параметрах информационной базы (Администрирование → Настройки программы → Общие настройки).
  2. Используйте УниверсальноеВремя() для хранения дат в UTC:
ДатаUTC = УниверсальноеВремя(ТекущаяДата());

ДатаЛокальная = ЛокальноеВремя(ДатаUTC);

Для расчёта разницы с учётом временных зон:

Функция РазницаСУчетомВременныхЗон(Дата1, Дата2, ЧасовойПояс1, ЧасовойПояс2)

Дата1UTC = УниверсальноеВремя(Дата1, ЧасовойПояс1);

Дата2UTC = УниверсальноеВремя(Дата2, ЧасовойПояс2);

Возврат Дата2UTC - Дата1UTC;

КонецФункции;

💡

Всегда храните даты в базе в формате UTC, а преобразование в локальное время выполняйте только при отображении пользователю. Это исключит ошибки при миграции серверов или изменении временных зон.

Пример вызова:

Разница = РазницаСУчетомВременныхЗон(

'2026-05-10 23:00:00',

'2026-05-11 06:00:00',

Новый ЧасовойПояс(3, 0), // UTC+3 (Москва)

Новый ЧасовойПояс(10, 0) // UTC+10 (Хабаровск)

);

// Вернёт 0.291666... (7 часов)

6. Практическое применение: примеры из реальных задач

Рассмотрим 3 типичные задачи, где требуется вычитание дат в , и готовые решения для них.

Задача 1. Расчёт просрочки оплаты по счёту:

Процедура РассчитатьПросрочку(ДокументСчет)

ТекущаяДата = ТекущаяДата();

ДатаОплаты = ДокументСчет.ДатаОплаты;

Если ДатаОплаты = '0001-01-01' Тогда // Не оплачен

ДнейПросрочки = Цел(ТекущаяДата - ДокументСчет.Дата);

Если ДнейПросрочки > 0 Тогда

Сообщить(Формат("Просрочка: %1 дней", ДнейПросрочки));

КонецЕсли;

КонецЕсли;

КонецПроцедуры;

Задача 2. Определение возраста клиента (в годах):

Функция ВозрастВГодах(ДатаРождения)

Возврат Цел((ТекущаяДата() - ДатаРождения) / 365.25);

КонецФункции;

Задача 3. Расчёт времени выполнения заказа (с учётом рабочих дней):

Функция ВремяВыполненияЗаказа(ДатаСоздания, ДатаВыполнения)

Календарь = Календари.РабочийКалендарьОрганизации(ТекущаяОрганизация());

Возврат Календарь.РазницаВДнях(ДатаСоздания, ДатаВыполнения);

КонецФункции;

Для автоматизации подобных расчётов рекомендуем:

  • 📂 Создавать ОбщиеМодули с часто используемыми функциями (например, РазницаВРабочихДнях()).
  • 📊 Использовать РегистрыСведений для хранения производственных календарей (это ускорит доступ к данным).
  • 🔄 Тестировать функции на крайних случаях (например, даты до 1900 года или переход через границу года).

FAQ: Частые вопросы по вычитанию дат в 1С

Как вычесть из даты 3 месяца, учитывая разное количество дней в месяцах?

Используйте функцию ДобавитьМесяц():

НоваяДата = ДобавитьМесяц(ТекущаяДата(), -3);

Эта функция корректно обрабатывает переходы между месяцами с разным количеством дней (например, 31 января → 30 апреля).

Почему при вычитании дат получается отрицательное число?

Отрицательный результат означает, что Дата1 позже Дата2. Например:

'2026-05-10' - '2026-05-15' // Вернёт -5

Чтобы избежать ошибок, всегда проверяйте порядок дат:

Если Дата1 > Дата2 Тогда

Разница = Дата1 - Дата2;

Иначе

Разница = Дата2 - Дата1;

КонецЕсли;

Как посчитать разницу между датами в минутах с точностью до секунды?

Умножьте разницу в днях на количество минут в дне (1440) и округлите:

РазницаВМинутах = Окр((Дата2 - Дата1) * 1440, 2);

Для секунд используйте коэффициент 86400.

Можно ли в 1С посчитать разницу между датами с учётом только рабочих часов (например, с 9:00 до 18:00)?

Да, но для этого потребуется написать кастомную функцию, которая:

  1. Разобьёт интервал на дни.
  2. Для каждого дня проверит, попадает ли время в рабочий интервал (например, 9:00–18:00).
  3. Просуммирует только рабочие часы.

Пример кода:

Код функции для рабочих часов

Функция РазницаВРабочихЧасах(ДатаНачала, ДатаОкончания, НачалоРабочегоДня = 9, КонецРабочегоДня = 18)

// Логика разбиения интервала на дни и учёта рабочих часов

// ...

КонецФункции;

Как в отчёте 1С отобразить разницу между датами в формате "X дней Y часов"?

Используйте комбинацию функций Цел() и Окр():

Дней = Цел(РазницаВДнях);

Часов = Окр((РазницаВДнях - Дней) * 24, 0);

Результат = Формат("Дней: %1, Часов: %2", Дней, Часов);