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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Часто в практике разработки на платформе 1С возникает необходимость узнать, сколько месяцев прошло между двумя произвольными датами. Если мы просто попытаемся вычесть одну дату из другой, система вернет нам разницу в секундах. Проанализируем ситуацию: прямой перевод полученных секунд в месяцы обычным делением невозможен. Причина заключается в том, что разные месяцы содержат разное количество дней (от 28 до 31), а также существуют високосные года. Разберем по шагам, как правильно решить эту задачу.

Математический расчет по границам календарных месяцев

Посмотрим на простой и эффективный подход. Главное правило, которое стоит запомнить: переводим данные в месяцы и только потом вычитаем. Математическая формула для расчета выглядит следующим образом:


Разница = Год(КонДата) * 12 - Год(НачДата) * 12 + Месяц(КонДата) - Месяц(НачДата);

Рассмотрим подробнее готовую экспортную функцию на встроенном языке 1С, которая реализует этот алгоритм и дополнительно проверяет, какая из дат больше, чтобы всегда возвращать положительный результат:


Функция РазницаДатВМесяцах(Дата1, Дата2) Экспорт
    
    ДатаНач = ?(Дата1 < Дата2, Дата1, Дата2);
    ДатаКон = ?(Дата1 < Дата2, Дата2, Дата1);
    
    Годы   = Год(ДатаКон) - Год(ДатаНач);
    Месяцы = Месяц(ДатаКон) - Месяц(ДатаНач);
    Разность = Месяцы + Годы * 12;
    
    Возврат Разность;
    
КонецФункции

Ограничения математического метода

Проанализируем возможные подводные камни предложенного решения. Приведенная выше математическая формула считает лишь пересеченные границы календарных месяцев и полностью игнорирует дни. Разберем на примере: если переменная ДатаНач равна 31 января, а ДатаКон равна 1 февраля, формула выдаст разницу ровно в 1 месяц. Фактически же прошел всего 1 день. Это критично, если вам требуется рассчитать точный стаж сотрудника или количество дней компенсации за неиспользованный отпуск.

Расчет количества полных месяцев с учетом дней

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

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

  1. Выполняем базовый расчет по формуле, описанной выше.
  2. Добавляем дополнительное сравнение дней с помощью функции День().
  3. Если значение функции День() у даты окончания меньше, чем у даты начала, то из полученного математического количества месяцев вычитается единица (так как полный месяц еще не истек).
  4. Отдельно обрабатываем ситуации с концами месяцев и високосными годами (например, при вычитании дат с 31 числа одного месяца по 30 число другого). Для этого активно используем системные функции КонецМесяца() и ДобавитьМесяц().

Использование языка запросов

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

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

РАЗНОСТЬДАТ(ДатаНачала, ДатаОкончания, МЕСЯЦ)

Однако проанализируем важный нюанс: эта встроенная функция имеет то же самое платформенное ограничение, что и математический расчет. Она возвращает разницу в календарных месяцах без учета дней (округление происходит строго по границам месяцев). Чтобы в запросе получить точное количество полных месяцев, разработчикам приходится конструировать более сложные условия, используя функции НАЧАЛОПЕРИОДА, КОНЕЦПЕРИОДА и ДОБАВИТЬКДАТЕ.

Готовые решения в типовых конфигурациях

Рассмотрим ситуацию, когда разработка или доработка ведется в рамках современных типовых решений от фирмы "1С" (например, 1С:ЗУП, 1С:Бухгалтерия или 1С:ERP). В этом случае писать собственные алгоритмы и изобретать сложные функции для точного вычисления периодов не требуется.

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

← На главную