Вычисление разницы между датами — одна из самых распространённых задач в 1С:Предприятие, которая возникает при работе с отчётами, расчётами зарплаты, сроками выполнения задач или анализом временных интервалов. Казалось бы, что может быть проще: взять две даты и вычесть одну из другой. Но в 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') учитывает часы, минуты и секунды - 🔹 Возвращает целое число (округляет дробные значения)
2. Альтернативный подход: арифметические операции с датами
В 1С даты можно вычитать напрямую, как числа. Результат будет представлен в днях с дробной частью (где дробь — это время). Этот метод удобен, когда нужно получить точную разницу с учётом часов и минут.
Пример:
ДатаНачала = '20260101080000'; // 1 января 2026, 8:00
ДатаОкончания = '20260102103000'; // 2 января 2026, 10:30
РазницаВДнях = ДатаОкончания - ДатаНачала;
// Результат: 1.10416666666667 (1 день и ~2.5 часа)
Чтобы преобразовать результат в часы или минуты, умножьте на соответствующий коэффициент:
- 🕒 Часы:
РазницаВДнях * 24→26.5часов - ⏱️ Минуты:
РазницаВДнях 24 60→1590минут
⚠️ Внимание: При прямом вычитании дат не учитываются временные зоны. Если в вашей базе данные хранятся в UTC, а отображаются в локальном времени, результат может быть искажён на ± несколько часов.
Преимущества метода:
- 🔹 Точность: сохраняет дробную часть (время)
- 🔹 Производительность: работает быстрее, чем
РазностьДат(), в циклах - 🔹 Гибкость: легко конвертировать в любые единицы
Если вам нужна разница в полных днях без учёта времени, используйте функцию Цел(Дата2 - Дата1). Это округлит результат до ближайшего целого числа вниз.
3. Работа с датами в запросах 1С
В Запросах 1С для вычисления разности дат используются функции ДОБАВИТЬКДАТЕ() и арифметические операции. Однако синтаксис здесь отличается от встроенного языка.
Пример запроса, который возвращает разницу в днях между датой документа и текущей датой:
ВЫБРАТЬ
ДокументСклад.Дата КАК ДатаДокумента,
ТЕКУЩАЯДАТА() КАК ТекущаяДата,
ДЕНЬ(ТЕКУЩАЯДАТА() - ДокументСклад.Дата) КАК РазницаВДнях
ИЗ
Документ.ПоступлениеТоваров КАК ДокументСклад
ГДЕ
ДокументСклад.Дата > ДОБАВИТЬКДАТЕ(ТЕКУЩАЯДАТА(), МЕСЯЦ, -1)
Ключевые функции для работы с датами в запросах:
- 📆
ТЕКУЩАЯДАТА()— возвращает текущую дату сервера - 🔢
ДЕНЬ(Выражение)— извлекает количество дней из разницы - ⏳
ДОБАВИТЬКДАТЕ(Дата, Интервал, Количество)— сдвигает дату на заданный период
| Функция | Пример | Результат |
|---|---|---|
ГОД(Дата) |
ГОД('20260115') |
2026 |
МЕСЯЦ(Дата) |
МЕСЯЦ('20260115') |
1 |
ДЕНЬ(Дата) |
ДЕНЬ('20260115') |
15 |
НАЧАЛОПЕРИОДА(Дата, Интервал) |
НАЧАЛОПЕРИОДА('20260115', "МЕСЯЦ") |
'20260101' |
Особенности работы с датами в запросах:
- 🔹 Формат даты: в запросах даты указываются в кавычках:
'20260115' - 🔹 Временная зона: все даты приводятся к серверному времени
- 🔹 Производительность: вычисления в запросе оптимизированы для больших выборок
☑️ Подготовка запроса с датами
4. Расчёт разницы в рабочих днях (с учётом праздников)
Если вам нужно посчитать только рабочие дни, исключая выходные и праздники, стандартные функции 1С не подойдут. Здесь требуется кастомный алгоритм или использование внешних календарей.
Пример функции для расчёта рабочих дней (без учёта праздников):
Функция РабочиеДни(ДатаНачала, ДатаОкончания)
Дни = ДатаОкончания - ДатаНачала;
Выходные = Цел(Дни / 7) * 2; // 2 выходных в неделю
Если ДеньНедели(ДатаОкончания) = 6 Тогда // Суббота
Выходные = Выходные + 1;
ИначеЕсли ДеньНедели(ДатаОкончания) = 7 Тогда // Воскресенье
Выходные = Выходные + 1;
КонецЕсли;
Если ДеньНедели(ДатаНачала) = 7 Тогда // Начало в воскресенье
Выходные = Выходные - 1;
КонецЕсли;
Возврат Дни - Выходные;
КонецФункции
Для учёта праздников необходимо:
- 📅 Создать справочник праздничных дат (например,
Справочник.Праздники) - 🔄 Добавить в функцию проверку на попадание даты в этот справочник
- 📊 Использовать
Запросдля выборки праздников в заданном интервале
⚠️ Внимание: Алгоритмы учёта рабочих дней зависят от региональных особенностей. Например, в некоторых странах выходной не суббота/воскресенье, а пятница/суббота. Всегда уточняйте правила у заказчика!
Готовые решения:
- 🔧 Библиотека стандартных подсистем (БСП): содержит функции для работы с производственными календарями
- 📦 Внешние обработки: на Инфостарте или 1С-Галлерее есть готовые календари с праздниками до 2030 года
- 🛠️ Самостоятельная доработка: если праздников мало, их можно жёстко прописать в коде
Пример учёта праздников в коде
Для проверки даты на праздничность можно использовать такой запрос:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
КалендарьПраздников.Дата КАК Дата
ИЗ
Справочник.Праздники КАК КалендарьПраздников
ГДЕ
КалендарьПраздников.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
Затем из общей разницы дней вычитаем количество найденных праздников.
5. Сложные сценарии: разность дат с учётом времени суток
Иногда требуется посчитать разницу между датами только в рамках рабочего времени. Например, если офис работает с 9:00 до 18:00, а задача была создана в 17:50, то следующие 10 минут не должны учитываться как "рабочее время".
Алгоритм расчёта:
- 🕘 Разбить интервал на полные дни и частичные (первый и последний день)
- 📊 Для полных дней использовать стандартный расчёт (например, 8 рабочих часов в день)
- ⏰ Для частичных дней учитывать только время в пределах рабочего графика
Пример кода для расчёта рабочих часов между двумя датами (график 9:00–18:00):
Функция РабочиеЧасы(ДатаНачала, ДатаОкончания)
// Начало и конец рабочего дня
НачалоДня = Время(9, 0, 0);
КонецДня = Время(18, 0, 0);
// Корректируем границы интервала
Если Время(ДатаНачала) < НачалоДня Тогда
ДатаНачала = Дата(ДатаНачала) + НачалоДня;
КонецЕсли;
Если Время(ДатаОкончания) > КонецДня Тогда
ДатаОкончания = Дата(ДатаОкончания) + КонецДня;
КонецЕсли;
// Рассчитываем полные дни
ПолныхДней = Цел((ДатаОкончания - ДатаНачала) / 86400) - 1;
Если ПолныхДней < 0 Тогда ПолныхДней = 0; КонецЕсли;
// Рассчитываем частичные дни
ПервыйДень = Минута(КонецДня - Время(ДатаНачала)) / 60;
ПоследнийДень = Минута(Время(ДатаОкончания) - НачалоДня) / 60;
Возврат ПолныхДней * 8 + ПервыйДень + ПоследнийДень;
КонецФункции
Где это применимо:
- 🔹 SLA-контроль: расчёт времени реакции на заявки только в рабочие часы
- 🔹 Логистика: планирование доставки с учётом графика работы складов
- 🔹 Зарплата: расчёт сверхурочных часов
При расчёте рабочего времени всегда учитывайте временную зону сервера 1С и локальное время пользователя. Разница может приводить к ошибкам в расчётах!
6. Ошибки и ловушки при работе с датами в 1С
Даже опытные разработчики 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 и конвертировать в локальное время только при отображении.
- Использовать внешние сервисы (например, API TimeZoneDB) для точного расчёта смещений.
- Жёстко прописывать правила перехода для конкретного региона (например, для Москвы: +3 часа зимой, +4 летом).