Разработка и Конфигурация · 8 мин
Как вычесть две даты в 1С: все рабочие способы
Как вычесть две даты в 1С: оператор вычитания, функция РазностьДат, расчёт лет, месяцев и дней между датами, работа с датами в запросах и типовые ошибки.
Вычитание дат — одна из самых частых операций при разработке и доработке конфигураций 1С: она нужна для расчёта стажа, сроков годности, просрочки платежей, длительности отпуска и возраста контрагента. Платформа 1С:Предприятие 8 предлагает несколько способов получить разницу между датами, и у каждого есть свои ограничения.
Простейший вариант — обычный оператор «минус»: он возвращает разницу в секундах, что часто неудобно. Для получения разницы в днях, месяцах или годах используется функция встроенного языка РазностьДат(), а в запросах — конструкция РАЗНОСТЬДАТ. Ниже разобраны все способы с примерами кода и типичными ошибками.
Вычитание дат оператором «минус» и результат в секундах
Самый прямой способ — вычесть одну дату из другой обычным арифметическим оператором. В 1С дата хранится как количество секунд от начала отсчёта, поэтому результатом вычитания будет число — разница в секундах.
ДатаНачала = '20260115100000';
ДатаОкончания = '20260120123000';
РазницаВСекундах = ДатаОкончания - ДатаНачала; // число секунд
РазницаВДнях = РазницаВСекундах / 86400; // 86400 = 60*60*24
Такой способ подходит, когда нужна точная длительность с точностью до секунды: например, время выполнения операции или длительность звонка. Для календарных расчётов он неудобен — придётся вручную пересчитывать секунды в дни, учитывая, что количество дней в месяцах и годах разное.
Обратите внимание: если вычесть из меньшей даты большую, результат будет отрицательным. Перед расчётом полезно проверять порядок дат через простое сравнение Если ДатаОкончания < ДатаНачала Тогда.
Функция РазностьДат: разница в днях, месяцах и годах
Для календарных вычислений во встроенном языке 1С предназначена функция РазностьДат(). Она принимает три параметра: начальную дату, конечную дату и тип единицы измерения из перечисления ТипЕдиницыИзмеренияПериодов.
КоличествоДней = РазностьДат(ДатаНачала, ДатаОкончания,
ТипЕдиницыИзмеренияПериодов.День);
КоличествоМесяцев = РазностьДат(ДатаНачала, ДатаОкончания,
ТипЕдиницыИзмеренияПериодов.Месяц);
КоличествоЛет = РазностьДат(ДатаНачала, ДатаОкончания,
ТипЕдиницыИзмеренияПериодов.Год);
Доступны единицы: Секунда, Минута, Час, День, Месяц, Квартал, Год. Функция возвращает целое число полных единиц, укладывающихся между датами. Например, между 15 января и 14 марта разность в месяцах будет равна 1, а не 2, потому что полных двух месяцев не прошло.
Эта особенность важна при расчёте возраста или стажа: функция корректно считает полные годы, но если нужно «добавить» остаток дней, его вычисляют отдельно — от даты, полученной прибавлением полных лет к начальной дате.
ПолныхЛет = РазностьДат(ДатаРождения, ТекущаяДатаСеанса(), ТипЕдиницыИзмеренияПериодов.Год);Разница между датами в запросах 1С
В языке запросов оператор вычитания дат не поддерживается. Вместо него используется функция РАЗНОСТЬДАТ с тремя параметрами: первая дата, вторая дата и единица измерения.
ВЫБРАТЬ
Заказ.Ссылка КАК Заказ,
РАЗНОСТЬДАТ(Заказ.ДатаОтгрузки, Заказ.ДатаОплаты, ДЕНЬ) КАК ДнейПросрочки
ИЗ
Документ.ЗаказКлиента КАК Заказ
Единицы измерения в запросе задаются ключевыми словами: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, КВАРТАЛ, ГОД. Результат — целое число полных единиц, как и у функции встроенного языка.
Поле с разностью дат можно использовать в условии через вычисляемое выражение, но чаще разность считают в выборке, а фильтрацию выполняют уже по результату — например, в конструкторе СКД или при обходе результата запроса. Помните, что если одна из дат в запросе равна NULL, результат тоже будет NULL, поэтому для необязательных полей стоит применять ЕСТЬNULL.
Расчёт точного возраста и стажа: полные годы, месяцы и дни
Задача «сколько лет, месяцев и дней между датами» решается последовательным вычитанием. Сначала считаются полные годы, затем от даты, сдвинутой на эти годы, — полные месяцы, затем остаток в днях.
Функция ВозрастТекстом(ДатаРождения, НаДату)
Лет = РазностьДат(ДатаРождения, НаДату,
ТипЕдиницыИзмеренияПериодов.Год);
ПромежуточнаяДата = ДобавитьМесяц(ДатаРождения, Лет * 12);
Месяцев = РазностьДат(ПромежуточнаяДата, НаДату,
ТипЕдиницыИзмеренияПериодов.Месяц);
ПромежуточнаяДата = ДобавитьМесяц(ПромежуточнаяДата, Месяцев);
Дней = РазностьДат(ПромежуточнаяДата, НаДату,
ТипЕдиницыИзмеренияПериодов.День);
Возврат СтрШаблон("%1 г. %2 мес. %3 дн.", Лет, Месяцев, Дней);
КонецФункции
Функция ДобавитьМесяц() корректно обрабатывает переходы через границы месяцев и лет, поэтому ручные манипуляции с числами месяца не нужны. Для кадровых расчётов стажа в типовых конфигурациях есть готовые механизмы, но принцип тот же.
- 1Определите, где выполняется расчёт: в коде модуля или в запросе
- 2Выберите способ: оператор «-» для секунд, РазностьДат для календарных единиц, РАЗНОСТЬДАТ для запроса
- 3Проверьте, что конечная дата не раньше начальной, иначе результат будет отрицательным
- 4Убедитесь, что обе переменные имеют тип Дата, а не строка или NULL
- 5Проверьте результат на контрольном примере с известной разницей
Типичные ошибки при вычитании дат
Самая распространённая ошибка — ожидать от оператора «минус» количество дней. Результат в секундах затем ошибочно подставляется в условия вида «просрочка больше 30», хотя сравнивать нужно с 30 × 86400 секунд или использовать РазностьДат.
Вторая частая проблема — сравнение дат с разным составом. Если одна дата содержит время, а другая — только начало дня, разница в днях может оказаться на единицу меньше ожидаемой. Для сравнения календарных дат применяйте НачалоДня() к обоим значениям.
Третья ошибка — работа с пустыми датами. Пустая дата в 1С равна '00010101000000', и разность с ней даст огромное число. Перед расчётом проверяйте значение через ЗначениеЗаполнено().
Проверка результата и выбор подходящего способа
Проверить корректность расчёта проще всего на контрольном примере: возьмите две даты, разницу между которыми легко посчитать вручную, например 1 января и 1 февраля одного года. Разность в днях должна быть 31, в месяцах — 1.
Дополнительно полезно проверить граничные случаи: одинаковые даты (результат 0), конец и начало месяца, переход через високосный год. Если расчёт используется в отчёте, выведите рядом исходные даты — так ошибку заметит и пользователь.
Сравнение способов
Подходит для точной длительности в секундах; неудобен для календарных расчётов
Основной способ в коде: дни, месяцы, годы; возвращает только целые единицы
Единственный вариант в языке запросов; требует обработки NULL через ЕСТЬNULL
Комбинация для точного расчёта лет, месяцев и дней, например возраста или стажа
Как проверить результат
31 день, 1 месяц
30 дней или 0 месяцев — ошибка в единицах
Результат 0
Отрицательное или большое число
Расчёт пропущен проверкой ЗначениеЗаполнено
Огромное число дней или NULL в отчёте
Часто задаваемые вопросы
Как получить разницу между датами в днях в 1С?
Используйте РазностьДат(Дата1, Дата2, ТипЕдиницыИзмеренияПериодов.День). Если нужна разница с учётом времени, вычтите даты оператором «минус» и разделите результат на 86400.
Почему вычитание дат возвращает огромное число?
Оператор «минус» возвращает секунды, а не дни. Также проверьте, не пустая ли одна из дат: пустая дата равна 01.01.0001, и разница с ней исчисляется сотнями тысяч дней.
Как вычесть даты в запросе 1С?
Используйте функцию РАЗНОСТЬДАТ(Дата1, Дата2, ДЕНЬ) с единицами СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, КВАРТАЛ или ГОД. Оператор вычитания дат в запросах не работает.
Как посчитать полный возраст в годах?
Примените РазностьДат с единицей Год: функция вернёт только полные годы, поэтому день рождения, который ещё не наступил в текущем году, учтён не будет.
Что делать, если даты содержат время, а нужны только календарные дни?
Приведите обе даты к началу дня функцией НачалоДня() перед вычитанием. Тогда время не повлияет на результат, и разница в днях будет точной.
Может ли разность дат быть отрицательной?
Да, если конечная дата раньше начальной. Перед расчётом сравните даты и при необходимости поменяйте их местами или выведите предупреждение пользователю.
Что важно запомнить
В коде 1С используйте оператор «-» для секунд и РазностьДат() для дней, месяцев и лет; в запросах — РАЗНОСТЬДАТ. Всегда проверяйте порядок дат, заполненность значений и наличие времени в составе даты.