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

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

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

Базовый синтаксис и арифметика дат

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

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

ДатаСегодня = ТекущаяДата();

ДатаЗавтра = ДатаСегодня + 1;

Сообщить("Сегодня: " + ДатаСегодня);

Сообщить("Завтра: " + ДатаЗавтра);

Если вам нужно работать не с текущим моментом, а с конкретной датой, заданной жестко или полученной из формы, логика остается прежней. Платформа автоматически обрабатывает переходы через конец месяца. Например, если вы прибавите 1 к дате 31 января, система корректно вернет 1 февраля, учитывая количество дней в месяце.

⚠️ Внимание: При арифметических операциях с типом Дата всегда учитывайте компонент времени. Если дата содержит время 23:59:59, то прибавление 1 дня даст 23:59:59 следующего дня, а не начало суток. Для работы с периодами это может быть критично.

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

📊 Как вы чаще всего сдвигаете даты в коде 1С?
Прямое сложение (+1)
Функция ДобавлениеПериода
Через конструктор даты
Использую запросы

Использование функции ДобавлениеПериода

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

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

ИсходнаяДата = '20260131';

// Добавляем один день

НоваяДата = ДобавлениеПериода(ИсходнаяДата, ВидПериода.День, 1);

// Добавляем один месяц

ДатаЧерезМесяц = ДобавлениеПериода(ИсходнаяДата, ВидПериода.Месяц, 1);

Функция также корректно обрабатывает пограничные ситуации. Если вы пытаетесь прибавить месяц к дате 31 января, результат будет зависеть от количества дней в целевом месяце (в феврале это будет 28 или 29 число). При работе с днями поведение функции полностью идентично прямой арифметике, но код выглядит более формализованным.

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

💡

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

Работа с началом и концом суток

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

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

  • 🕒 НачалоДня() — устанавливает время в 00:00:00, что идеально для начала отчетного периода.
  • 🌙 КонецДня() — устанавливает время в 23:59:59, что удобно для включения всей информации за текущие сутки.
  • 📅 ТекущаяДата() — возвращает точное время, которое часто нужно округлять перед расчетами.

Рассмотрим сценарий, когда необходимо установить дату документа на завтра, но строго на начало рабочего дня. Если мы просто возьмем ТекущаяДата() + 1, то время останется тем же, что и сейчас. Если сейчас 15:30, то дата документа будет "завтра 15:30", что может быть неверно для регламентных операций.

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

Такой подход гарантирует, что независимо от времени выполнения кода, результирующая дата будет указывать на 00:00:00 следующего календарного дня. Это критически важно при формировании выборок в запросах, где условия часто задаются в виде диапазонов Между.

⚠️ Внимание: Функция КонецДня возвращает время 23:59:59. Если вы используете это значение как верхнюю границу диапазона в запросе, убедитесь, что в базе нет записей с временем большим than 23:59:59 (хотя стандартные механизмы 1С обычно этого не допускают, при импорте из внешних источников такие аномалии возможны).

Особенности работы в запросах

При написании запросов к базе данных 1С логика работы с датами имеет свои особенности. В языке запросов также поддерживается арифметика с датами, но синтаксис немного отличается от встроенного языка. Здесь важно использовать ключевое слово ДАТАВРЕМЯ или работать с полями типа ДатаВремя.

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

ВЫБРАТЬ

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

Документ.Дата

ИЗ

Документ.РеализацияТоваровУслуг КАК Документ

ГДЕ

Документ.Дата МЕЖДУ &НачалоПериода И &КонецПериода

В параметрах запроса значения границ периода формируются заранее в коде. Это позволяет гибко управлять логикой. Например, для получения всех документов за завтрашний день, параметры вычисляются так:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ ... ГДЕ Дата МЕЖДУ &Нач И &Кон";

Запрос.УстановитьПараметр("Нач", НачалоДня(ТекущаяДата() + 1));

Запрос.УстановитьПараметр("Кон", КонецДня(ТекущаяДата() + 1));

Использование параметров запроса вместо подстановки значений напрямую в текст запроса является лучшей практикой. Это защищает от SQL-инъекций (хотя в 1С это менее актуально, чем в вебе) и позволяет плану запроса кэшироваться, что ускоряет повторное выполнение.

Метод Где используется Преимущество Недостаток
Арифметика (+1) Встроенный язык Краткость записи Менее явно для чтения
ДобавлениеПериода Встроенный язык Гибкость (месяцы, годы) Длинный синтаксис
ПАРАМЕТРЫ запроса Язык запросов Безопасность и кэширование Требует подготовки кода
НачалоДня/КонецДня Оба языка Точность до суток Доп. вызов функции

☑️ Проверка корректности работы с датами

Выполнено: 0 / 4

Конвертация типов и строковые представления

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

Функция Строка позволяет получить текстовое представление даты. По умолчанию используется формат, заданный в региональных настройках пользователя, что может привести к ошибкам при обмене данными между системами с разными локалями. Для универсальности рекомендуется использовать формат ЧЧЧЧММДД.

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

СтрокаДаты = "25.10.2026";

// Преобразование строки в дату

ДатаЗначение = Дата(СтрокаДаты);

// Прибавление дня

НоваяДата = ДатаЗначение + 1;

// Обратное преобразование в строку формата YYYYMMDD

СтрокаРезультат = Формат(НоваяДата, "ЧЧЧЧММДД");

Использование функции Формат дает полный контроль над видом итоговой строки. Это особенно полезно при формировании имен файлов, где недопустимы символы разделителей даты, такие как точки или двоеточия.

Нюансы региональных настроек

Если вы работаете в международной компании, помните, что формат DD.MM.YYYY не является стандартом во всех странах. В США принято MM/DD/YYYY. Всегда используйте нейтральный формат ЧЧЧЧММДД для внутреннего обмена данными.

Типичные ошибки и отладка

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

Одна из частых проблем возникает при сравнении дат. Если вы сравниваете дату документа (которая может содержать время 14:35:10) с датой отсечки (например, начало дня), условие равенства никогда не выполнится. Необходимо либо округлять сравниваемые значения, либо использовать диапазоны.

  • Ошибка: Сравнение Если ДатаДокумента = ТекущаяДата() Тогда. Работает только в ту же секунду.
  • Решение: Сравнение Если НачалоДня(ДатаДокумента) = НачалоДня(ТекущаяДата()) Тогда.
  • ⚠️ Риск: Прибавление месяцев к дате 31 числа может дать неожиданный результат в конце февраля.

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

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

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

💡

Главное правило отладки дат: всегда проверяйте компонент времени. В 90% случаев логические ошибки возникают из-за того, что разработчик забыл, что в дате есть часы, минуты и секунды.

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

Как прибавить к дате один рабочий день, исключая выходные?

Простое прибавление +1 не учитывает календарь рабочих дней. Для этого нужно использовать цикл Пока, который будет проверять день недели с помощью функции ДеньНедели(). Если выпадает суббота (6) или воскресенье (7), счетчик дней не увеличивается, пока не наступит понедельник.

Что вернет выражение Дата("20260229") + 1 в невисокосном году?

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

Можно ли прибавить отрицательное число к дате?

Да, арифметика дат поддерживает отрицательные значения. Выражение Дата - 1 вернет вчерашний день. Это эквивалентно вызову ДобавлениеПериода(Дата, ВидПериода.День, -1). Механизм работает симметрично в обе стороны временной шкалы.

Как получить дату следующего месяца в тот же день?

Для этого лучше всего использовать функцию ДобавлениеПериода с параметром ВидПериода.Месяц. Прямое прибавление числа дней не подойдет, так как количество дней в месяцах разное (30, 31, 28, 29). Функция сама рассчитает корректную дату, учитывая длину месяца.

Влияет ли часовой пояс на результат сложения дат?

Внутри одной информационной базы время хранится в едином стандарте (обычно UTC или локальное время сервера). Арифметические операции выполняются над этим хранимым значением. Часовой пояс влияет только на отображение даты пользователю и на конвертацию при получении времени от клиента. Сама операция "+ 1 день" всегда сдвигает дату на 24 часа относительно внутренней шкалы времени.