Работа с датами и временем является одной из базовых операций при разработке конфигураций на платформе 1С:Предприятие 8. Разработчикам часто требуется сдвинуть срок оплаты, рассчитать дату следующего документа или определить период действия договора. Самая частая задача в этом ряду — увеличение текущей даты на единицу времени.
Казалось бы, операция тривиальна, однако платформа предоставляет несколько способов её реализации, каждый из которых имеет свои нюансы производительности и читаемости кода. Неправильный подход может привести к ошибкам при переходе через високосные годы или месяцы с разным количеством дней.
В этом материале мы детально разберем все доступные методы сдвига даты, рассмотрим встроенные функции платформы и проанализируем, как система обрабатывает граничные значения календаря.
Прямое арифметическое сложение в коде
Самый очевидный и часто используемый способ получения новой даты — это использование оператора сложения. В языке 1С тип данных Дата поддерживает арифметические операции с числами, где единица измерения числа соответствует одному дню.
Для того чтобы прибавить к переменной ТекущаяДата ровно одни сутки, достаточно написать простую строку кода. Платформа автоматически вычислит новое значение, учитывая переход на следующий месяц или год.
НоваяДата = ТекущаяДата + 1;
Этот метод является наиболее производительным, так как не требует вызова дополнительных функций и выполняется на уровне ядра платформы. Однако при чтении кода коллегами может возникнуть вопрос о размерности единицы «1».
⚠️ Внимание: При использовании числового литерала всегда помните, что дробная часть числа означает время. Например, прибавление 1.5 добавит одни сутки и 12 часов.
Если вам нужно изменить дату на несколько дней, вы просто умножаете единицу на нужное количество. Такой подход делает код компактным, но менее самодокументируемым по сравнению с вызовом специализированных функций.
Используйте прямое сложение (Дата + 1) в циклах с большим количеством итераций, где критична скорость выполнения кода.
Использование встроенной функции ДобавлениеМесяца
Хотя для добавления дней чаще используют арифметику, в платформе существует универсальная функция ДобавлениеМесяца. Она предназначена для сдвига даты на заданное количество месяцев, но может быть адаптирована и для работы с днями через вспомогательные конструкции.
Однако, более корректным аналогом для работы с произвольными интервалами является функция ДобавитьПериод (в некоторых версиях или контекстах встречается как часть работы с периодами). Но классическим решением для явного указания интервала "день" считается использование констант времени.
Рассмотрим пример, где мы явно указываем, что добавляем именно временной интервал. Это повышает читаемость кода, делая намерение разработчика очевидным для любого, кто будет поддерживать конфигурацию в будущем.
Существует также подход с использованием функции НачалоДня в комбинации со сложением, если вам важно сбросить время до нуля перед добавлением суток. Это частый кейс при расчете сроков исполнения задач.
ДатаЗавтра = НачалоДня(ТекущаяДата) + 1;
Такой код гарантирует, что вы получите ровно начало следующих суток, независимо от того, в какое время дня был создан исходный документ.
Тонкости работы с функцией Дата
Иногда возникает необходимость сконструировать новую дату «с нуля», используя компоненты старой даты. Для этого применяется функция Дата, которая принимает год, месяц, день, час, минуту и секунду.
Вы можете извлечь день из исходной даты, прибавить к нему единицу и передать результат в конструктор. Этот метод полезен, если вам нужно реализовать сложную логику валидации перед созданием новой даты.
- 📅 Извлеките год с помощью функции
Год(ИсходнаяДата). - 📅 Получите номер месяца через
Месяц(ИсходнаяДата). - 📅 Увеличьте день на единицу:
День(ИсходнаяДата) + 1.
Главное преимущество такого подхода — полный контроль над каждым компонентом даты. Вы можете добавить проверку: если день стал больше 31, то переключить месяц. Хотя платформа делает это автоматически при передаче некорректного дня в функцию Дата.
Например, если вы передадите в функцию дату 32 января, система автоматически конвертирует её в 1 февраля. Это поведение называется нормализацией даты и является стандартным для 1С:Предприятие.
НоваяДата = Дата(Год(СтараяДата), Месяц(СтараяДата), День(СтараяДата) + 1);
Использование этого метода может быть избыточным для простой задачи, но оно демонстрирует гибкость встроенного языка при решении нестандартных календарных задач.
Обработка високосных лет и переходов месяцев
Одна из самых больших проблем при ручном расчете дат — учет високосных лет. В году, делящемся на 4 (но не на 100, если только не на 400), в феврале 29 дней. Ошибка в логике может привести к тому, что 28 февраля + 1 день превратится в 1 марта, пропустив 29-е число.
К счастью, все стандартные методы 1С, описанные выше, корректно обрабатывают високосные годы. Платформа хранит дату как количество секунд, прошедших с начала эры, поэтому переходы между месяцами и годами происходят математически точно.
| Исходная дата | Операция | Результат в 1С | Тип года |
|---|---|---|---|
| 28.02.2023 | + 1 день | 01.03.2023 | Обычный |
| 28.02.2026 | + 1 день | 29.02.2026 | Високосный |
| 29.02.2026 | + 1 день | 01.03.2026 | Високосный |
| 31.01.2026 | + 1 день | 01.02.2026 | Обычный |
Как видно из таблицы, система самостоятельно определяет длину месяца. Вам не нужно писать условия Если Месяц = 2 Тогда... Это существенно упрощает разработку сложных алгоритмов планирования.
⚠️ Внимание: При работе с историческими датами (до 1918 года в РФ) учитывайте возможную разницу между юлианским и григорианским календарем, если это критично для вашей предметной области.
Как 1С хранит дату внутри?
Дата в 1С хранится как 64-битное целое число, представляющее количество тиков (1 тик = 100 наносекунд), прошедших с 1 января 1 года н.э. по всемирному координированному времени (UTC).
Сдвиг даты в запросах к базе данных
Часто необходимость прибавить день возникает не в коде модуля, а непосредственно в тексте запроса к базе данных. Язык запросов 1С имеет свой синтаксис для работы с временными интервалами.
Для выполнения операции в запросе используется ключевое слово ИНТЕРВАЛ. Это позволяет фильтровать данные или вычислять поля прямо на стороне СУБД, что повышает производительность выборки.
ВЫБРАТЬ
Документ.Ссылка,
Документ.Дата + ИНТЕРВАЛ "1 ДЕНЬ" КАК ДатаИсполнения
ИЗ
Документ.Заказы КАК Документ
Использование конструкции ИНТЕРВАЛ "1 ДЕНЬ" является стандартом для запросов. Вы также можете использовать переменные, передавая в них значение интервала из кода 1С.
Все вычисления должны производиться средствами языка запросов или через виртуальные таблицы.
- ⚡ Используйте
ИНТЕРВАЛдля фильтрации периодов в условияхГДЕ. - ⚡ Применяйте сдвиг даты в списке
ВЫБРАТЬдля формирования отчетных показателей. - ⚡ Избегайте вызова внешних функций в запросах, это замедляет работу базы.
Если вы работаете с большими объемами данных, вынос вычислений даты в запрос является обязательным требованием оптимизации.
Всегда выполняйте арифметику с датами на стороне СУБД (в запросе), если это возможно, чтобы снизить нагрузку на сервер приложений 1С.
Частые ошибки и рекомендации по оптимизации
Несмотря на простоту операции, разработчики часто допускают ошибки, связанные с временными зонами и форматом хранения данных. В клиент-серверном варианте работы время на клиенте и на сервере может отличаться.
При сохранении документа дата записывается в базу в формате UTC (всемирное время), а при отображении пользователю конвертируется в локальное время региона. При добавлении дня важно понимать, к какому времени вы применяете операцию.
Если вы прибавляете день к дате, полученной от клиента, убедитесь, что переход через полночь не приведет к смещению на лишние сутки из-за разницы часовых поясов.
⚠️ Внимание: Интерфейсы и способы вызова функций могут незначительно отличаться в зависимости от версии платформы 1С:Предприятие. Всегда сверяйте синтаксис в справочнике разработчика для вашей конкретной версии.
Для оптимизации кода старайтесь избегать многократного вызова функций извлечения компонентов (Год, Месяц, День) внутри циклов. Прямое сложение работает быстрее.
Также стоит использовать тип ДатаВремя осторожно. Если вам нужна только дата, обязательно обнуляйте время функцией НачалоДня, чтобы избежать ошибок при сравнении.
☑️ Проверка корректности работы с датами
FAQ: Часто задаваемые вопросы
Как прибавить к дате 1 рабочий день, исключая выходные?
Для этого простого сложения недостаточно. Необходимо использовать цикл Пока, который будет проверять день недели с помощью функции ДеньНедели. Если выпадает суббота (6) или воскресенье (7), нужно прибавлять день до тех пор, пока не попадете на будний день.
В чем разница между Дата + 1 и Дата + Время(0,0,24,0)?
Функционально результат одинаков — сдвиг на 24 часа. Однако запись Дата + 1 более читаема и предпочтительна. Конструкция с функцией Время может быть полезна, если нужно добавить конкретное количество часов, минут или секунд, а не целые сутки.
Что будет, если прибавить день к 31 декабря?
Система автоматически осуществит переход на следующий год. Результатом будет 1 января следующего года. Вам не нужно вручную менять значение года, платформа сделает это за вас благодаря внутренней нормализации дат.
Как вычесть один день из даты в 1С?
Используется оператор вычитания. Синтаксис аналогичен сложению: НоваяДата = ИсходнаяДата - 1. Это сдвинет дату на одни сутки назад, корректно обрабатывая переходы между месяцами и годами в обратном направлении.
Можно ли использовать дробные числа для добавления части дня?
Да, можно. Например, Дата + 0.5 добавит 12 часов. Однако будьте осторожны: при отображении такой даты в формах могут возникнуть нюансы округления минут, в зависимости от настроек формата вывода.