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

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

1. Встроенная функция РазностьДат() — простой способ для большинства задач

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

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

Где ЕдиницаИзмерения может принимать значения:

  • 📅 "Д" — дни (значение по умолчанию)
  • "Ч" — часы
  • ⏱️ "М" — минуты
  • "С" — секунды

Пример использования:

ДатаНачала = '2026-01-15';

ДатаОкончания = '2026-02-20';

РазницаВДнях = РазностьДат(ДатаОкончания, ДатаНачала); // Вернет 36

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

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

  • 🔹 Простота и читаемость кода
  • 🔹 Быстрое выполнение (встроенная функция платформы)
  • 🔹 Поддержка всех основных единиц времени

Однако у этого способа есть ограничения:

  • 🚫 Нельзя получить разницу в месяцах или годах напрямую
  • 🚫 Не учитываются временные зоны (если даты в разных часовых поясах)
  • 🚫 Для сложных календарных расчетов (например, "2 месяца и 5 дней") потребуется комбинировать с другими функциями
📊 Какой метод расчета дат вы используете чаще всего?
Встроенные функции 1С
Запросы
Программный код
Стандартные процедуры из библиотек

2. Использование запросов — когда данные хранятся в базе

Если даты хранятся в базе данных (например, в регистрах сведений или документах), удобнее рассчитывать разницу прямо в запросе 1С. Это позволит избежать лишних обращений к базе и ускорить выполнение кода. В языке запросов для этого есть функция РАЗНОСТЬДАТ().

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

ВЫБРАТЬ

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

РАЗНОСТЬДАТ(ТЕКУЩАЯДАТА(), Документ.Дата, ДЕНЬ) КАК ДнейПрошло

ИЗ

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

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

  • 📊 Можно сразу отфильтровать результаты (например, выбрать документы, где разница больше 30 дней)
  • 🔄 Поддерживаются все те же единицы измерения, что и в РазностьДат()
  • 📈 Результаты можно группировать и агрегировать (например, посчитать среднюю просрочку по контрагентам)
Единица измерения в запросе Синтаксис Пример результата
Дни ДЕНЬ 36
Часы ЧАС 864
Минуты МИНУТА 51840
Секунды СЕКУНДА 3110400
⚠️ Внимание: В некоторых конфигурациях (особенно старых версиях) функция РАЗНОСТЬДАТ() может работать медленнее, чем вычисления в программном коде. Если запрос выполняется долго, попробуйте перенести логику расчета в модуль объекта.

Когда стоит использовать запросы:

  • 🗃️ Нужно получить разницу дат для большого количества записей (тысячи строк)
  • 🔍 Требуется отфильтровать или сгруппировать данные по временным интервалам
  • 📊 Нужно интегрировать расчеты с другими полями из базы (например, сумма документа + количество дней просрочки)

Проверьте формат хранения дат в базе (Дата или ДатаВремя)

Убедитесь, что временная зона одинакова для всех сравниваемых дат

Определите единицу измерения заранее (дни, часы и т.д.)

Тестируйте запрос на небольшом наборе данных перед выполнением на всей базе-->

3. Программный расчет с учетом календарных периодов

Если вам нужно получить разницу в месяцах или годах, а также учитывать неполные периоды (например, "2 месяца и 15 дней"), стандартные функции не подойдут. В этом случае придется писать собственный код. Вот универсальная функция для расчета разницы в месяцах:

Функция РазницаВМесяцах(ДатаНачала, ДатаОкончания)

Месяцев = (Год(ДатаОкончания) - Год(ДатаНачала)) * 12 + (Месяц(ДатаОкончания) - Месяц(ДатаНачала));

Если День(ДатаОкончания) < День(ДатаНачала) Тогда

Месяцев = Месяцев - 1;

КонецЕсли;

Возврат Месяцев;

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

Пример использования:

ДатаТрудоустройства = '2020-05-15';

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

Сообщить("Стаж: " + РазницаВМесяцах(ДатаТрудоустройства, ТекущаяДата) + " месяцев");

Для более точного расчета с учетом дней можно модифицировать функцию:

Процедура РазницаПериодов(Дата1, Дата2, Перем Месяцы, Перем Дни)

Месяцы = РазницаВМесяцах(Дата1, Дата2);

Дни = День(Дата2) - День(Дата1);

Если Дни < 0 Тогда

Дни = Дни + ДнейВМесяце(Год(Дата2), Месяц(Дата2) - 1);

КонецЕсли;

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

Где ДнейВМесяце() — стандартная функция , возвращающая количество дней в указанном месяце.

Как учитывать високосные годы в расчетах

При расчете разницы в годах или месяцах високосные годы учитываются автоматически в стандартных функциях 1С (например, ДнейВМесяце() вернет 29 для февраля 2026 года). Однако если вы пишете собственную логику для работы с датами, не забывайте проверять год на високосность с помощью функции ГодВисокосный().

Когда нужен программный расчет:

  • 📅 Требуется разница в месяцах/годах с учетом неполных периодов
  • 🔄 Нужно учитывать специфические бизнес-правила (например, "квартал считается полным, если прошло хотя бы 45 дней")
  • 📊 Необходимо интегрировать расчеты с другими алгоритмами (например, начисление премий по стажу)

4. Работа с интервалами времени (Тип "Интервал")

В 1С:Предприятие 8.3 есть специальный тип данных Интервал, который предназначен для хранения временных промежутков. Его удобно использовать, когда нужно не просто получить разницу в днях, а сохранить ее для дальнейших операций (например, сложение интервалов).

Пример создания интервала:

Дата1 = '2026-01-01 10:00:00';

Дата2 = '2026-01-03 15:30:00';

Интервал = Дата2 - Дата1; // Автоматически создаст объект типа "Интервал"

С интервалами можно выполнять следующие операции:

  • 🔢 Получать отдельные компоненты (дни, часы, минуты) через свойства Дни, Часы, Минуты, Секунды
  • ➕ Складывать и вычитать интервалы
  • ⏱️ Преобразовывать в секунды для точных расчетов

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

Интервал = ДатаОкончания - ДатаНачала;

Дней = Интервал.Дни;

Часов = Интервал.Часы;

Сообщить(Строка(Дней) + " дней и " + Строка(Часов) + " часов");

⚠️ Внимание: При вычитании дат с типом Дата (без времени) результат все равно будет иметь тип Интервал, но свойства Часы, Минуты и Секунды будут равны нулю. Если вам нужны только дни, используйте РазностьДат() — это эффективнее.

Преимущества работы с интервалами:

  • 🔹 Точность до секунды
  • 🔹 Удобство для сложных временных расчетов (например, суммирование времени выполнения задач)
  • 🔹 Возможность конвертации в разные единицы измерения
Дни = Окр(Интервал.ВСекундах() / 86400, 0, 1)

где 1 в конце означает округление вверх.-->

5. Стандартные процедуры из библиотек 1С

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

  • 📅 РабочиеДниМеждуДатами() — возвращает количество рабочих дней между двумя датами (учитывает выходные и праздники)
  • 📊 ДобавитьМесяц() / ДобавитьГод() — удобно для расчета дат с учетом календарных периодов
  • НайтиДатуПоДнюНедели() — помогает найти ближайший понедельник/пятницу и т.д.

Пример использования РабочиеДниМеждуДатами():

КоличествоРабочихДней = РабочиеДниМеждуДатами('2026-01-01', '2026-01-31');

Сообщить("Рабочих дней в январе: " + КоличествоРабочихДней);

Где искать эти функции:

  • 📂 В стандартных модулях конфигурации (например, ОбщийМодуль.РаботаСДатами)
  • 📦 В типовой конфигурации "Зарплата и управление персоналом" (модуль Календарь)
  • 🔧 В библиотеке стандартных подсистем (БСП) для 1С:Предприятие 8.3
⚠️ Внимание: Состав стандартных библиотек может отличаться в зависимости от версии платформы и конфигурации. Если функции нет в вашей базе, проверьте наличие обновлений или реализуйте аналогичную логику самостоятельно.

Когда стоит использовать стандартные процедуры:

  • 🏢 Работаете с типовой конфигурацией (УТ, ERP, ЗУП и т.д.)
  • 📅 Нужно учитывать производственный календарь (праздники, переносы выходных)
  • 🔄 Требуется сложная логика работы с датами (например, "найти последний рабочий день месяца")
💡

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

Типичные ошибки и как их избежать

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

  1. 🚫 Игнорирование временной зоны: Если в базе хранятся даты с временем (тип ДатаВремя), но без указания временной зоны, расчеты могут быть неточными при работе с распределенными системами.
  2. 🚫 Путаница с форматами дат: Функция РазностьДат() ожидает параметры типа Дата, а не строку. Если передать строку (например, '2026.01.15'), получите ошибку.
  3. 🚫 Неучет граничных условий: При расчете разницы в месяцах легко забыть про случаи, когда день окончания меньше дня начала (например, с 31 января по 28 февраля).
  4. 🚫 Избыточные вычисления: Расчет разницы в секундах для тысяч записей может замедлить работу системы. В таких случаях лучше использовать запросы.

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

  • 🔍 Всегда проверяйте типы передаваемых данных (используйте ТипЗнч())
  • 📅 Тестируйте код на граничных датах (конец месяца, високосные годы)
  • ⏱️ Для критичных расчетов добавьте отладочный вывод (например, Сообщить(ТипЗнч(ДатаНачала)))

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

Как рассчитать разницу между датами с учетом только рабочих дней?

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

Функция РабочиеДни(Дата1, Дата2)

Дней = РазностьДат(Дата2, Дата1, "Д");

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

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

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

Если НЕ ТекущаяДата.ДеньНедели() = 6 И НЕ ТекущаяДата.ДеньНедели() = 7 Тогда

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

КонецЕсли;

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

КонецЦикла;

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

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

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

Наиболее вероятные причины:

  1. Вы передаете даты в неправильном порядке (должно быть РазностьДат(БольшаяДата, МеньшаяДата)).
  2. Одна из дат имеет тип ДатаВремя, а время влияет на результат (используйте НачалоДня() для обнуления времени).
  3. В вашей конфигурации переопределена стандартная функция (проверьте глобальные модули).

Чтобы диагностировать проблему, выведите типы и значения дат перед расчетом:

Сообщить(ТипЗнч(Дата1) + " | " + Дата1);

Сообщить(ТипЗнч(Дата2) + " | " + Дата2);

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

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

Процедура РазницаВГодахМесяцахДнях(Дата1, Дата2, Перем Годы, Перем Месяцы, Перем Дни)

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

Если Месяц(Дата2) < Месяц(Дата1) Или (Месяц(Дата2) = Месяц(Дата1) И День(Дата2) < День(Дата1)) Тогда

Годы = Годы - 1;

КонецЕсли;

Месяцы = Месяц(Дата2) - Месяц(Дата1);

Если День(Дата2) < День(Дата1) Тогда

Месяцы = Месяцы - 1;

КонецЕсли;

Если Месяцы < 0 Тогда

Месяцы = Месяцы + 12;

КонецЕсли;

Дни = День(Дата2) - День(Дата1);

Если Дни < 0 Тогда

Дни = Дни + ДнейВМесяце(Год(Дата2), Месяц(Дата2) - 1);

КонецЕсли;

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

Пример использования:

ДатаРождения = '1990-05-15';

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

РазницаВГодахМесяцахДнях(ДатаРождения, ТекущаяДата, Годы, Месяцы, Дни);

Сообщить(Строка(Годы) + " лет, " + Строка(Месяцы) + " месяцев, " + Строка(Дни) + " дней");

Можно ли в 1С рассчитать разницу между датами с точностью до миллисекунд?

Нет, платформа 1С:Предприятие 8.3 не поддерживает миллисекунды. Максимальная точность — до секунд (тип ДатаВремя). Если вам нужна более высокая точность, придется хранить время отдельно (например, в числовом поле) и обрабатывать его вручную.

Альтернативный вариант — использовать внешние системы (например, базы данных с поддержкой миллисекунд) и интегрировать их с через HTTP-Сервисы или COM-соединение.

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

Для этого можно использовать следующую функцию:

Функция ПолныхМесяцевМеждуДатами(Дата1, Дата2)

Возврат (Год(Дата2) - Год(Дата1)) * 12 + (Месяц(Дата2) - Месяц(Дата1)) -

Если День(Дата2) < День(Дата1) Тогда 1 Иначе 0 КонецЕсли;

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

Пример:

ДатаНачала = '2026-01-15';

ДатаОкончания = '2026-03-10';

Сообщить("Полных месяцев: " + ПолныхМесяцевМеждуДатами(ДатаНачала, ДатаОкончания)); // Вернет 1