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

Эта статья поможет разобраться, как корректно складывать даты и время в с учетом всех особенностей платформы. Мы рассмотрим базовые функции, типовые ошибки и продвинутые сценарии — от простого сложения дней до работы с временными зонами. Особое внимание уделим практическим примерам кода, которые можно сразу использовать в своих конфигурациях.

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

📊 С какой задачей по датам в 1С вы сталкиваетесь чаще?
Сложение/вычитание дней
Работа с рабочими/выходными
Конвертация форматов
Сравнение дат
Другое

1. Базовые функции для работы с датами в 1С

Платформа 1С:Предприятие предоставляет встроенный тип данных Дата, который автоматически обрабатывает календарные правила. Основные функции для манипуляции датами:

  • 📅 ДатаВремя() — создает значение типа Дата с указанием года, месяца, дня, часов, минут, секунд. Пример: ДатаВремя(2026, 5, 15, 14, 30, 0).
  • ДобавитьМесяц(), ДобавитьДень(), ДобавитьЧас() — увеличивают дату на заданный интервал. Важно: эти функции корректно обрабатывают переходы между месяцами.
  • 🔄 НачалоДня(), КонецДня() — возвращают дату с временем 00:00:00 или 23:59:59 соответственно.
  • ⏱️ ТекущаяДата() — возвращает текущие дату и время сервера .

Простейшее сложение дней выглядит так:

ДатаОтгрузки = ДатаВремя(2026, 5, 20);

ДатаОтгрузки = ДобавитьДень(ДатаОтгрузки, 5); // Прибавляем 5 дней

Обратите внимание: функция ДобавитьДень() автоматически учитывает количество дней в месяце. Например, если к 31.01.2026 прибавить 1 день, результат будет 01.02.2026, а не 32.01.2026.

💡

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

2. Сложение времени: часы, минуты, секунды

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

  • ДобавитьЧас() — прибавляет указанное количество часов. Пример: ДобавитьЧас(ВремяНачала, 2).
  • ⏲️ ДобавитьМинуту()/ДобавитьСекунду() — аналогично для минут и секунд.
  • 🔢 Час(), Минута(), Секунда() — извлекают соответствующие компоненты из значения типа Дата.

Пример сложения времени с учетом перехода через полночь:

ВремяОкончания = ДатаВремя(2026, 5, 15, 22, 0, 0); // 22:00

ВремяОкончания = ДобавитьЧас(ВремяОкончания, 3); // Результат: 01:00 следующего дня

Важный нюанс: при сложении времени автоматически корректирует дату, если время выходит за пределы суток. Это избавляет от ручной обработки случаев вроде "23:00 + 2 часа = 01:00 следующего дня".

⚠️ Внимание: При работе с временными зонами функции сложения времени не учитывают переход на летнее/зимнее время. Для таких случаев требуется дополнительная логика или использование внешних библиотек.

3. Продвинутые сценарии: рабочие дни, праздники, календари

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

1. Использование объекта "Календарь":

Календарь = Календари.ПроизводственныйКалендарь();

ДатаДоставки = Календарь.ДобавитьРабочиеДни(ДатаОтгрузки, 3); // Прибавляем 3 рабочих дня

2. Ручная проверка (если календарь не настроен):

Функция ДобавитьРабочиеДни(ДатаНачала, КоличествоДней)

ТекущаяДата = ДатаНачала;

ОсталосьДней = КоличествоДней;

Пока ОсталосьДней > 0 Цикл

ТекущаяДата = ДобавитьДень(ТекущаяДата, 1);

Если НЕ ТекущаяДата.ДеньНедели() = 6 И НЕ ТекущаяДата.ДеньНедели() = 7 Тогда

ОсталосьДней = ОсталосьДней - 1;

КонецЕсли;

КонецЦикла;

Возврат ТекущаяДата;

КонецФункции

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

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

Если ваша компания работает в нескольких регионах с разными праздничными днями, создайте справочник "РегиональныеПраздники" с полями "Регион" и "Дата". В функции добавьте проверку:

Если НЕ ПустаяСсылка(РегиональныеПраздники.НайтиПоРеквизиту("Дата", ТекущаяДата)) Тогда

Продолжить; // Пропускаем праздничный день

КонецЕсли;

Метод Преимущества Недостатки
Календарь 1С Автоматический учет выходных и праздников Требует предварительную настройку календаря
Ручная функция Гибкость, возможность кастомизации Требует поддержки кода при изменении правил
Внешняя библиотека Поддержка сложных сценариев (например, мусульманский календарь) Дополнительные зависимости в проекте

4. Ошибки и "подводные камни" при работе с датами

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

  • 🗓️ Неучет временной зоны: Функция ТекущаяДата() возвращает время сервера, которое может отличаться от локального времени пользователя. Для клиент-серверных решений это критично.
  • Переполнение даты: Прибавление большого количества дней (например, 10000) может привести к ошибке переполнения.
  • 🔄 Неявное приведение типов: Сравнение даты с строкой (например, Если Дата = "20.05.2026" Тогда) работает, но может давать неожиданные результаты.
  • 📊 Форматирование при выводе: Дата в формате ДД.ММ.ГГГГ может быть интерпретирована по-разному в различных локалях (например, в США сначала идет месяц).

Пример ошибочного кода с неявным приведением:

ДатаСтрока = "31.02.2026"; // Несуществующая дата

Дата = ДатаСтрока; // 1С автоматически преобразует в 03.03.2026!

⚠️ Внимание: При обмене данными с внешними системами всегда явным образом указывайте формат даты. Например, для JSON используйте стандарт ISO 8601 (YYYY-MM-DDTHH:MM:SS). В для этого есть функция Формат(Дата, "ДФ=yyyy-MM-dd; ЧФ=ЧЦ=0").

Используются ли явные приведения типов?|Учтена ли временная зона сервера?|Проверены ли граничные значения (например, конец месяца)?|Тестировался ли код на разных конфигурациях локали?|Документированы ли неочевидные моменты?

-->

5. Оптимизация производительности при массовых операциях

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

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

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

3. Используйте серверные процедуры для тяжелых вычислений. Клиентский код в работает медленнее, особенно при большом объеме данных.

Пример оптимизированного кода для массового сдвига дат:

// Серверная функция

Функция СдвинутьДатыМассово(МассивДат, КоличествоДней)

Результат = Новый Массив();

Для Каждого Дата Из МассивДат Цикл

Результат.Добавить(ДобавитьДень(Дата, КоличествоДней));

КонецЦикла;

Возврат Результат;

КонецФункции

При массовой обработке более 10 000 дат рассмотрите возможность использования механизма распределенных задач (BackgroundJobs в 1С:Предприятие 8.3.20+), чтобы не блокировать интерфейс пользователя.

6. Работа с временными зонами и летним временем

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

1. Хранение времени в UTC с последующим преобразованием:

// Преобразование локального времени в UTC

UTCВремя = ДатаВремя(2026, 5, 15, 14, 0, 0).ВУТС();

// Обратно в локальное время

ЛокальноеВремя = UTCВремя.ИзУТС();

2. Ручная корректировка с учетом смещения:

СмещениеМск = 3; // Часовой пояс Москвы (UTC+3)

ЛокальноеВремя = ДобавитьЧас(UTCВремя, СмещениеМск);

Для учета перехода на летнее/зимнее время потребуется таблица правил или интеграция с внешним сервисом (например, Time Zone Database). В стандартной поставке таких инструментов нет.

⚠️ Внимание: При работе с историческими данными учитывайте, что правила перехода на летнее/зимнее время менялись. Например, в России с 2014 года отменен переход на зимнее время, но в других странах правила могут отличаться.
💡

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

7. Интеграция с внешними системами: JSON, XML, SQL

При обмене данными с другими системами формат даты становится критически важным. Рассмотрим типовые сценарии:

1. JSON:

Стандарт де-факто — ISO 8601. В для преобразования используйте:

ДатаJSON = Формат(Дата, "ДФ=yyyy-MM-dd; ЧФ=ЧЦ=0; ДЛФ=Т; ЧН=:"); // "2026-05-15T14:30:00"

2. XML:

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

ДатаXML = Формат(Дата, "ДФ=yyyy-MM-dd; ЧФ=ЧЦ=0; ДЛФ=Т; ЧН=; ТЧ=zzz");

// "2026-05-15T14:30:00+03:00"

3. SQL:

Для запросов к базам данных (например, PostgreSQL или MS SQL) используйте параметризованные запросы с явным указанием типа:

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

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

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

При чтении данных из внешних источников всегда валидируйте формат даты перед преобразованием в тип . Например:

Попытка

Дата = Дата(СтрокаДатаИзJSON);

Исключение

Сообщить("Ошибка формата даты: " + ОписаниеОшибки());

КонецПопытки;

Часто задаваемые вопросы

Как прибавить к дате 1 месяц с учетом конца месяца?

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

Дата = ДатаВремя(2026, 1, 31);

НоваяДата = ДобавитьМесяц(Дата, 1); // Результат: 29.02.2026 (а не 31.02!)

Если нужно всегда получать тот же номер дня (даже если его не существует в целевом месяце), используйте ДобавитьДень(ДобавитьМесяц(Дата, 1), День(Дата) - День(НачалоМесяца(ДобавитьМесяц(Дата, 1)))).

Почему при сложении даты и времени получаю неверный результат?

Наиболее вероятные причины:

  • Вы работаете с датой в формате строки, а не типа Дата. Всегда используйте явное преобразование: Дата = Дата(СтрокаДата).
  • Не учтена временная зона сервера. Проверьте настройки кластера .
  • Переполнение значения. Максимальная дата в 31.12.9999 23:59:59.

Для диагностики выведите промежуточные значения с помощью Сообщить().

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

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

ДниРазницы = РазницаДней(Дата2, Дата1);

Для часов, минут или секунд есть аналогичные функции: РазницаЧасов(), РазницаМинут().

Если нужна разница в рабочих днях, используйте метод РазницаРабочихДней() объекта Календарь.

Можно ли в 1С работать с миллисекундами?

Тип Дата в не поддерживает миллисекунды. Если требуется высокая точность (например, для логов или интеграции с внешними системами), храните миллисекунды отдельно в числовом поле и комбинируйте при выводе:

ДатаСМиллисекундами = Формат(Дата, "ДФ=yyyy-MM-dd; ЧФ=ЧЦ=0; ЧМС=мс") + "." + Миллисекунды;
Как учитывать праздничные дни в разных странах?

Для международных проектов:

  1. Создайте справочник "ГлобальныеПраздники" с полями "Страна", "Регион", "Дата", "Повторяющийся".
  2. Реализуйте функцию проверки с учетом страны пользователя (можно брать из справочника "Пользователи").
  3. Для динамического обновления праздников интегрируйтесь с API типа Google Calendar или Nager.Date.

Пример структуры справочника:

Праздник = Справочники.ГлобальныеПраздники.СоздатьЭлемент();

Праздник.Страна = Справочники.Страны.НайтиПоНаименованию("Германия");

Праздник.Дата = ДатаВремя(2026, 12, 25); // Рождество

Праздник.Повторяющийся = Истина;