При работе в среде 1С:Предприятие начинающие разработчики часто сталкиваются с неожиданным поведением системы при попытке выполнить простейшие арифметические операции с датами. Например, если к значению типа Дата прибавить число 5, система не выдаст ошибку, но результат будет отличаться от ожидаемого: вместо пяти дней прибавится пять секунд. В этой статье мы подробно разберем, почему так происходит, и изучим все корректные способы решения этой задачи.
Прежде всего, нам необходимо понять внутреннее устройство платформы. В 1С тип данных Дата хранит в себе одновременно и календарную дату, и время (с точностью до секунды). Основная особенность заключается в том, что внутреннее представление даты в 1С — это количество секунд, прошедших с начала нашей эры (0001-01-01 00:00:00).
Именно поэтому, когда мы пишем ТекущаяДата() + 5, платформа интерпретирует это буквально: "взять текущее количество секунд и добавить к нему еще 5". В итоге мы получаем ту же дату и время, но на 5 секунд позже. Чтобы работать с днями, нам нужно перевести их в универсальную единицу измерения системы — секунды.
Рассмотрим самый простой и эффективный способ изменения даты непосредственно в программном коде. Чтобы прибавить 5 дней, нам нужно вычислить, сколько секунд содержится в этом периоде. Разберем расчет по шагам:
Таким образом, магическое число 86400 — это константа секунд в одних сутках. Проанализируем правильный код для решения нашей задачи:
КоличествоДней = 5;
СекундВСутках = 86400;
НоваяДата = ТекущаяДата() + (КоличествоДней * СекундВСутках);
Сообщить(НоваяДата);
Этот метод работает безотказно как на стороне клиента, так и на стороне сервера. Однако, для повышения читаемости кода в крупных проектах часто используют вспомогательные функции. Рассмотрим пример оформления такого решения в виде функции:
// Функция добавляет заданное количество дней к дате.
Функция ДобавитьДниКДате(ИсходнаяДата, ЧислоДней) Экспорт
Возврат ИсходнаяДата + (ЧислоДней * 86400);
КонецФункции
Иногда задача прибавления дней возникает не в программном коде, а при выборке данных из базы. В языке запросов 1С математика с секундами не применяется так же напрямую, как в коде. Вместо этого используется специальная встроенная функция ДОБАВИТЬКДАТЕ. Посмотрим на пример запроса, который решает нашу задачу:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДОБАВИТЬКДАТЕ(&НачальнаяДата, ДЕНЬ, 5) КАК ДатаЧерезПятьДней";
Запрос.УстановитьПараметр("НачальнаяДата", ТекущаяДата());
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Сообщить(Выборка.ДатаЧерезПятьДней);
КонецЕсли;
Преимущество этого метода заключается в его универсальности. Функция ДОБАВИТЬКДАТЕ умеет работать не только с днями, но и с месяцами, годами, кварталами. При этом она автоматически учитывает календарные нюансы (например, разное количество дней в месяцах и високосные годы), что делает её незаменимой при сложных расчетах.
Для ускорения разработки в конфигураторе 1С предусмотрен механизм шаблонов кода. Чтобы не вспоминать каждый раз количество секунд в сутках, мы можем воспользоваться быстрыми командами. Если в текстовом редакторе модуля набрать +д и нажать комбинацию клавиш Ctrl + Q, система предложит вставить готовую конструкцию для работы с датами.
Это отличный способ избежать опечаток в больших числах и сэкономить время при написании кода.
Разберем несколько важных моментов, которые часто упускают из виду:
1. Начало дня и сравнение дат. Если вы прибавляете 5 дней к ТекущаяДата(), результат будет содержать текущее время (например, 14:30:15). Если вам нужно получить дату через 5 дней строго на начало суток (00:00:00), используйте функцию НачалоДня(). Проанализируем пример:
// Получаем дату через 5 дней, но время сбрасываем в 00:00:00
Результат = НачалоДня(ТекущаяДата() + 5 * 86400);
2. Месяцы и годы. В отличие от дней, количество секунд в месяце или годе — величина переменная. Никогда не пытайтесь прибавлять месяцы через умножение секунд! Для этого в 1С существует встроенная функция ДобавитьМесяц(Дата, Количество). Она корректно обработает переход, например, с 31 августа на 30 сентября.
3. Производственный календарь. Если ваша задача — прибавить 5 рабочих дней, то простым сложением секунд здесь не обойтись. В типовых конфигурациях (БП, ЗУП, ERP) для этого используются специальные функции из Библиотеки стандартных подсистем (БСП), которые обращаются к графику работ и производственному календарю, чтобы пропустить праздники и выходные.
4. Читаемость кода. Использование "магических чисел" вроде 86400 в коде считается плохим тоном. Профессиональнее будет либо использовать именованную переменную, либо вызывать стандартную функцию, если она предусмотрена в вашей конфигурации (например, ОбщегоНазначения.ДобавитьДниКДате).
Выяснив причину, по которой 1С работает с секундами, мы теперь можем уверенно манипулировать временными интервалами. Помните: для дней используем 86400, для месяцев — ДобавитьМесяц(), а в запросах всегда применяем ДОБАВИТЬКДАТЕ. Это обеспечит надежность и точность ваших алгоритмов.