Прибавить дни, месяцы и годы к дате в 1С 8.3
Содержание
Чтобы увеличить дату в 1С на несколько дней, прибавьте к ней число секунд: Дата + 5 * 86400 даёт дату на пять дней позже. Месяцы и годы добавляет функция ДобавитьМесяц(), а в запросе работает ДОБАВИТЬКДАТЕ(). Если нужна другая дата в документе, достаточно поправить реквизит в шапке, но с закрытым периодом придётся разбираться отдельно.
Под фразой «увеличить дату» обычно скрываются четыре разные задачи: сменить дату документа, сдвинуть дату в коде, сдвинуть её в запросе и отчёте, поменять системное время. Ниже каждая из них разобрана отдельно, с примерами и подводными камнями.
Что именно вы хотите сдвинуть
Сначала определите, о какой дате речь. От этого зависит весь дальнейший путь.
| Задача | Где делается | Нужен программист |
|---|---|---|
| Дата проведённого или нового документа | Шапка документа, поле даты | Нет |
| Дата в расчёте (срок оплаты, окончание договора) | Модуль, встроенный язык | Да |
| Сдвиг даты в выборке и отчёте | Запрос, схема компоновки данных | Да, но простой |
| Системное время компьютера или сервера | Настройки Windows | Нет, но это опасно |
Для обычного пользователя первая строка закрывает 90% ситуаций. Остальное нужно тем, кто настраивает отчёты и пишет обработки.
Меняем дату документа в пользовательском режиме
Откройте документ, найдите в шапке поле с датой и временем (обычно подписано «от»). Щёлкните по нему и введите нужное значение с клавиатуры либо нажмите кнопку выбора и укажите день в календаре. Для сдвига удобны клавиши: в поле даты работают + и -, которые увеличивают и уменьшают выбранную часть значения (день, месяц, год) на единицу. Какая часть меняется, зависит от того, где стоит курсор.
После смены даты проведите документ заново. Движения перезапишутся на новую дату, а порядок документов внутри дня определяется временем, поэтому для двух документов за один день время тоже имеет значение.
Если нужно просто дописать документ «задним числом» внутри дня, не меняйте дату. Достаточно поправить время: документы одного дня упорядочиваются по нему.
Что происходит при переносе даты на другой месяц:
- 📌 Нумерация в новом периоде может не совпасть: номер присваивается при записи по правилам нумерации, а не по дате.
- 📌 Документы-основания и подчинённые документы остаются на старых датах, их придётся сдвигать вручную.
- 📌 Отчёты за прошлые периоды после переноса пересчитаются, а сданная отчётность останется прежней.
Перенос даты проведённого документа в другой отчётный период меняет учёт. Согласуйте его с главным бухгалтером до того, как нажмёте «Провести».
Когда 1С не даёт поставить новую дату
Самая частая причина: в базе установлена дата запрета изменения данных. Всё, что раньше этой даты, программа не позволяет ни записать, ни провести, ни пометить на удаление. При попытке выводится сообщение о запрете редактирования в закрытом периоде.
Что с этим делать:
- Выясните, кто и зачем закрыл период. Обычно это делает главный бухгалтер после сдачи отчётности.
- Откройте раздел
Администрированиеи найдите настройку дат запрета изменения (в типовых конфигурациях на БСП она называется «Даты запрета изменения»). Если ссылку не видно, у вашей роли может не хватать прав. - Дату запрета можно задать общей для всей базы, отдельно по организациям или по видам данных. Проверьте все уровни, а не только общий.
- Отодвигайте дату назад только по согласованию, внесите правку и верните запрет на место.
Снятие запрета «навсегда» открывает путь к тихим исправлениям в закрытых периодах. Лучше снять его на день, исправить и поставить обратно.
Если вы переносите документ из закрытого периода в открытый, проверяется и старая, и новая дата. Запрет на любой из них блокирует запись.
Прибавляем дни, часы и минуты в коде
Тип «Дата» во встроенном языке хранит момент времени. Арифметика с ним устроена просто: если прибавить число, оно воспринимается как секунды.
Сегодня = НачалоДня(ТекущаяДатаСеанса());
ЧерезНеделю = Сегодня + 7 * 24 * 60 * 60; // +7 суток
ЧерезЧас = ТекущаяДатаСеанса() + 3600; // +1 час
ВчераУтром = Сегодня - 86400; // -1 сутки
Пример с числами: Дата(2025, 3, 15) + 10 * 86400 равно 25.03.2025, потому что 10 суток это 864 000 секунд.
Разность двух дат тоже возвращается в секундах:
Начало = Дата(2025, 3, 1);
Конец = Дата(2025, 3, 31);
Дней = (Конец - Начало) / 86400; // 30
Полезные функции для работы с границами периодов:
- 🗓
НачалоДня()иКонецДня()отсекают время или ставят 23:59:59; - 🗓
НачалоМесяца(),КонецМесяца(),НачалоКвартала(),НачалоГода()дают границы периода для любой даты; - 🗓
НачалоНедели()иКонецНедели()дают границы недели, аДеньНедели()возвращает номер дня: понедельник это 1, воскресенье 7.
Складывайте дату только с числом. Строка вместо числа вызовет ошибку преобразования типа, а пустая дата Дата(1, 1, 1) после прибавления даёт «ненастоящий» первый год, который потом попадает в отчёты.
Месяцы и годы: ДобавитьМесяц
Сутки не равны месяцу, поэтому прибавлять 30 * 86400 для «через месяц» нельзя. Для календарных сдвигов есть ДобавитьМесяц(Дата, Количество):
Начальная = Дата(2025, 1, 31);
Вперёд = ДобавитьМесяц(Начальная, 1); // 28.02.2025
Год = ДобавитьМесяц(Начальная, 12); // 31.01.2026
Назад = ДобавитьМесяц(Начальная, -2); // 30.11.2024
Если в целевом месяце нет такого числа, функция возвращает последний день месяца: 31 января плюс месяц даёт 28 февраля. Время суток сохраняется.
Отдельной функции для лет нет, год это ДобавитьМесяц(Дата, 12). Поэтому для 29 февраля високосного года через год получится 28 февраля.
Типовые задачи на этом приёме:
| Что считаем | Формула |
|---|---|
| Срок действия договора на 12 месяцев | ДобавитьМесяц(НачалоДоговора, 12) - 1 (минус сутки) |
| Первый день следующего месяца | ДобавитьМесяц(НачалоМесяца(Дата), 1) |
| Последний день следующего месяца | КонецМесяца(ДобавитьМесяц(Дата, 1)) |
| Квартал назад | ДобавитьМесяц(НачалоКвартала(Дата), -3) |
Для вычитания единицы в последней строке таблицы важен порядок: сначала привести дату к началу периода, потом сдвигать.
Рабочие дни, а не календарные
Задачу «через 10 рабочих дней» ставят постоянно: срок ответа на претензию, срок отправки документа, окончание пробного периода.
Прибавить «пять рабочих дней» простым умножением не получится: выходные и праздники в такой расчёт не входят. В типовых конфигурациях есть производственный календарь , и расчёт строится по нему. Самый надёжный способ без самописной логики: найти в вашей конфигурации готовую функцию для работы с графиком (в библиотеке стандартных подсистем есть календарные графики) и вызывать её, а не писать цикл с проверкой выходных.
Вариант на крайний случай: цикл, который прибавляет по одним суткам и считает только те, что помечены в календаре рабочими. Он медленнее готовой функции, зато прозрачен и легко проверяется на примере. Если пишете свой цикл, учтите перенос выходных, который утверждается ежегодно: хардкодом дни не зашить, данные должны браться из справочников календаря.
Сдвиг даты в запросе и отчёте
В запросе прибавление делается функцией ДОБАВИТЬКДАТЕ:
ВЫБРАТЬ
Договоры.Ссылка КАК Договор,
ДОБАВИТЬКДАТЕ(Договоры.Дата, ДЕНЬ, 30) КАК СрокОплаты,
ДОБАВИТЬКДАТЕ(Договоры.Дата, МЕСЯЦ, 6) КАК КонецГарантии
ИЗ
Справочник.ДоговорыКонтрагентов КАК Договоры
Вторым параметром указывается тип приращения: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД. Третий параметр, число, может быть отрицательным.
Для подсчёта промежутка между датами используется РАЗНОСТЬДАТ(Начало, Конец, ДЕНЬ). Эту функцию удобно ставить в условие отбора просроченных документов.
В схеме компоновки данных (отчёты) дату сдвигают одним из способов:
- 📊 вычисляемое поле с выражением
ДобавитьМесяц(Период, 1); - 📊 параметр отчёта с типом «Стандартная дата начала», где пользователь выбирает «начало этого месяца», «прошлый квартал» и подобные варианты;
- 📊 функция
ДОБАВИТЬКДАТЕвнутри текста запроса набора данных.
Параметры периода лучше передавать в запрос, а не собирать строкой: так нет проблем с форматом даты и со временем в конце суток. Для включения последнего дня периода берите КонецПериода или КонецДня, иначе документы после полуночи пропадут из выборки.
Часовой пояс и «текущая дата»
Здесь чаще всего ошибаются те, у кого пользователи сидят в разных регионах.
- ⏱
ТекущаяДата()возвращает время компьютера, на котором выполняется код. В клиент-серверной базе серверный вызов даст время сервера, клиентский вызов время рабочего места. - ⏱
ТекущаяДатаСеанса()учитывает часовой пояс, заданный для сеанса. Для прикладного кода это основной выбор. - ⏱
ТекущаяУниверсальнаяДата()возвращает время UTC, его удобно хранить и сравнивать. - ⏱
МестноеВремя()иУниверсальноеВремя()переводят значения туда и обратно по заданному поясу.
Если сервер стоит в Москве, а филиал во Владивостоке, документы, созданные кодом через ТекущаяДата(), окажутся со временем сервера, а не филиала. Разница в семь часов может сдвинуть документ на соседние сутки.
Часовой пояс информационной базы выставляется в её свойствах. Если его менять в базе с накопленными данными, проверьте регламентные задания и расписания: они привязаны ко времени.
Системное время: когда нельзя и когда осторожно
Иногда спрашивают, как «увеличить дату в 1С» сменой даты в Windows. Платформа берёт время у операционной системы, поэтому такой способ технически работает. Но на нём держится слишком много:
- ⛔ журнал регистрации и записи в базе получат «прыгающее» время, и разбирать инциденты станет невозможно;
- ⛔ регламентные задания либо не сработают, либо запустятся пачкой;
- ⛔ сертификаты электронной подписи и защищённые соединения проверяют срок действия по системному времени, их поведение непредсказуемо;
- ⛔ у сервера 1С переводить часы без остановки службы нельзя: оборвутся сеансы всех пользователей.
Применимо это только для тестовой копии базы на отдельной машине. В рабочей базе корректный путь один: менять дату в документе или в расчёте, а не время системы.
Отладка: почему дата получилась не та
Если после расчёта в поле оказалась неожиданная дата, проверьте по порядку:
- Какой тип имеет переменная. Если результат запроса вернул
Неопределеноили пустую ссылку, арифметика даст ошибку или нулевую дату. - Не перепутаны ли секунды и дни. Прибавка
5к дате добавляет пять секунд, а не пять дней. - Нет ли «хвоста» времени. Сравнение
Дата1 = Дата2учитывает часы и минуты, поэтому перед сравнением дней приводите обе даты кНачалоДня(). - Как значение выводится в форму. Формат отображения не влияет на содержимое, но по нему легко принять 01.02 за 2 января.
- Не затёрла ли результат обработка заполнения. Некоторые формы пересчитывают срок при каждом изменении исходного реквизита.
Ещё один частый источник путаницы: пользователь видит дату в формате «день.месяц.год», а в коде она хранится как момент времени без формата вообще. Поэтому сравнивать даты по их строковому представлению нельзя, сравнивайте сами значения.
Для быстрой проверки выводите промежуточные значения через Формат(Дата, "ДФ=dd.MM.yyyy HH:mm:ss"): так видны и дата, и время.
Частые вопросы
Как прибавить к дате один год в 1С?
ДобавитьМесяц(Дата, 12). Для 29 февраля результат придётся на 28 февраля следующего года.Почему при прибавлении 30 к дате меняется только время?
ДОБАВИТЬКДАТЕ в запросе.