Работа с датами во встроенном языке 1С:Предприятия 8.3
Содержание
Программно задать дату в 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'. Оба способа надёжны, первый читается проще.Можно ли хранить в реквизите только время?
Как узнать, високосный ли год?
День(КонецМесяца(Дата(Год, 2, 1))) = 29. Выражение работает для любого года в диапазоне типа.