К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как вычислить дату в 1С: полное руководство с примерами

Как вычислить дату в 1С: функции ДобавитьМесяц, ТекущаяДатаСеанса, расчёт разности дат, работа с датами в запросах и типичные ошибки разработчика.

Работа с датами — одна из самых частых задач при разработке и доработке конфигураций 1С. Сроки оплаты, даты отгрузки, расчёт остатков отпусков, периоды отчётов — всё это требует корректных вычислений с типом «Дата». Ошибка в одном дне может привести к неверным начислениям, просроченным документам или сбоям в обменах данными.

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

Материал охватывает основные сценарии: получение текущей даты, прибавление и вычитание периодов, расчёт разности между датами, вычисления в запросах и типовые ошибки. Примеры приведены на встроенном языке 1С и применимы как к управляемым, так и к обычным формам.

Получение текущей даты: какой способ выбрать

Первый шаг большинства вычислений — получить точку отсчёта. В 1С есть несколько способов узнать текущую дату, и они не взаимозаменяемы.

Функция ТекущаяДатаСеанса() возвращает дату и время компьютера, на котором выполняется код, с учётом часового пояса сеанса. Именно её рекомендуется использовать в серверном коде и бизнес-логике: она даёт согласованное значение для всех пользователей независимо от настроек их рабочих станций.

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

Если нужна только дата без времени, обрежьте время функцией НачалоДня():

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

ДатаБезВремени = НачалоДня(ТекущаяДата);

Прибавление и вычитание дней, часов и секунд

В 1С дата хранится с точностью до секунды, и арифметика дат работает именно в секундах. Чтобы прибавить сутки, добавьте 86400 секунд (60 × 60 × 24). Аналогично час — 3600 секунд, неделя — 604800 секунд.

Завтра = ТекущаяДатаСеанса() + 86400;

НеделюНазад = ТекущаяДатаСеанса() - 7 * 86400;

ЧерезДваЧаса = ТекущаяДатаСеанса() + 2 * 3600;

Для читаемости кода часто заводят переменную СекундВДне = 86400 или используют конструкцию 60*60*24. Это снижает риск опечатки в длинном числе.

Важное ограничение: складывать две даты между собой нельзя — платформа выдаст ошибку. Разрешены только операции «дата плюс число» и «дата минус дата» (результат — число секунд).

Добавление месяцев и лет: функция ДобавитьМесяц

Месяцы имеют разную длину, поэтому прибавлять их через секунды нельзя. Для этого существует функция ДобавитьМесяц(Дата, КоличествоМесяцев). Чтобы прибавить год — передайте 12 месяцев, квартал — 3.

ЧерезМесяц = ДобавитьМесяц(ТекущаяДатаСеанса(), 1);

ЧерезГод = ДобавитьМесяц(ТекущаяДатаСеанса(), 12);

МесяцНазад = ДобавитьМесяц(ТекущаяДатаСеанса(), -1);

Ключевая особенность: если исходный день не существует в целевом месяце, результатом будет последний день этого месяца. Например, ДобавитьМесяц('20260131', 1) вернёт 29 февраля (в високосном году), а не 2–3 марта. При расчёте сроков оплаты «через месяц от конца месяца» это может изменить логику договора — проверяйте требования предметной области.

Вычисление разности между двумя датами

Вычитание дат возвращает разность в секундах. Чтобы получить количество дней, разделите результат на 86400. Для целого числа дней используйте функцию Цел() или округление в зависимости от бизнес-правила.

РазностьСекунд = ДатаОкончания - ДатаНачала;

КоличествоДней = Цел(РазностьСекунд / 86400);

Обратите внимание: если даты содержат время, простое деление может дать «на день меньше», чем ожидает пользователь. Например, разница между 10 марта 09:00 и 12 марта 18:00 — это 2,6 суток, и Цел() даст 2, хотя календарно затронуто 3 дня. Если считаете календарные дни, сначала приведите обе даты к началу дня.

Для расчёта возраста или стажа в полных годах простое деление на 365 непригодно из-за високосных лет. Надёжный подход — сравнить день и месяц рождения с текущими и скорректировать результат.

Как посчитать полные дни между датами
  1. 1
    Приведите обе даты к началу суток: НачалоДня(Дата1) и НачалоДня(Дата2)
  2. 2
    Вычтите меньшую дату из большей — получите секунды
  3. 3
    Разделите результат на 86400
  4. 4
    Проверьте на контрольном примере: разность между 1 и 2 марта должна быть 1
  5. 5
    Если нужны рабочие дни — используйте данные производственного календаря, а не простую арифметику

Определение начала и конца периода

Для отборов в запросах, формирования отчётов и проверок попадания даты в период платформа предоставляет семейство функций границ периодов:

  • НачалоДня(Дата), КонецДня(Дата) — границы суток;
  • НачалоНедели(Дата), КонецНедели(Дата) — неделя начинается с понедельника;
  • НачалоМесяца(Дата), КонецМесяца(Дата);
  • НачалоКвартала(Дата), КонецКвартала(Дата);
  • НачалоГода(Дата), КонецГода(Дата);
  • НачалоЧаса(Дата), КонецЧаса(Дата), НачалоМинуты(Дата), КонецМинуты(Дата).

Конец периода возвращает последнюю секунду: например, КонецДня('20260315') даст 15.03.2026 23:59:59. Это удобно для условий «меньше или равно», но будьте внимательны при сравнении с датами, где время обрезано до дня — документ с 23:59:59 формально не равен дате 15.03.2026 00:00:00.

Типичный приём для отбора за день:

НачалоПериода = НачалоДня(ОтчетнаяДата);

КонецПериода = КонецДня(ОтчетнаяДата);

Вычисление дат в запросах

В языке запросов 1С арифметика секунд недоступна — вместо неё используются специальные функции. Основные из них:

  • ДОБАВИТЬКДАТЕ(Дата, ТИП, Количество) — прибавляет период, где ТИП принимает значения СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД;
  • РАЗНОСТЬДАТ(Дата1, Дата2, ТИП) — возвращает разность в указанных единицах;
  • НАЧАЛОПЕРИОДА(Дата, ТИП) и КОНЕЦПЕРИОДА(Дата, ТИП) — границы периода;
  • ДАТАВРЕМЯ(2026, 3, 15) — литерал даты, при необходимости с часами, минутами и секундами.
ВЫБРАТЬ

Заказы.Ссылка КАК Заказ,

ДОБАВИТЬКДАТЕ(Заказы.ДатаОтгрузки, ДЕНЬ, 14) КАК СрокОплаты,

РАЗНОСТЬДАТ(Заказы.Дата, Заказы.ДатаОтгрузки, ДЕНЬ) КАК ДнейНаСборку

ИЗ

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

РАЗНОСТЬДАТ считает целые единицы: разность между 10:00 и 18:00 одного дня в типе ДЕНЬ даст 0, а в типе ЧАС — 8. Выбирайте единицу измерения, соответствующую бизнес-правилу, и помните, что дробная часть отбрасывается.

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

Встроенный язык (модуль)

Подходит для сложной логики, циклов, работы с производственным календарём. Полный набор функций, но требует выборки данных в контекст.

Язык запросов

Оптимален для вычислений над большими выборками — расчёт выполняется на уровне СУБД без перебора строк. Ограничен набором функций ДОБАВИТЬКДАТЕ и РАЗНОСТЬДАТ.

СКД (выражения)

Удобен для отчётов: вычисляемые поля с функциями дат прямо в схеме компоновки, без изменения запроса.

Проверка и сравнение дат

Даты сравниваются обычными операторами <, >, =. Однако есть два подводных камня. Первый — пустая дата: значение '00010101' (1 января года 1) меньше любой реальной даты, и условие «дата заполнена» проверяют через ЗначениеЗаполнено(Дата) или сравнение с пустой датой.

Второй — время в составе даты. Две даты одного календарного дня с разным временем не равны. Перед сравнением «тот ли это день» приводите обе к началу дня:

Если НачалоДня(Дата1) = НачалоДня(Дата2) Тогда

// один и тот же календарный день

КонецЕсли;

Для проверки попадания в интервал используйте двойное условие, включая границы осознанно — от этого зависит, попадёт ли документ ровно на границе периода в выборку.

Типичные ошибки
01
Прибавление месяца через 30*86400 — при длине месяца 31 или 28 дней результат смещается на несколько суток
02
Сравнение дат без обрезки времени — документы одного дня признаются разными датами
03
Использование ТекущаяДата() на клиенте в учётных расчётах — сбитые часы пользователя искажают данные
04
Деление разности дат на 86400 без Цел() — дробный результат попадает в условия и итоги
05
Игнорирование пустой даты '00010101' — она проходит проверку «меньше срока» и ломает отборы
Контрольные точки

Как проверить результат

Прибавление суток
Норма

Дата сдвинулась ровно на один календарный день, время сохранилось

Тревожный признак

Смещение на 2 дня или потеря времени

ДобавитьМесяц от 31 числа
Норма

Результат — последний день следующего месяца

Тревожный признак

Ожидалось 1-е число через месяц, логика сроков нарушена

Разность дат в днях
Норма

Целое число, совпадает с подсчётом по календарю

Тревожный признак

Дробное значение или расхождение на день из-за времени

Границы периода в запросе
Норма

Документы последнего дня периода попали в выборку

Тревожный признак

Документы за последний день теряются — конец периода задан как начало дня

Часто задаваемые вопросы

Как прибавить к дате только рабочие дни?

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

Как узнать день недели для даты?

Функция ДеньНедели(Дата) возвращает число от 1 (понедельник) до 7 (воскресенье). Для названия дня используйте Формат(Дата, "ДФ=dddd").

Чем отличается пустая дата от незаполненной?

Пустая дата — это значение '00010101' (1 января года 1, 00:00:00). Для реквизитов составного типа значение может быть Неопределено. Проверка ЗначениеЗаполнено() корректно отрабатывает оба случая, поэтому предпочтительнее прямого сравнения с '00010101'.

Как вычислить возраст в полных годах?

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

Почему ДОБАВИТЬКДАТЕ в запросе выдаёт ошибку?

Чаще всего неверно указан второй параметр — тип периода пишется без кавычек и только из фиксированного списка: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД. Также проверьте, что первый параметр действительно имеет тип Дата, а не строка или число.

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

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

Итог

Что важно запомнить

Арифметика дат в коде 1С работает в секундах: сутки — 86400. Месяцы и годы прибавляйте только через ДобавитьМесяц, в запросах — через ДОБАВИТЬКДАТЕ и РАЗНОСТЬДАТ. Перед сравнением дат обрезайте время через НачалоДня, а текущую дату в учётной логике берите из ТекущаяДатаСеанса.