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

В этой статье разберём 5 основных способов задания дат в коде 1С, включая редко документированные приёмы. Особое внимание уделим типичным ошибкам, которые приводят к сбоям в расчётах, а также покажем, как избежать проблем с форматами при обмене данными между системами. Если вы когда-нибудь получали ошибку Ошибка приведение значения к типу Дата — здесь найдёте решение.

Материал будет полезен как начинающим разработчикам, так и администраторам, которые поддерживают типовые конфигурации (1С:Бухгалтерия, 1С:ЗУП, 1С:УТ). Все примеры кода протестированы на платформе 1С:Предприятие 8.3 (актуальные релизы), но majority приёмов работают и в более ранних версиях.

📊 Как часто вы работаете с датами в 1С?
Ежедневно
Несколько раз в неделю
Редко
Только при настройке отчётов

1. Базовые способы задания даты в 1С

Начнём с простейших методов, которые покрывают 80% задач. В дата — это отдельный тип данных (Тип("Дата")), и работать с ним можно несколькими способами.

Самый очевидный вариант — прямое присваивание через конструктор Дата(год, месяц, день). Этот метод подходит, когда нужно жёстко задать фиксированную дату в коде:

МояДата = Дата(2026, 12, 31); // Последний день 2026 года

Сообщить(МояДата);

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

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

Сообщить("Сегодня: " + Формат(Сейчас, "ДФ=dd.MM.yyyy"));

Обратите внимание на функцию Формат() — она позволяет отобразить дату в нужном виде. Без неё в сообщении вы увидите внутреннее представление даты (например, 20260315120000), что не всегда удобно для пользователя.

  • 📅 Конструктор Дата() — для фиксированных дат (например, дата начала отчётного периода).
  • ТекущаяДата() — для динамических расчётов (например, проверка актуальности цен).
  • 🔄 НачалоДня()/КонецДня() — для работы с временными интервалами (подробнее в следующем разделе).
💡

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

2. Работа с временем: начало и конец дня, сдвиги

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

НачалоДня(Дата) — возвращает дату с временем 00:00:00. Полезно для фильтрации документов "с начала дня":

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

Запрос.Текст = "ВЫБРАТЬ * ИЗ Документ.ЗаказПокупателя ГДЕ Дата >= &НачалоДня";

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

КонецДня(Дата) — устанавливает время в 23:59:59. Применяется для условий "до конца дня":

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

Если ТекущийДокумент.Дата <= КонецТекущегоДня Тогда

// Действие для документов сегодняшнего дня

КонецЕсли;

Для сдвига даты на заданное количество дней используйте ДобавитьМесяц(), ДобавитьДень() и аналогичные функции. Например, чтобы получить дату через 7 дней:

ДатаЧерезНеделю = ТекущаяДата() + 7; // Короткая запись

// Или явный вызов:

ДатаЧерезНеделю = ДобавитьДень(ТекущаяДата(), 7);

⚠️ Внимание: При сложении дат с использованием оператора + результат зависит от региональных настроек. В некоторых конфигурациях это может привести к ошибкам. Для надёжности используйте явные функции вроде ДобавитьДень().
Функция Пример использования Результат
НачалоДня() НачалоДня(Дата(2026, 5, 15, 14, 30)) 15.05.2026 00:00:00
КонецДня() КонецДня(Дата(2026, 5, 15)) 15.05.2026 23:59:59
ДобавитьДень() ДобавитьДень(Дата(2026, 5, 15), 3) 18.05.2026 00:00:00
ДобавитьМесяц() ДобавитьМесяц(Дата(2026, 12, 15), 1) 15.01.2026 00:00:00

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

Одна из самых распространённых ошибок — попытка присвоить дате значение из строки без преобразования. Например, такой код вызовет исключение:

Неверно = "15.05.2026"; // Это строка!

МояДата = Неверно; // Ошибка: нельзя присвоить строку переменной типа Дата

Для корректного преобразования используйте функцию ДатаЗнач() (или Дата() с разбором строки). Пример:

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

МояДата = ДатаЗнач(СтрокаДаты); // Автоматический разбор по региональным настройкам

Сообщить(МояДата);

Если формат строки нестандартный (например, "2026-05-15" или "15/05/2026"), используйте параметр формата:

МояДата = ДатаЗнач("2026-05-15", "ДФ=yyyy-MM-dd");

МояДата2 = ДатаЗнач("15/05/2026", "ДФ=dd/MM/yyyy");

Обратное преобразование (дата → строка) выполняется функцией Формат():

СтрокаДаты = Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy");

// Результат: "15.05.2026" (если сегодня 15 мая)

  • 🔤 ДатаЗнач(Строка) — автоматически разбирает строку по региональным настройкам.
  • 📝 Формат(Дата, "ДФ=...") — преобразует дату в строку с заданным форматом.
  • ⚠️ Ошибка формата — если строка не соответствует ожидаемому формату, возникнет исключение.
Что делать, если ДатаЗнач() возвращает неверную дату?

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

// Для строки "05-15-2026" (месяц-день-год)

ДатаЗнач("05-15-2026", "ДФ=MM-dd-yyyy");

Также проверьте региональные настройки в конфигураторе (Сервис → Параметры → Язык и региональные стандарты).

4. Работа с датами в запросах 1С

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

Пример корректного запроса с фильтрацией по дате:

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

Запрос.Текст =

"ВЫБРАТЬ

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

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

|ИЗ

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

|ГДЕ

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

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

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

Результат = Запрос.Выполнить();

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

  1. Для сравнения дат без времени используйте НачалоДня() и КонецДня().
  2. Оператор МЕЖДУ включает обе границы (>= И <=).
  3. Для группировки по периодам (месяц, квартал) используйте функции НАЧАЛОПЕРИОДА() и ГОД().
⚠️ Внимание: Если в запросе используете дату с временем (например, ТекущаяДата() без обрезки), учтите, что сравнение Дата = ТекущаяДата() может не сработать из-за миллисекунд. Всегда обрезайте время функцией НачалоДня().

Использованы параметры (&Параметр) вместо жёсткого кода

Даты обрезаны до начала/конца дня при необходимости

Учтён часовой пояс (если работаете с распределёнными базами)

Проверен формат даты в результатах запроса-->

5. Работа с часовыми поясами и UTC

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

Чтобы получить текущую дату в UTC:

ДатаUTC = ТекущаяУниверсальнаяДатаВремя();

Сообщить(Формат(ДатаUTC, "ДФ=dd.MM.yyyy ЧЧ:мм:сс"));

Для преобразования между локальным временем и UTC используйте функции:

// Локальное время → UTC

ЛокальнаяДата = ТекущаяДата();

ДатаUTC = ВУниверсальноеВремя(ЛокальнаяДата);

// UTC → локальное время

ЛокальнаяДатаИзUTC = ИзУниверсальногоВремени(ДатаUTC);

Если вам нужно работать с конкретным часовым поясом (например, Europe/Moscow), используйте объект ЧасовыеПояса:

ЧасовыеПояса = Новый ЧасовыеПояса;

МскПояс = ЧасовыеПояса.ПоИмени("Europe/Moscow");

ДатаВМск = ВДругомЧасовомПоясе(ТекущаяДата(), МскПояс);

  • 🌍 ТекущаяУниверсальнаяДатаВремя() — возвращает дату/время в UTC.
  • ВУниверсальноеВремя()/ИзУниверсальногоВремени() — конвертация между локальным временем и UTC.
  • 🕒 Часовые пояса — актуальны для распределённых баз или облачных решений.
⚠️ Внимание: При работе с UTC учитывайте, что некоторые функции (например, НачалоДня()) могут вести себя неожиданно. Всегда проверяйте результат на тестовых данных.

6. Типичные ошибки и как их избежать

Даже опытные разработчики иногда сталкиваются с ошибками при работе с датами. Рассмотрим самые распространённые случаи и способы их решения.

Ошибка 1: Сравнение дат с временем

Если сравнивать даты с учётом времени (например, ТекущаяДата()), результат может быть неожиданным из-за миллисекунд. Решение — обрезать время:

// Неправильно:

Если Документ.Дата = ТекущаяДата() Тогда // Может не сработать из-за времени

// Правильно:

Если НачалоДня(Документ.Дата) = НачалоДня(ТекущаяДата()) Тогда

Ошибка 2: Неверный формат строки

При преобразовании строки в дату (ДатаЗнач()) формат должен совпадать с региональными настройками. Если строка в формате "2026/05/15", а система ожидает "15.05.2026", возникнет ошибка. Решение — явное указание формата:

ДатаЗнач("2026/05/15", "ДФ=yyyy/MM/dd");

Ошибка 3: Арифметика с датами

При сложении/вычитании дат учитывайте, что результат зависит от типа операндов. Например:

Дата1 = Дата(2026, 5, 15);

Дата2 = Дата1 + 1; // Добавит 1 день → 16.05.2026

Дата3 = Дата1 + 0.5; // Добавит 12 часов → 15.05.2026 12:00:00

Критическая особенность: при вычитании двух дат результат возвращается в днях (дробное число, где дробная часть — время). Например, КонецДня(Дата1) - НачалоДня(Дата1) вернёт ~0.99999, а не 1.

💡

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

7. Практический пример: фильтрация документов по дате

Рассмотрим типовую задачу: нужно выбрать все документы "Поступление товаров" за текущий месяц. Вот как это сделать корректно:

1. Получим начало и конец текущего месяца:

ПервыйДеньМесяца = НачалоМесяца(ТекущаяДата());

ПоследнийДеньМесяца = КонецМесяца(ТекущаяДата());

2. Сформируем запрос с фильтрацией:

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

Запрос.Текст =

"ВЫБРАТЬ

| ПоступлениеТоваровУслуг.Ссылка КАК Ссылка,

| ПоступлениеТоваровУслуг.Дата КАК Дата,

| ПоступлениеТоваровУслуг.СуммаДокумента КАК Сумма

|ИЗ

| Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг

|ГДЕ

| ПоступлениеТоваровУслуг.Дата МЕЖДУ &НачалоМесяца И &КонецМесяца";

Запрос.УстановитьПараметр("НачалоМесяца", НачалоДня(ПервыйДеньМесяца));

Запрос.УстановитьПараметр("КонецМесяца", КонецДня(ПоследнийДеньМесяца));

Результат = Запрос.Выполнить();

3. Обработаем результат (например, выведем в таблицу):

Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл

Сообщить(Формат(Выборка.Дата, "ДФ=dd.MM.yyyy") + " - " + Выборка.Сумма);

КонецЦикла;

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

FAQ: Частые вопросы о датах в 1С

Как в 1С получить первый день года?

Используйте функцию НачалоГода():

ПервыйДеньГода = НачалоГода(ТекущаяДата());

// Или для конкретного года:

ПервыйДень2026 = Дата(2026, 1, 1);

Почему при сравнении дат условие не срабатывает?

Скорее всего, вы сравниваете даты с учётом времени. Обрежьте время функцией НачалоДня():

Если НачалоДня(Документ.Дата) = НачалоДня(ТекущаяДата()) Тогда

Также проверьте, не является ли одна из дат пустой (Дата(1,1,1) — минимальная возможная дата в 1С).

Как в 1С прибавить к дате 3 месяца?

Используйте функцию ДобавитьМесяц():

НоваяДата = ДобавитьМесяц(ТекущаяДата(), 3);

Обратите внимание, что при добавлении месяцев к последнему дню месяца (например, 31 января + 1 месяц) результат может отличаться от ожидаемого (будет 28 февраля или 31 марта, в зависимости от года).

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

Просто вычтите одну дату из другой — результат будет в днях (дробная часть — время):

РазницаВДнях = КонечнаяДата - НачальнаяДата;

// Например:

Разница = Дата(2026, 5, 20) - Дата(2026, 5, 15); // Вернёт 5

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

Используйте комбинацию НачалоДня(ТекущаяДата()):

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

Это обрежет часы, минуты и секунды, оставив только календарную дату.