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

В этой статье разберем все актуальные способы преобразования ДатаВремя → Дата в 1С 8.3 и 8.2, включая встроенные функции, запросы, программный код на встроенном языке и обходные пути для нестандартных ситуаций. Особое внимание уделим типовым ошибкам (например, потере данных при неявном приведении типов) и оптимизации кода для крупных баз данных.

Материал будет полезен как бухгалтерам, которые хотят самостоятельно доработать отчет, так и разработчикам, ищущим наиболее эффективное решение для обработки больших массивов данных.

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

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

Функция НачалоДня(<ДатаВремя>) обнуляет временную часть, возвращая дату с временем 00:00:00. Это удобно, когда нужно сохранить тип ДатаВремя, но "сбросить" время. Например:

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

// Результат: 2026-05-20 00:00:00

Функция Дата(<Год>, <Месяц>, <День>) создает новую дату без времени, но требует явного указания компонентов. Для преобразования существующей даты-времени придется извлекать год, месяц и день:

ДатаБезВремени = Дата(Год(ТекущаяДата()), Месяц(ТекущаяДата()), День(ТекущаяДата()));

// Результат: 2026-05-20

  • Плюсы: Простота, не требует дополнительных модулей.
  • ⚠️ Минусы: НачалоДня() сохраняет тип ДатаВремя, что может вызвать ошибки при сравнении с полем типа Дата.
  • 🔄 Альтернатива: Использовать Формат() для строкового представления (см. раздел 3).
💡

Если вам нужно сравнить дату-время с датой в запросе, используйте конструкцию ДАТАВРЕМЯ(Год, Месяц, День) — это ускорит выполнение на больших базах.

2. Преобразование в запросах 1С

В языке запросов тип ДатаВремя автоматически не преобразуется в Дата. Чтобы получить чистую дату, используйте функцию ДАТАВРЕМЯ() с извлечением компонентов или НАЧАЛОПЕРИОДА():

Пример 1: Извлечение даты из поля Документ.Дата:

ВЫБРАТЬ

ДАТАВРЕМЯ(ГОД(Документ.Дата), МЕСЯЦ(Документ.Дата), ДЕНЬ(Документ.Дата)) КАК ДатаБезВремени

ИЗ

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

Пример 2: Использование НАЧАЛОПЕРИОДА() для обнуления времени:

ВЫБРАТЬ

НАЧАЛОПЕРИОДА(Документ.Дата, "ДЕНЬ") КАК ДатаНачалоДня

ИЗ

Документ.РеализацияТоваров КАК Документ

Метод Синтаксис Тип результата Примечание
ДАТАВРЕМЯ() ДАТАВРЕМЯ(ГОД(), МЕСЯЦ(), ДЕНЬ()) ДатаВремя Время будет 00:00:00, но тип остается ДатаВремя
НАЧАЛОПЕРИОДА() НАЧАЛОПЕРИОДА(Дата, "ДЕНЬ") ДатаВремя Аналог НачалоДня() в языке 1С
Явное приведение ДАТА(ДатаВремя) Дата Работает только в новых версиях платформы (8.3.14+)
📊 Какой способ преобразования даты вы используете чаще?
Встроенные функции (НачалоДня, Дата)
Запросы 1С
Программный код (1С)
Внешние обработки

3. Программное преобразование на встроенном языке

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

Функция ПреобразоватьВДата(ЗначениеДатаВремя)

Возврат Новый Дата(Год(ЗначениеДатаВремя), Месяц(ЗначениеДатаВремя), День(ЗначениеДатаВремя));

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

Если требуется массовая обработка (например, в цикле по таблице значений), оптимизируйте код, избегая повторных вызовов Год()/Месяц()/День():

Для Каждого Строка Из ТаблицаДокументов Цикл

ГодТек = Год(Строка.Дата);

МесяцТек = Месяц(Строка.Дата);

ДеньТек = День(Строка.Дата);

Строка.ДатаБезВремени = Новый Дата(ГодТек, МесяцТек, ДеньТек);

КонецЦикла;

⚠️ Внимание: При неявном приведении типов (например, присваивании ДатаВремя в поле типа Дата) платформа автоматически обрезает время, но это может вызвать ошибку "Тип не соответствует типу параметра" в строго типизированных контекстах (например, при передаче в функцию).
Почему не работает приведение типов в старых версиях 1С?

В версиях платформы ниже 8.3.14 явное приведение Дата(ДатаВремя) не поддерживалось. Вместо этого использовали обходные пути:

  • Создание новой даты через конструктор Новый Дата().
  • Использование Формат(ДатаВремя, "ДФ=dd.MM.yyyy") с последующим разбором строки.
  • Запросы с ДАТАВРЕМЯ(ГОД(), МЕСЯЦ(), ДЕНЬ()).

4. Преобразование через форматирование (строка → дата)

Иногда удобно преобразовать ДатаВремя в строку, а затем обратно в Дата. Это актуально, например, при обмене данными с внешними системами, где даты передаются в текстовом формате.

Пример 1: Форматирование с последующим разбором:

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

ДатаРезультат = Дата(СтрокаДата);

Пример 2: Использование региональных настроек (если формат даты зависит от локали):

ФорматДаты = Формат(ТекущаяДата(), "ДЛФ=D");

ДатаРезультат = Дата(ФорматДаты);

  • 📅 Плюсы: Гибкость — можно адаптировать под любой формат.
  • ⚠️ Минусы: Зависимость от региональных настроек (например, "05.06" может быть интерпретировано как 5 июня или 6 мая).
  • 🔧 Совет: Всегда явно указывайте формат ("ДФ=dd.MM.yyyy"), чтобы избежать неоднозначностей.

5. Типовые ошибки и как их избежать

Ошибка 1: Потеря данных при неявном приведении.

При присваивании ДатаВремя в поле типа Дата время обрезается, но если поле имеет ограничения (например, Неопределено не допускается), это вызовет исключение.

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

Условие Если ДатаСВременем = ДатаБезВремени Тогда может не сработать, даже если даты совпадают, из-за ненулевого времени. Используйте НачалоДня() для обеих сторон сравнения:

Если НачалоДня(ДатаСВременем) = ДатаБезВремени Тогда

// Код

КонецЕсли;

Ошибка 3: Проблемы с часовыми поясами.

Если база работает с учетом временных зон, НачалоДня() может вернуть неожиданный результат (например, 19.05.2026 23:00:00 вместо 20.05.2026 00:00:00). В таких случаях используйте:

ДатаБезВремени = Дата(Год(ДатаСВременем), Месяц(ДатаСВременем), День(ДатаСВременем));
⚠️ Внимание: В версиях 1С:Предприятие ниже 8.3.10 функция Дата() при передаче строки с временной частью ("20.05.2026 15:30:00") может игнорировать время или вызвать ошибку. Всегда очищайте временную часть заранее.

Поле не содержит Неопределено|Учет часовых поясов отключен или скорректирован|Формат даты явно задан (например, "ДФ=dd.MM.yyyy")|Тип результата соответствует целевому полю (Дата vs ДатаВремя)

-->

6. Оптимизация для больших баз данных

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

1. Используйте запросы вместо поэлементной обработки.

Запрос с ДАТАВРЕМЯ(ГОД(), МЕСЯЦ(), ДЕНЬ()) выполнится быстрее, чем цикл по таблице значений с вызовом Новый Дата() для каждой строки.

2. Кэшируйте промежуточные значения.

Если в цикле многократно извлекаете год/месяц/день, сохраняйте их в переменные (см. пример в разделе 3).

3. Отключайте проверку прав при массовых операциях.

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

НачатьТранзакцию();

Попытка

// Ваш код с преобразованием дат

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ВызватьИсключение;

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

Метод Скорость (10 000 записей) Память Рекомендация
Поэлементный Новый Дата() ~1.2 сек Высокая Не использовать для больших массивов
Запрос с ДАТАВРЕМЯ() ~0.3 сек Низкая Оптимально для выборок
Массовое НачалоДня() + приведение ~0.8 сек Средняя Подходит для промежуточных расчетов
💡

Для массовой обработки дат всегда отдавайте предпочтение запросам — они выполняются на сервере 1С и не нагружают клиентское приложение.

7. Альтернативные подходы (для нестандартных задач)

Если стандартные методы не подходят (например, требуется преобразовать дату в негригорианском календаре или с учетом производственного календаря), рассмотрите следующие варианты:

  • 📅 Использование внешних компонент:

    Библиотеки вроде OneScript.DateExtensions или NativeAPI позволяют работать с датами на уровне ОС, где доступны дополнительные функции (например, преобразование в UNIX-time).

  • 🔄 Обмен через JSON/XML:

    При интеграции с веб-сервисами даты часто передаются в формате ISO ("2026-05-20T00:00:00"). Для разбора используйте:

    ДатаРезультат = Дата(Лев(JSONСтрока, 10)); // Извлекаем "2026-05-20"
  • 📊 Производственный календарь:

    Если нужно преобразовать дату в "рабочий день" (исключая выходные), используйте обработку с учетом календаря:

    Если Не Календарь.ЭтоВыходной(ДатаБезВремени) Тогда
    

    // Логика для рабочего дня

    КонецЕсли;

⚠️ Внимание: При работе с внешними компонентами проверьте их совместимость с вашей версией платформы 1С:Предприятие. Некоторые библиотеки требуют дополнительных лицензий или прав администратора для установки.

FAQ: Частые вопросы по преобразованию дат в 1С

Можно ли преобразовать ДатаВремя в Дата без потери времени?

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

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

Платформа 1С сравнивает не только дату, но и время. Например, ДатаВремя(2026, 5, 20, 15, 0, 0) = Дата(2026, 5, 20) вернет Ложь, потому что слева есть ненулевое время. Используйте НачалоДня() для обеих сторон сравнения.

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

Используйте параметр "ДЛФ" в функции Формат():

СтрокаДата = Формат(ТекущаяДата(), "ДЛФ=D"); // Формат по умолчанию для даты

Чтобы явно задать формат, используйте "ДФ=dd.MM.yyyy".

Работает ли Дата(ДатаВремя) в 1С 8.2?

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

Как преобразовать дату в UNIX-time?

В стандартной поставке 1С нет прямой функции для этого. Используйте внешнюю компоненту или рассчитайте вручную:

UNIXTime = Цел((ДатаВремя - Дата(1970, 1, 1)) * 86400);

Обратите внимание на часовые пояса!