Разработка и Конфигурация · 10 мин
Как в 1С работать с датой: практическое руководство
Как в 1С работать с датой: форматирование, функции языка, даты в запросах, периоды документов, частые ошибки и проверка результата.
Дата — один из самых часто используемых типов данных в 1С: ей заполнены документы, регистры, отчёты и отборы. При этом ошибки в работе с датами встречаются постоянно: сбивается формат вывода, дата сравнивается как строка, запрос возвращает пустой результат из-за неверно заданного периода.
Встроенный язык 1С предоставляет отдельный тип «Дата», который хранит дату и время с точностью до секунды, а также набор функций для получения, преобразования и форматирования дат. Важно понимать разницу между датой как значением и её строковым представлением — большинство проблем возникает именно на этом стыке.
Материал охватывает работу с датами в трёх контекстах: во встроенном языке (модули конфигурации), в языке запросов и в пользовательском интерфейсе. Подходы подходят для типовых конфигураций на платформе 8.3, но общие принципы применимы и к более ранним версиям.
Тип «Дата» и способы его создания
Тип «Дата» в 1С объединяет календарную дату и время. Пустое значение даты — это 01.01.0001 00:00:00, и его часто используют как признак «дата не заполнена». Проверка на пустую дату выполняется сравнением с литералом '00010101' или через функцию ЗначениеЗаполнено().
Создать дату можно несколькими способами. Литерал даты записывается в одинарных кавычках в формате ГГГГММДД, например '20260115' или с временем '20260115143000'. Функция Дата() позволяет собрать значение из чисел: Дата(2026, 1, 15, 14, 30, 0) или преобразовать строку.
// Литерал даты
ДатаДокумента = '20260315';
// Из составляющих
ДатаСобранная = Дата(2026, 3, 15, 10, 30, 0);
// Из строки
ДатаИзСтроки = Дата("20260315103000");
// Проверка на пустую дату
Если Не ЗначениеЗаполнено(ДатаДокумента) Тогда
Сообщить("Дата не заполнена");
КонецЕсли;Частая ошибка — сравнение даты со строкой вида «15.03.2026». Такое сравнение работает непредсказуемо, потому что строка автоматически приводится к дате по правилам, зависящим от региональных настроек. Всегда приводите обе стороны сравнения к типу «Дата» явно.
Получение текущей даты и её составляющих
Для получения текущей даты в серверном коде используйте функцию ТекущаяДатаСеанса(). Она возвращает дату и время сеанса с учётом часового пояса, что важно для распределённых баз и веб-клиента. Функция ТекущаяДата() на клиенте возвращает время компьютера пользователя и может отличаться от серверного времени — в документах и регистрах опирайтесь именно на дату сеанса.
Извлечь части даты помогают функции Год(), Месяц(), День(), Час(), Минута(), Секунда() и ДеньНедели(). Для получения начала или конца периода есть готовые функции: НачалоДня(), КонецДня(), НачалоМесяца(), КонецМесяца(), НачалоКвартала(), КонецКвартала(), НачалоГода(), КонецГода(), НачалоНедели(), КонецНедели().
ТекДата = ТекущаяДатаСеанса();
НачалоТекущегоМесяца = НачалоМесяца(ТекДата);
КонецПрошлогоМесяца = КонецМесяца(ДобавитьМесяц(ТекДата, -1));
НомерГода = Год(ТекДата);
НомерДняНедели = ДеньНедели(ТекДата); // 1 — понедельник, 7 — воскресеньеФункции НачалоДня() и КонецДня() особенно важны при построении отборов по периоду: КонецДня() возвращает 23:59:59, и если вместо неё использовать просто дату без времени (00:00:00), документы, проведённые в течение последнего дня периода, выпадут из выборки.
Форматирование и вывод даты
Для представления даты пользователю применяется функция Формат() с форматной строкой. Основные шаблоны: ДФ — для даты, ДЛФ — для локализованных форматов. Например, Формат(ДатаДокумента, "ДЛФ=D") выведет длинный формат даты вида «15 марта 2026 г.», а Формат(ДатаДокумента, "ДФ=dd.MM.yyyy") — «15.03.2026».
Полезные параметры форматной строки: ДФ="dd.MM.yyyy HH:mm:ss" — дата со временем, ДФ="MMMM" — название месяца, ДФ="dddd" — день недели. Пустая дата при форматировании по умолчанию превращается в «01.01.0001», чтобы этого избежать, добавьте параметр ДП (дата пустая): Формат(Дата, "ДЛФ=D; ДП='не указана'").
Формат(ДатаДокумента, "ДЛФ=D"); // 15 марта 2026 г.
Формат(ДатаДокумента, "ДФ=dd.MM.yyyy"); // 15.03.2026
Формат(ДатаДокумента, "ДФ='dd.MM.yyyy HH:mm:ss'"); // 15.03.2026 10:30:00
Формат(ПустаяДата, "ДЛФ=D; ДП='—'"); // —При выводе дат в печатные формы и отчёты предпочитайте локализованные форматы (ДЛФ) — они автоматически учитывают языковые настройки пользователя. Жёстко зашитый формат «dd.MM.yyyy» уместен в технических строках: именах файлов, обменах, номерах документов.
Арифметика дат: добавление и разница периодов
Простейший способ сдвинуть дату — прибавить или вычесть число секунд: Дата + 86400 сдвинет её на сутки. Такой способ подходит для коротких интервалов, но для месяцев и лет он ненадёжен, потому что месяцы имеют разную длину.
Для сдвига на месяцы используйте функцию ДобавитьМесяц(Дата, КоличествоМесяцев). Она корректно обрабатывает переход через год и короткие месяцы: ДобавитьМесяц('20260131', 1) вернёт 29.02.2026, а не несуществующую дату.
Разность двух дат в секундах получается вычитанием: Разность = Дата2 - Дата1. Чтобы получить разницу в днях, разделите на 86400. Для календарной разницы в месяцах и годах готовой функции нет — её считают через функции запроса РАЗНОСТЬДАТ или собственные алгоритмы с учётом границ месяцев.
// Сдвиг на 30 дней
ДатаЧерезМесяц = ТекущаяДатаСеанса() + 30 * 86400;
// Корректный сдвиг на 3 месяца
ДатаЧерезКвартал = ДобавитьМесяц(ТекущаяДатаСеанса(), 3);
// Разница в днях
ДнейПросрочено = (ТекущаяДатаСеанса() - ДатаОплаты) / 86400;Даты в запросах
В языке запросов даты задаются литералом ДАТАВРЕМЯ(2026, 3, 15) или ДАТАВРЕМЯ(2026, 3, 15, 10, 30, 0), либо передаются параметром. Параметры предпочтительнее: текст запроса не нужно пересобирать, и исключены ошибки форматирования.
Для работы с периодами в запросе доступны функции НАЧАЛОПЕРИОДА(Дата, ДЕНЬ|МЕСЯЦ|КВАРТАЛ|ГОД) и КОНЕЦПЕРИОДА(...), а также ДОБАВИТЬКДАТЕ(Дата, МЕСЯЦ, 3). Разницу между датами считает РАЗНОСТЬДАТ(Дата1, Дата2, ДЕНЬ). Для отбора по регистрам накопления и сведений используйте виртуальные таблицы с параметрами периода — это эффективнее, чем отбор условием ГДЕ по полной таблице.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.Номенклатура,
| СУММА(Продажи.СуммаОборот) КАК Сумма
|ИЗ
| РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Продажи
|СГРУППИРОВАТЬ ПО
| Продажи.Номенклатура";
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(Период));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(Период));При отборе документов по периоду помните о неоднозначности границы: условие Дата МЕЖДУ &Начало И &Конец с конечной датой 00:00:00 пропустит документы последнего дня. Передавайте КонецДня(Период) либо используйте объект Граница с видом «Включая».
Даты в интерфейсе и отчётах
В пользовательском режиме даты вводятся в поля ввода с маской, формат которой зависит от региональных настроек информационной базы. В динамических списках и отчётах на СКД период обычно задаётся через стандартный параметр «Период» или «СтандартныйПериод» — тип СтандартныйПериод удобен тем, что хранит начало и конец с правильными границами (23:59:59).
В СКД для группировок по времени используйте поля-периоды: День, Неделя, Месяц, Квартал, которые платформа добавляет автоматически для полей типа «Дата». В пользовательских настройках отчёта период лучше задавать через стандартные варианты («Этот месяц», «Прошлый квартал») — они пересчитываются при каждом формировании.
Проверка результата и диагностика проблем
После написания кода или запроса с датами проверьте граничные случаи: пустую дату, переход через месяц и год, високосный февраль, документы, проведённые в 23:59 последнего дня периода. Быстрее всего это сделать в консоли запросов или через «Вычислить выражение» в отладчике.
Признаки типичных проблем: отчёт не видит документы последнего дня (неверная конечная граница), в выгрузке даты сдвинуты на сутки (часовые пояса), строковое сравнение дат даёт неверный порядок сортировки (даты хранятся как строки в формате ДД.ММ.ГГГГ вместо типа «Дата»).
Как проверить результат
Конечная дата содержит 23:59:59 или задана через КонецДня()
Конечная дата с временем 00:00:00 — выпадают документы последнего дня
Реквизит имеет тип Дата, сортировка и сравнение корректны
Дата хранится строкой — сортировка идёт по алфавиту, а не по календарю
Используется ТекущаяДатаСеанса()
Используется клиентская ТекущаяДата() при записи данных
Что важно запомнить
Дата в 1С — отдельный тип данных: создавайте её литералами и функцией Дата(), получайте текущую через ТекущаяДатаСеанса(), сдвигайте через ДобавитьМесяц(), выводите через Формат(), а в запросах передавайте периоды параметрами с правильными границами. Большинство ошибок связано со строковым представлением дат и неверной конечной границей периода.
Частые вопросы
Как проверить, что дата пустая?
Сравните значение с литералом '00010101' или используйте функцию ЗначениеЗаполнено(): для пустой даты она вернёт Ложь. В запросах условие выглядит как ГДЕ Дата = ДАТАВРЕМЯ(1,1,1).
Как преобразовать строку «15.03.2026» в дату?
Надёжнее всего разобрать строку вручную: извлечь день, месяц и год функциями работы со строками и передать их в Дата(Год, Месяц, День). Прямое преобразование Дата("15.03.2026") зависит от региональных настроек и может дать неверный результат или ошибку.
Почему отчёт не видит документы за последний день периода?
Конечная дата периода задана с временем 00:00:00, то есть на начало суток. Документы, проведённые днём, в интервал не попадают. Передайте в параметр КонецДня(Период) или используйте СтандартныйПериод, который хранит корректную границу 23:59:59.
Как получить разницу между датами в месяцах?
В запросе используйте РАЗНОСТЬДАТ(Дата1, Дата2, МЕСЯЦ). В коде на встроенном языке готовой функции нет: считайте разницу лет и месяцев через Год() и Месяц() с поправкой на день месяца, либо выполните небольшой запрос с РАЗНОСТЬДАТ.
Чем ТекущаяДатаСеанса() отличается от ТекущаяДата()?
ТекущаяДатаСеанса() возвращает время сервера с учётом часового пояса сеанса и одинакова для всех пользователей базы. ТекущаяДата() на клиенте берёт время компьютера пользователя, которое может быть неточным или в другом часовом поясе. Для записи документов и регистров используйте дату сеанса.
Как вывести дату в печатной форме без времени?
Примените Формат(ДатаДокумента, "ДЛФ=Д") для длинного локализованного формата («15 марта 2026 г.») или Формат(ДатаДокумента, "ДФ=dd.MM.yyyy") для короткого числового. Время в эти форматы не входит.