При обмене данными с внешними системами, такими как Excel, текстовые файлы или веб-сервисы, программисты часто сталкиваются с необходимостью преобразовать строковое представление времени (например, "08:23:17") в объект типа Дата платформы 1С. Несмотря на то, что в реквизитах объектов можно установить состав даты «Время», важно понимать, что внутри системы 1С время не существует отдельно — оно всегда является частью типа Дата. Рассмотрим подробно все способы решения этой задачи, разберем их преимущества и возможные подводные камни.
Прежде чем переходить к коду, проанализируем, как 1С хранит данные. Когда вы создаете реквизит с типом Дата и выбираете состав «Время», это влияет только на то, как значение будет отображаться в пользовательском интерфейсе и как оно будет редактироваться. В базе данных всё равно хранится полная дата. Для значений, где важна только временная составляющая, 1С использует «пустую» или «нулевую» дату — 01.01.0001. Таким образом, время "08:23:17" фактически хранится как "01.01.0001 08:23:17".
Это классический и наиболее наглядный метод. Мы разбиваем строку на массив подстрок, используя двоеточие в качестве разделителя, а затем передаем полученные части в конструктор Дата(). Разберем по шагам реализацию этого алгоритма:
ВремяСтр = "08:23:17";
// Разбиваем строку на массив: ["08", "23", "17"]
Части = СтрРазделить(ВремяСтр, ":");
// Проверяем, что в массиве достаточно элементов для создания даты
Если Части.Количество() >= 3 Тогда
// Используем конструктор Дата(Год, Месяц, День, Час, Минута, Секунда)
Время = Дата(1, 1, 1, Части[0], Части[1], Части[2]);
КонецЕсли;
Этот метод хорош тем, что он позволяет легко добавить проверку входящих данных. Если формат строки изменится (например, придет "08:23"), код не упадет с ошибкой, если вы заранее предусмотрите проверку количества элементов в массиве Части.
Платформа 1С умеет преобразовывать строку в дату напрямую, если строка соответствует формату ГГГГММДДЧЧММСС. Этот способ работает быстрее, так как не требует создания промежуточных массивов. Нам нужно просто удалить разделители и добавить в начало символы пустой даты. Рассмотрим этот вариант:
ВремяСтр = "08:23:17";
// Удаляем двоеточия и добавляем префикс пустой даты 0001 год 01 месяц 01 число
ЧистаяСтрока = "00010101" + СтрЗаменить(ВремяСтр, ":", "");
Попытка
Время = Дата(ЧистаяСтрока);
Исключение
Сообщить("Некорректный формат времени!");
КонецПопытки;
Важный момент: использование блока Попытка...Исключение крайне желательно, так как если во входящей строке окажутся нецифровые символы или недопустимые значения (например, 25 часов), конструктор Дата() вызовет критическую ошибку.
Существует системный метод, использующий механизмы XML-сериализации. Платформа поддерживает стандарт ISO 8601, где время отделяется от даты символом "T". Этот метод считается наиболее профессиональным и «чистым» с точки зрения архитектуры системы.
ВремяСтр = "08:23:17";
// Формируем строку вида 0001-01-01T08:23:17
СтрокаISO = "0001-01-01T" + ВремяСтр;
Время = XMLЗначение(Тип("Дата"), СтрокаISO);
Функция XMLЗначение удобна тем, что она жестко стандартизирована и отлично справляется с типизацией данных.
Если вы работаете на современных версиях платформы, использование функции СтрШаблон сделает ваш код более читаемым и легким для поддержки. Мы можем заранее подготовить маску для канонического формата. Проанализируем пример:
ВремяСтр = "08:23:17";
// Выделяем часы, минуты и секунды по позициям
ЧЧ = Лев(ВремяСтр, 2);
ММ = Сред(ВремяСтр, 4, 2);
СС = Прав(ВремяСтр, 2);
// Собираем строку через шаблон
Время = Дата(СтрШаблон("00010101%1%2%3", ЧЧ, ММ, СС));
Выясним причину, по которой часто возникают сложности при загрузке из Excel. Проблема в том, что Excel хранит время не как строку, а как число (долю суток). Например, полдень (12:00:00) в Excel — это число 0.5.
Если вы читаете данные через COM-объект, попробуйте обратиться к свойству Value ячейки. В большинстве случаев 1С автоматически поймет, что это время, и вернет вам готовый объект типа Дата. Если же вы используете свойство Text, вы получите строку, которую придется парсить вышеуказанными методами.
Рекомендация: Если в Excel ячейка имеет формат времени, всегда используйте Ячейка.Value. Это избавит вас от необходимости писать функции парсинга.
Никогда не доверяйте внешним данным. Прежде чем присваивать значение реквизиту, убедитесь, что оно корректно. Рассмотрим пример простой функции валидации:
Функция СтрокаЯвляетсяВременем(Знач ВхСтрока)
// Простейшая проверка регулярным выражением или длиной
Если СтрДлина(ВхСтрока) <> 8 Тогда
Возврат Ложь;
КонецЕсли;
// Можно добавить проверку на наличие двоеточий
Если СтрНайти(ВхСтрока, ":") = 0 Тогда
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции
Мы рассмотрели несколько эффективных способов преобразования строки во время. Выбор конкретного метода зависит от ваших предпочтений и требований к производительности:
СтрРазделить.XMLЗначение.Помните, что независимо от выбранного способа, результатом всегда будет объект типа Дата с календарным значением 01.01.0001, что является абсолютно правильным для платформы 1С при работе с временем.