Разработка и Конфигурация · 10 мин
Как рассчитать разницу дат в 1С
Как рассчитать разницу дат в 1С: оператор вычитания, функции РазностьДат и ДобавитьКЧислу, расчёт в запросах, в днях, месяцах и годах с примерами кода.
Разница между датами — одна из самых частых задач при разработке и доработке конфигураций 1С: расчёт стажа сотрудника, срока хранения документа, количества дней просрочки по договору или возраста товара на складе. Встроенный язык 1С предлагает несколько способов решить эту задачу, и у каждого есть свои ограничения, о которых важно знать заранее.
Главная особенность платформы: простое вычитание дат оператором «минус» возвращает разницу в секундах, а не в днях. Из-за этого начинающие разработчики часто получают неожиданные результаты — например, число 86400 вместо одного дня. Правильный инструмент зависит от того, где выполняется расчёт: в коде на встроенном языке, в запросе или в СКД.
Ниже разобраны все рабочие способы: вычитание дат с переводом секунд в дни, функция РазностьДат в запросах, вычисление полных лет и месяцев для стажа и возраста, а также типичные ошибки, которые приводят к неверным результатам в отчётах и кадровых документах.
Как устроен тип «Дата» в 1С и почему минус даёт секунды
Тип «Дата» в платформе 1С хранит момент времени с точностью до секунды. Когда вы пишете выражение ДатаОкончания - ДатаНачала, платформа возвращает число — количество секунд между двумя моментами. Это поведение зафиксировано в синтакс-помощнике и не зависит от версии платформы.
Чтобы получить разницу в днях, результат делят на количество секунд в сутках — 86400. Если нужны часы, делят на 3600, минуты — на 60. Важно помнить: деление даёт дробное число, если даты содержат время, отличное от полуночи.
Для отсечения дробной части применяют функцию Цел(), а для округления по правилам математики — Окр(). Выбор зависит от бизнес-логики: при расчёте просрочки обычно берут целую часть, при расчёте длительности смены — округление.
ДатаНачала = '20260115';
ДатаОкончания = '20260220';
РазницаВСекундах = ДатаОкончания - ДатаНачала;
РазницаВДнях = Цел(РазницаВСекундах / 86400);
Сообщить("Прошло дней: " + РазницаВДнях);Расчёт разницы в днях, часах и минутах на встроенном языке
Базовый приём — вычитание с последующим делением. Для удобства повторного использования расчёт оформляют функцией в общем модуле, чтобы не дублировать магические числа 86400 и 3600 по всему коду конфигурации.
Если даты содержат время и нужна разница только в календарных днях без учёта часов, сначала применяют функцию НачалоДня() к обеим датам. Это устраняет ситуацию, когда между «вчера 23:00» и «сегодня 01:00» формально два часа, но разница в датах — один день.
Для проверки знака результата используйте простое сравнение: если дата окончания раньше даты начала, разница будет отрицательной. В кадровых и финансовых расчётах отрицательное значение часто означает ошибку входных данных, которую нужно обработать явно, а не передавать дальше в отчёт.
Функция РазницаВДнях(ДатаНачала, ДатаОкончания) Экспорт
Возврат Цел((НачалоДня(ДатаОкончания) - НачалоДня(ДатаНачала)) / 86400);
КонецФункции
Функция РазницаВЧасах(ДатаНачала, ДатаОкончания) Экспорт
Возврат Окр((ДатаОкончания - ДатаНачала) / 3600, 1);
КонецФункцииФункция РАЗНОСТЬДАТ в запросах 1С
В языке запросов доступна встроенная функция РАЗНОСТЬДАТ(Дата1, Дата2, Единица), которая сразу возвращает разницу в указанных единицах: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, ГОД. Это основной способ расчёта разницы дат в отчётах, потому что вычисление выполняется на уровне СУБД и не требует выборки данных в код.
Функция считает количество полных единиц между датами. Например, РАЗНОСТЬДАТ с единицей МЕСЯЦ между 31 января и 1 февраля вернёт 0, потому что полный месяц ещё не прошёл. Это поведение нужно учитывать при расчёте сроков оплаты и просрочек.
В отчётах на СКД функцию можно использовать прямо в тексте запроса набора данных или в вычисляемых полях. Результат допустимо агрегировать — например, посчитать средний срок доставки по группе заказов через СРЕДНЕЕ(РАЗНОСТЬДАТ(...)).
ВЫБРАТЬ
Заказ.Ссылка КАК Заказ,
РАЗНОСТЬДАТ(Заказ.Дата, Заказ.ДатаОтгрузки, ДЕНЬ) КАК ДнейНаОтгрузку,
РАЗНОСТЬДАТ(Заказ.ДатаОплаты, &ТекущаяДата, ДЕНЬ) КАК ДнейПросрочки
ИЗ
Документ.ЗаказПокупателя КАК Заказ
ГДЕ
РАЗНОСТЬДАТ(Заказ.ДатаОплаты, &ТекущаяДата, ДЕНЬ) > 5Как посчитать полные годы и месяцы: стаж и возраст
Расчёт возраста сотрудника или стажа работы сложнее деления на 365: из-за високосных лет год не равен фиксированному числу дней. Правильный подход — сравнить месяц и день даты рождения с текущей датой и скорректировать результат.
Алгоритм: вычислить разницу лет через Год(Дата2) - Год(Дата1), затем проверить, наступил ли в текущем году «юбилей» начальной даты. Если месяц и день текущей даты меньше месяца и дня рождения — вычесть единицу. Аналогично строится расчёт полных месяцев с поправкой на день месяца.
В типовых конфигурациях (например, в зарплатных решениях) есть готовые механизмы расчёта стажа с учётом этих правил. Если вы дорабатываете типовую конфигурацию, сначала проверьте наличие подходящих функций в общих модулях — это надёжнее, чем писать собственный расчёт.
Функция ПолныхЛет(ДатаРождения, НаДату) Экспорт
Лет = Год(НаДату) - Год(ДатаРождения);
Если Месяц(НаДату) < Месяц(ДатаРождения)
Или (Месяц(НаДату) = Месяц(ДатаРождения)
И День(НаДату) < День(ДатаРождения)) Тогда
Лет = Лет - 1;
КонецЕсли;
Возврат Лет;
КонецФункцииОбратная задача: прибавить интервал к дате
Часто вместе с разницей дат нужна обратная операция — получить дату через заданное число дней или месяцев, например рассчитать дату окончания договора. Для дней и меньших единиц достаточно прибавить секунды: Дата + 7 * 86400 добавит неделю.
Для месяцев простое сложение не подходит, потому что длина месяцев различается. Используйте функцию ДобавитьМесяц(Дата, КоличествоМесяцев) — она корректно обрабатывает переход через год и конец месяца: к 31 января прибавление одного месяца даст последний день февраля.
В запросах аналогичную роль выполняет функция ДОБАВИТЬКДАТЕ(Дата, МЕСЯЦ, 3). Она удобна для отбора документов за скользящий период — например, все заказы за последние три месяца относительно текущей даты.
Сравнение способов расчёта
Подходит для дней, часов и секунд в алгоритмах. Ограничение: результат в секундах, нужно делить и округлять вручную.
Оптимально для отчётов и отборов, считается на стороне СУБД. Ограничение: только целые единицы, нет смешанных периодов.
Для обратной задачи — сдвига даты на месяцы и годы. Не вычисляет разницу, только смещает дату.
Для стажа и возраста в типовых решениях. Ограничение: зависят от конкретной конфигурации и её версии.
Проверка результата и типичные ошибки
После внедрения расчёта проверьте его на граничных случаях: одинаковые даты, соседние даты, переход через месяц и через год, 29 февраля високосного года, даты с временем 23:59:59. Большинство дефектов в расчётах дат проявляется именно на границах периодов.
Отдельно проверьте поведение при пустой дате (01.01.0001). Если реквизит не заполнен, разница дат даст огромное число, которое «испортит» итоги отчёта. Перед расчётом добавляйте проверку ЗначениеЗаполнено(Дата) или условие в запросе.
Как проверить результат
Возвращается 1 день
0 дней или 86400 без обработки
Результат 0
Отрицательное или дробное значение
31 день или 1 месяц по РАЗНОСТЬДАТ
Отрицательное значение, сбой единиц измерения
Расчёт пропускается или выдаёт 0 по явному условию
Огромное число дней в итогах отчёта
Частые вопросы о разнице дат в 1С
Почему при вычитании дат получается большое число вместо дней?
Оператор «минус» между датами возвращает разницу в секундах. Разделите результат на 86400, чтобы получить дни, на 3600 — часы, на 60 — минуты. Для целого числа дней дополнительно примените функцию Цел().
Как в запросе посчитать разницу дат в месяцах?
Используйте РАЗНОСТЬДАТ(Дата1, Дата2, МЕСЯЦ). Учтите, что функция считает только полные месяцы: между 31 января и 28 февраля полный месяц не пройдёт, и результат будет 0.
Как правильно рассчитать возраст сотрудника?
Вычислите разницу годов, затем уменьшите её на единицу, если день рождения в текущем году ещё не наступил (сравните месяц и день). Делить дни на 365 нельзя — високосные годы дадут ошибку. В типовых кадровых конфигурациях есть готовые функции расчёта возраста и стажа.
Что делать, если одна из дат не заполнена?
Проверяйте дату функцией ЗначениеЗаполнено() перед расчётом. Пустая дата в 1С равна 01.01.0001, и разница с ней даст огромное число, которое исказит итоги отчёта. В запросе добавьте условие ГДЕ Дата <> ДАТАВРЕМЯ(1,1,1).
Можно ли учесть при расчёте только рабочие дни?
Штатных функций разницы рабочих дней во встроенном языке нет. Нужно использовать производственные календари (регистры сведений с графиками работы в типовых конфигурациях) и подсчитывать дни по календарю, а не арифметикой дат.
Как прибавить к дате несколько месяцев?
В коде — функцией ДобавитьМесяц(Дата, КоличествоМесяцев): она корректно обрабатывает конец месяца и переход через год. В запросе — ДОБАВИТЬКДАТЕ(Дата, МЕСЯЦ, N). Складывать дни вручную для месяцев не следует из-за разной длины месяцев.
Что важно запомнить
Вычитание дат в коде даёт секунды — делите на 86400 для дней. В запросах и отчётах используйте РАЗНОСТЬДАТ с нужной единицей измерения. Возраст и стаж считайте сравнением месяца и дня, а не делением на 365. Всегда проверяйте пустые даты и граничные случаи: соседние даты, конец месяца, високосный год.