Вычисление разницы между датами — одна из самых распространённых задач в 1С:Предприятие, которая возникает при работе с отчётами, расчётами зарплаты, сроками выполнения задач или анализом временных интервалов. Казалось бы, что может быть проще: взять две даты и вычесть одну из другой. Но в этот процесс имеет нюансы, зависящие от формата хранения дат, требуемой точности (дни, часы, минуты) и контекста использования (запросы, встроенный язык, отчёты).

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

Материал актуален для платформ 1С:Предприятие 8.3 и 8.2, но некоторые примеры могут требовать адаптации под конкретные конфигурации (например, Бухгалтерия 3.0, ЗУП 3.1 или УТ 11). Если вы работаете с 1С:ERP или отраслевыми решениями, проверьте наличие специализированных функций для работы с датами в документации.

1. Базовый метод: функция РазностьДат()

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

РазностьДат(Дата2, Дата1, ЕдиницаИзмерения)

Где:

  • 📅 Дата2 — более поздняя дата (конечная)
  • 📅 Дата1 — более ранняя дата (начальная)
  • ЕдиницаИзмерения — строка с указанием единицы: "День", "Час", "Минута" или "Секунда"

Пример вычисления количества дней между 1 января и 10 января 2026 года:

КоличествоДней = РазностьДат('20260110', '20260101', "День");

// Результат: 9

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

Особенности функции:

  • 🔹 Работает с типами данных Дата и строками в формате "ГГГГММДД" или "ГГГГММДДччммсс"
  • 🔹 При передаче времени (например, '20260110120000') учитывает часы, минуты и секунды
  • 🔹 Возвращает целое число (округляет дробные значения)

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

2. Альтернативный подход: арифметические операции с датами

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

Пример:

ДатаНачала = '20260101080000'; // 1 января 2026, 8:00

ДатаОкончания = '20260102103000'; // 2 января 2026, 10:30

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

// Результат: 1.10416666666667 (1 день и ~2.5 часа)

Чтобы преобразовать результат в часы или минуты, умножьте на соответствующий коэффициент:

  • 🕒 Часы: РазницаВДнях * 2426.5 часов
  • ⏱️ Минуты: РазницаВДнях 24 601590 минут

⚠️ Внимание: При прямом вычитании дат не учитываются временные зоны. Если в вашей базе данные хранятся в UTC, а отображаются в локальном времени, результат может быть искажён на ± несколько часов.

Преимущества метода:

  • 🔹 Точность: сохраняет дробную часть (время)
  • 🔹 Производительность: работает быстрее, чем РазностьДат(), в циклах
  • 🔹 Гибкость: легко конвертировать в любые единицы

💡

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

3. Работа с датами в запросах 1С

В Запросах 1С для вычисления разности дат используются функции ДОБАВИТЬКДАТЕ() и арифметические операции. Однако синтаксис здесь отличается от встроенного языка.

Пример запроса, который возвращает разницу в днях между датой документа и текущей датой:

ВЫБРАТЬ

ДокументСклад.Дата КАК ДатаДокумента,

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

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

ИЗ

Документ.ПоступлениеТоваров КАК ДокументСклад

ГДЕ

ДокументСклад.Дата > ДОБАВИТЬКДАТЕ(ТЕКУЩАЯДАТА(), МЕСЯЦ, -1)

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

  • 📆 ТЕКУЩАЯДАТА() — возвращает текущую дату сервера
  • 🔢 ДЕНЬ(Выражение) — извлекает количество дней из разницы
  • ДОБАВИТЬКДАТЕ(Дата, Интервал, Количество) — сдвигает дату на заданный период

Функция Пример Результат
ГОД(Дата) ГОД('20260115') 2026
МЕСЯЦ(Дата) МЕСЯЦ('20260115') 1
ДЕНЬ(Дата) ДЕНЬ('20260115') 15
НАЧАЛОПЕРИОДА(Дата, Интервал) НАЧАЛОПЕРИОДА('20260115', "МЕСЯЦ") '20260101'

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

  • 🔹 Формат даты: в запросах даты указываются в кавычках: '20260115'
  • 🔹 Временная зона: все даты приводятся к серверному времени
  • 🔹 Производительность: вычисления в запросе оптимизированы для больших выборок

☑️ Подготовка запроса с датами

Выполнено: 0 / 4

4. Расчёт разницы в рабочих днях (с учётом праздников)

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

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

Функция РабочиеДни(ДатаНачала, ДатаОкончания)

Дни = ДатаОкончания - ДатаНачала;

Выходные = Цел(Дни / 7) * 2; // 2 выходных в неделю

Если ДеньНедели(ДатаОкончания) = 6 Тогда // Суббота

Выходные = Выходные + 1;

ИначеЕсли ДеньНедели(ДатаОкончания) = 7 Тогда // Воскресенье

Выходные = Выходные + 1;

КонецЕсли;

Если ДеньНедели(ДатаНачала) = 7 Тогда // Начало в воскресенье

Выходные = Выходные - 1;

КонецЕсли;

Возврат Дни - Выходные;

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

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

  • 📅 Создать справочник праздничных дат (например, Справочник.Праздники)
  • 🔄 Добавить в функцию проверку на попадание даты в этот справочник
  • 📊 Использовать Запрос для выборки праздников в заданном интервале

⚠️ Внимание: Алгоритмы учёта рабочих дней зависят от региональных особенностей. Например, в некоторых странах выходной не суббота/воскресенье, а пятница/суббота. Всегда уточняйте правила у заказчика!

Готовые решения:

  • 🔧 Библиотека стандартных подсистем (БСП): содержит функции для работы с производственными календарями
  • 📦 Внешние обработки: на Инфостарте или 1С-Галлерее есть готовые календари с праздниками до 2030 года
  • 🛠️ Самостоятельная доработка: если праздников мало, их можно жёстко прописать в коде

Пример учёта праздников в коде

Для проверки даты на праздничность можно использовать такой запрос:

ВЫБРАТЬ РАЗРЕШЕННЫЕ

КалендарьПраздников.Дата КАК Дата

ИЗ

Справочник.Праздники КАК КалендарьПраздников

ГДЕ

КалендарьПраздников.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания

Затем из общей разницы дней вычитаем количество найденных праздников.

5. Сложные сценарии: разность дат с учётом времени суток

Иногда требуется посчитать разницу между датами только в рамках рабочего времени. Например, если офис работает с 9:00 до 18:00, а задача была создана в 17:50, то следующие 10 минут не должны учитываться как "рабочее время".

Алгоритм расчёта:

  1. 🕘 Разбить интервал на полные дни и частичные (первый и последний день)
  2. 📊 Для полных дней использовать стандартный расчёт (например, 8 рабочих часов в день)
  3. ⏰ Для частичных дней учитывать только время в пределах рабочего графика

Пример кода для расчёта рабочих часов между двумя датами (график 9:00–18:00):

Функция РабочиеЧасы(ДатаНачала, ДатаОкончания)

// Начало и конец рабочего дня

НачалоДня = Время(9, 0, 0);

КонецДня = Время(18, 0, 0);

// Корректируем границы интервала

Если Время(ДатаНачала) < НачалоДня Тогда

ДатаНачала = Дата(ДатаНачала) + НачалоДня;

КонецЕсли;

Если Время(ДатаОкончания) > КонецДня Тогда

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

КонецЕсли;

// Рассчитываем полные дни

ПолныхДней = Цел((ДатаОкончания - ДатаНачала) / 86400) - 1;

Если ПолныхДней < 0 Тогда ПолныхДней = 0; КонецЕсли;

// Рассчитываем частичные дни

ПервыйДень = Минута(КонецДня - Время(ДатаНачала)) / 60;

ПоследнийДень = Минута(Время(ДатаОкончания) - НачалоДня) / 60;

Возврат ПолныхДней * 8 + ПервыйДень + ПоследнийДень;

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

Где это применимо:

  • 🔹 SLA-контроль: расчёт времени реакции на заявки только в рабочие часы
  • 🔹 Логистика: планирование доставки с учётом графика работы складов
  • 🔹 Зарплата: расчёт сверхурочных часов

💡

При расчёте рабочего времени всегда учитывайте временную зону сервера 1С и локальное время пользователя. Разница может приводить к ошибкам в расчётах!

6. Ошибки и ловушки при работе с датами в 1С

Даже опытные разработчики иногда сталкиваются с неожиданными проблемами при вычислении разности дат. Вот наиболее распространённые ошибки и как их избежать:

Ошибка Причина Решение
Неверное округление дней Функция РазностьДат() округляет результат до целого Используйте прямое вычитание дат для точности
Игнорирование временной зоны Сервер и клиент могут находиться в разных зонах Приведите даты к UTC или используйте ТекущаяДатаСеанса()
Праздники не учитываются Стандартные функции не знают о нерабочих днях Интегрируйте производственный календарь
Переполнение даты Дата выходит за пределы допустимого диапазона (01.01.0001–31.12.9999) Проверяйте границы с помощью Дата(1,1,1) и Дата(9999,12,31)

Дополнительные рекомендации:

  • 🔹 Тестируйте граничные случаи: разницу в 0 дней, переход через месяц/год, зимнее/летнее время
  • 🔹 Используйте отладочную печать: выводите промежуточные значения дат с помощью Сообщить()
  • 🔹 Документируйте логику: особенно если расчёты зависят от бизнес-правил (например, "пятница — короткий день")

⚠️ Внимание: В 1С:Предприятие 8.3.20+ появились новые функции для работы с временными зонами (ЧасовойПояс(), СмещениеВременнойЗоны()). Если вы работаете с распределёнными базами или облачными сервисами, изучите их возможности.

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

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

Используйте функцию РазностьДат() с единицей "Год" или вычисляйте разницу в днях и делите на 365. Однако учтите, что этот метод неточен из-за високосных лет. Для точного расчёта лучше использовать конструкцию:

Годы = ГОД(Дата2) - ГОД(Дата1) -

?(ДЕНЬГОДА(Дата2) < ДЕНЬГОДА(Дата1), 1, 0);

Почему РазностьДат() возвращает неверное значение для временных меток?

Функция РазностьДат() при вычитании дат с временем округляет результат до целых дней. Например, разница между '20260101 23:59:59' и '20260102 00:00:01' будет 1 день, хотя фактически прошла 1 секунда. Для точных расчётов используйте прямое вычитание (Дата2 - Дата1).

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

Разделите разницу в днях на 7 и возьмите целую часть:

ПолныхНедель = Цел((Дата2 - Дата1) / 7);

Если нужно учитывать начало недели с понедельника, используйте НАЧАЛОНЕДЕЛИ():

Недель = РазностьДат(НАЧАЛОНЕДЕЛИ(Дата2), НАЧАЛОНЕДЕЛИ(Дата1), "НЕДЕЛЯ");
Можно ли в 1С посчитать разницу между датами в кварталах?

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

Кварталов = РазностьДат(Дата2, Дата1, "МЕСЯЦ") / 3;

Для точного результата лучше использовать КВАРТАЛ(Дата):

Кварталов = (ГОД(Дата2) - ГОД(Дата1)) * 4 + (КВАРТАЛ(Дата2) - КВАРТАЛ(Дата1));
Как учесть летнее/зимнее время при расчёте разницы?

В нет встроенной поддержки переходов на летнее/зимнее время. Если это критично (например, для логистики), рекомендуется:

  1. Хранить все даты в UTC и конвертировать в локальное время только при отображении.
  2. Использовать внешние сервисы (например, API TimeZoneDB) для точного расчёта смещений.
  3. Жёстко прописывать правила перехода для конкретного региона (например, для Москвы: +3 часа зимой, +4 летом).