Работа с датами во встроенном языке 1С:Предприятия 8.3

· 9 мин

Содержание

Программно задать дату в 1С можно тремя способами: литералом '20261007', конструктором Дата(2026, 10, 7) или функцией Дата("20261007120000") из строки цифр. Текущий момент берут через ТекущаяДатаСеанса(), а сдвигают дату прибавлением секунд или функцией ДобавитьМесяц().

Тип «Дата» в 1С всегда хранит и дату, и время с точностью до секунды. Почти все ошибки разработчиков растут отсюда: дата «без времени» на самом деле содержит 00:00:00, и сравнение с документом, проведённым в 14:35, внезапно не срабатывает. Все примеры подходят для платформы 8.3 и не зависят от конфигурации: это встроенный язык, а не функции БП или ЗУП.

Как записать дату в коде: литерал, конструктор и строка

Литерал в одинарных кавычках

Самый короткий вариант — литерал. Цифры идут в порядке «год, месяц, день, часы, минуты, секунды»:

ДатаНачала = '20261001';          // 01.10.2026 00:00:00
ДатаСобытия = '20261007143000';   // 07.10.2026 14:30:00
ПустаяДата = '00010101';          // пустое значение даты

Литерал удобен для констант в тестах и обработках. В типовом коде его избегают: дату, зашитую в модуль, через год никто не вспомнит.

Конструктор Дата() с числами

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

Год = 2026;
Квартал = 4;
НачалоКв = Дата(Год, (Квартал - 1) * 3 + 1, 1);   // 01.10.2026
Момент = Дата(2026, 10, 7, 9, 0, 0);               // 07.10.2026 09:00:00

Часы, минуты и секунды можно не указывать, тогда они равны нулю. Если передать несуществующую дату, например 31 апреля, платформа выдаст ошибку выполнения, а не «перенесёт» день.

Функция Дата() со строкой

Вариант Дата("20261007") принимает строку цифр в формате ГГГГММДД или ГГГГММДДччммсс. Строку вида «07.10.2026» он не понимает — получите Преобразование значения к типу Дата не может быть выполнено. Разбор таких строк — в разделе про преобразование ниже.

СпособПримерКогда применять
Литерал'20261007'константы, тесты, отладка
Дата(числа)Дата(Год, Месяц, 1)дата собирается из вычисленных частей
Дата(строка)Дата("20261007")строка уже в формате ГГГГММДД
XMLЗначениеXMLЗначение(Тип("Дата"), "2026-10-07T14:30:00")ISO-формат из XML, JSON, веб-сервисов

Диапазон типа — от 1 января 1 года до 31 декабря 9999 года. Значение '00010101' платформа считает пустым: ЗначениеЗаполнено(Дата) для него вернёт Ложь.

Текущее время: ТекущаяДата, ТекущаяДатаСеанса и универсальное время

Функций «который час» в 1С несколько, и путают их постоянно.

  • 🕐 ТекущаяДата() — время компьютера, на котором выполняется код. На клиенте это часы рабочего места пользователя, на сервере — часы сервера 1С.
  • 🌍 ТекущаяДатаСеанса() — время с учётом часового пояса сеанса. Именно её используют для дат документов и записей регистров в типовых конфигурациях.
  • 🧭 ТекущаяУниверсальнаяДата() — время UTC без смещения. Подходит для журналов, обмена и отметок, которые сравнивают между разными городами.
  • ⏱ ТекущаяУниверсальнаяДатаВМиллисекундах() — число миллисекунд, а не дата. Нужна для замера длительности операций.

Не берите ТекущаяДата() на клиенте для записи в базу. У пользователя часы могут отставать на 10 минут или стоять в другом поясе, и документ получит «чужое» время.

Замер времени выполнения выглядит так:

Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
ВыполнитьОбработку();
Длительность = ТекущаяУниверсальнаяДатаВМиллисекундах() - Старт;
Сообщить("Выполнено за " + Формат(Длительность, "ЧГ=0") + " мс");

Часовые пояса

Пояс сеанса возвращает ЧасовойПоясСеанса(), пояс по умолчанию для информационной базы — ЧасовойПояс(). Для перевода UTC в местное время и обратно служат МестноеВремя(УнивДата, Пояс) и УниверсальноеВремя(МестнДата, Пояс).

УнивДата = ТекущаяУниверсальнаяДата();
ВремяНовосибирск = МестноеВремя(УнивДата, "Asia/Novosibirsk");

Пояс сеанса меняет процедура УстановитьЧасовойПоясСеанса(). Это актуально для распределённых компаний: филиал в Хабаровске проводит документы по своему времени, а база стоит в Москве.

Год, месяц, день и границы периода

Извлечь части даты

Для разбора даты есть отдельные функции, каждая возвращает число:

Д = '20261007143000';
Год(Д);         // 2026
Месяц(Д);       // 10
День(Д);        // 7
Час(Д);         // 14
Минута(Д);      // 30
Секунда(Д);     // 0
ДеньНедели(Д);  // 3 — среда (понедельник = 1, воскресенье = 7)
ДеньГода(Д);    // 280
НеделяГода(Д);

Пример: 7 октября 2026 года — 280-й день. Январь–сентябрь дают 273 дня (31+28+31+30+31+30+31+31+30), плюс 7.

Начало и конец периода

Группа функций обрезает дату до границы периода. Это главный инструмент для фильтров и отчётов.

ФункцияРезультат для 07.10.2026 14:30:00
НачалоДня(Д)07.10.2026 00:00:00
КонецДня(Д)07.10.2026 23:59:59
НачалоНедели(Д)05.10.2026 00:00:00 (понедельник)
НачалоМесяца(Д)01.10.2026 00:00:00
КонецМесяца(Д)31.10.2026 23:59:59
НачалоКвартала(Д)01.10.2026 00:00:00
КонецГода(Д)31.12.2026 23:59:59

Есть также НачалоЧаса, КонецЧаса, НачалоМинуты, КонецМинуты, КонецНедели, КонецКвартала, НачалоГода.

💡 Число дней в месяце получается одной строкой: День(КонецМесяца(Д)). Для февраля 2028 года вернётся 29.

Время отдельно от даты тоже бывает нужно. Реквизит с квалификатором «Время» хранит дату 01.01.0001 и время. Собрать полную дату из двух полей можно так:

Полная = НачалоДня(ДатаДокумента) + (ВремяНачала - '00010101');

Сдвиг даты, сравнение и интервалы

Прибавить дни, часы, месяцы

Арифметика с датой идёт в секундах. Д + 1 — это плюс одна секунда, а не день.

Завтра = Д + 86400;            // плюс сутки (24 × 60 × 60)
ЧерезДвеНедели = Д + 14 * 86400;
ЧасНазад = Д - 3600;

Месяцы и годы секундами не считают: месяцы разной длины. Для этого есть ДобавитьМесяц(Дата, Количество), количество может быть отрицательным.

ДобавитьМесяц('20261007', 1);    // 07.11.2026
ДобавитьМесяц('20261007', -12);  // 07.10.2025
ДобавитьМесяц('20260131', 1);    // 28.02.2026

Последний пример показывает поведение на конце месяца: если в целевом месяце нет такого дня, функция берёт последний день месяца. Для графиков платежей это удобно, но учитывайте, что обратный сдвиг от 28 февраля даст 28 января, а не 31-е.

Сравнить даты

Даты сравнивают обычными операторами =, <>, <, >, <=, >=. Разность двух дат — число секунд:

ДнейМежду = (НачалоДня(ДатаКонца) - НачалоДня(ДатаНачала)) / 86400;

НачалоДня здесь обязателен. Без него 07.10 23:00 минус 07.10 01:00 даст 0,92 дня, и округление начнёт врать.

Период как одно значение

Пару «начало — конец» удобно держать в объекте СтандартныйПериод. Его используют поля выбора периода в формах и отчётах:

Период = Новый СтандартныйПериод;
Период.Вариант = ВариантСтандартногоПериода.ЭтотМесяц;
Запрос.УстановитьПараметр("Начало", Период.ДатаНачала);
Запрос.УстановитьПараметр("Конец", Период.ДатаОкончания);

Для произвольного интервала задайте ДатаНачала и ДатаОкончания напрямую. Свойства пересчитываются от текущей даты, поэтому вариант «Этот месяц» в отчёте, сохранённом в октябре, в ноябре покажет уже ноябрь.

Мини-кейс: полных лет на дату

Типовая задача — возраст сотрудника или стаж в годах:

Функция ПолныхЛет(ДатаРождения, НаДату)
    Лет = Год(НаДату) - Год(ДатаРождения);
    Если ДобавитьМесяц(ДатаРождения, Лет * 12) > НаДату Тогда
        Лет = Лет - 1;
    КонецЕсли;
    Возврат Лет;
КонецФункции

Проверка: родился 15.11.1990, на 07.10.2026 разница годов — 36, но 15.11.2026 ещё не наступило, значит 35 полных лет.

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

Даты в запросах и параметрах

В языке запросов свой набор функций, и он не совпадает со встроенным языком один в один.

ЗадачаВстроенный языкЯзык запросов
Константа'20261007'ДАТАВРЕМЯ(2026, 10, 7)
Начало периодаНачалоМесяца(Д)НАЧАЛОПЕРИОДА(Д, МЕСЯЦ)
Конец периодаКонецМесяца(Д)КОНЕЦПЕРИОДА(Д, МЕСЯЦ)
СдвигДобавитьМесяц(Д, 1)ДОБАВИТЬКДАТЕ(Д, МЕСЯЦ, 1)
Разница(Д2 - Д1) / 86400РАЗНОСТЬДАТ(Д1, Д2, ДЕНЬ)
ЧастиГод(Д)ГОД(Д), МЕСЯЦ(Д), ДЕНЬНЕДЕЛИ(Д)

Даты в запрос лучше передавать параметрами, а не склеивать в текст:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Реализация.Ссылка
|ИЗ
|    Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
|    Реализация.Дата МЕЖДУ &Начало И &Конец";
Запрос.УстановитьПараметр("Начало", НачалоДня(ДатаС));
Запрос.УстановитьПараметр("Конец", КонецДня(ДатаПо));

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

Дата документа программно

При создании документа из кода дату задают явно, до записи:

ДокОбъект = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
ДокОбъект.Дата = ТекущаяДатаСеанса();
// ...заполнение реквизитов...
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);

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

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

Формат() и форматные строки

Для вывода пользователю — функция Формат():

Формат(Д, "ДФ=dd.MM.yyyy");            // 07.10.2026
Формат(Д, "ДФ='dd.MM.yyyy HH:mm'");    // 07.10.2026 14:30
Формат(Д, "ДЛФ=DD");                   // 7 октября 2026 г.
Формат(Д, "ДЛФ=DT");                   // 07.10.2026 14:30:00
Формат(ПустаяДата, "ДП='не указана'"); // не указана

Основные символы ДФ: dd — день, MM — месяц числом, MMMM — название месяца, yyyy — год, HH — часы в 24-часовом формате, mm — минуты, ss — секунды. Регистр важен: MM — месяц, mm — минуты. Перепутать их — частая причина дат вида «07.30.2026».

Для обмена с внешними системами форматирование не используют. XMLСтрока(Д) даёт 2026-10-07T14:30:00, и этот вид не зависит от региональных настроек.

Разобрать строку в дату

Строку «07.10.2026» из Excel или CSV разбирают вручную:

Функция ДатаИзСтроки(Стр)
    Части = СтрРазделить(СокрЛП(Стр), ".");
    Если Части.Количество() <> 3 Тогда
        Возврат '00010101';
    КонецЕсли;
    Попытка
        Возврат Дата(Число(Части[2]), Число(Части[1]), Число(Части[0]));
    Исключение
        Возврат '00010101';
    КонецПопытки;
КонецФункции

Попытка нужна: в файле может попасться «31.02.2026» или пустая ячейка. Функция вернёт пустую дату, а вызывающий код проверит её через ЗначениеЗаполнено.

Для ISO-строк из JSON удобнее ПрочитатьДатуJSON(Стр, ФорматДатыJSON.ISO), для XML — XMLЗначение(Тип("Дата"), Стр).

Приведение к типу и квалификаторы

Чтобы обрезать время по правилам типа, используют описание типов с квалификатором:

ТолькоДата = Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.Дата));
Д2 = ТолькоДата.ПривестиЗначение('20261007143000');  // 07.10.2026 00:00:00

Для реквизитов то же задаётся в свойствах: состав даты «Дата», «Время» или «Дата и время».

Ошибки при работе с датами в 1С

Диагностика: выберите симптом

Ещё одна неочевидная ловушка — пустая дата в условиях. Д < ТекущаяДатаСеанса() для '00010101' вернёт Истина, и незаполненный срок попадёт в «просроченные». Проверяйте ЗначениеЗаполнено(Д) до сравнения.

Частые вопросы

Чем ТекущаяДата() отличается от ТекущаяДатаСеанса()?
Первая возвращает часы компьютера, где выполняется код. Вторая учитывает часовой пояс сеанса и одинакова на клиенте и сервере, поэтому её используют для записи данных.
Как получить последний день предыдущего месяца?
КонецМесяца(ДобавитьМесяц(Д, -1)) или НачалоМесяца(Д) - 1. Второй вариант вернёт 23:59:59 последнего дня прошлого месяца.
Как проверить, что дата не заполнена?
ЗначениеЗаполнено(Д) или сравнение с '00010101'. Оба способа надёжны, первый читается проще.
Можно ли хранить в реквизите только время?
Да, задайте состав даты «Время». Платформа будет хранить дату 01.01.0001 и время, а в форме покажет только часы и минуты.
Как узнать, високосный ли год?
День(КонецМесяца(Дата(Год, 2, 1))) = 29. Выражение работает для любого года в диапазоне типа.