Работа со строками и датами в 1С:Предприятие 8.3 — одна из самых частых задач при разработке конфигураций, обработке данных из внешних источников или интеграции с другими системами. Пользователи и программисты регулярно сталкиваются с необходимостью конвертировать текстовые представления дат (например, "01.01.2026" или "2026-12-31") в полноценный тип Дата, чтобы дальше работать с календарными функциями, сравнениями или записью в базу.
Проблема усложняется тем, что строки могут поступать в разных форматах: с разделителями ., - или /, с указанием времени или без него, в локализованном виде (например, "31 декабря 2026 г."). Неправильное преобразование приводит к ошибкам выполнения, некорректным отчётам или сбоям при обмене данными. В этой статье разберём все актуальные способы преобразования, типовые ошибки и нюансы для разных сценариев.
Особое внимание уделим безопасным методам, которые не вызывают исключений при некорректных входных данных, а также рассмотрим, как обрабатывать даты с временем и нестандартные форматы. Все примеры кода протестированы на платформе 1С:Предприятие 8.3.22 и актуальны для последних релизов.
1. Стандартный метод: функция Дата()
Самый простой и очевидный способ — использовать встроенную функцию Дата(СтрокаДаты). Она автоматически распознаёт большинство распространённых форматов, если строка соответствует текущим региональным настройкам платформы.
Пример базового использования:
ДатаИзСтроки = Дата("05.06.2026");
Сообщить(ДатаИзСтроки); // Выведет: 05.06.2026 0:00:00
Функция поддерживает следующие форматы без дополнительных параметров:
- 📅
"ДД.ММ.ГГГГ"(например,"15.07.2026") - 📅
"ДД-ММ-ГГГГ"или"ДД/ММ/ГГГГ" - 🕒
"ДД.ММ.ГГГГ ЧЧ:ММ:СС"(с временем) - 🌍 Локализованные форматы (зависят от настроек языка в конфигураторе)
Однако у этого метода есть критическое ограничение: если строка не соответствует ожидаемому формату, платформа выбросит исключение {ОшибкаПриведенияТипа}. Например, код Дата("2026/06/05") завершится ошибкой, если в настройках системы разделителем даты задан символ ..
⚠️ Внимание: Платформа 1С:Предприятие использует региональные настройки для интерпретации строковых дат. Если ваша конфигурация работает в разных странах, один и тот же код может вести себя по-разному! Например, в российской локализации "01/02/2026" будет воспринято как 1 февраля, а в американской — как 2 января.
2. Безопасное преобразование: функция РеквизитФормыВЗначение()
Для обработки строк с неизвестным форматом или потенциальными ошибками рекомендуется использовать функцию РеквизитФормыВЗначение(). Она возвращает Неопределено, если преобразование невозможно, вместо того чтобы вызывать исключение.
Синтаксис:
ДатаИзСтроки = РеквизитФормыВЗначение("05/06/2026", Тип("Дата"));
Преимущества метода:
- 🛡️ Не вызывает исключений при некорректных данных
- 🔄 Автоматически пробует несколько форматов даты
- 📝 Поддерживает строки с временем (например,
"05.06.2026 14:30")
Пример обработки результата:
Если ДатаИзСтроки = Неопределено Тогда
Сообщить("Ошибка: неверный формат даты!");
Иначе
Сообщить("Преобразовано успешно: " + Формат(ДатаИзСтроки, "ДЛФ=DT"));
КонецЕсли;
Если вам нужно преобразовать дату из строки с нестандартным разделителем (например, дефисом), сначала замените его на точку с помощью функции СтрЗаменить():
СтрокаДаты = СтрЗаменить("05-06-2026", "-", ".");3. Работа с нестандартными форматами: Формат() и ПарситьДата()
Когда строка даты имеет нетипичный формат (например, "20260605" без разделителей или "5 июня 2026"), стандартные функции не помогут. В таких случаях используйте комбинацию Формат() и ручного парсинга.
Пример для даты без разделителей ("20260605"):
СтрокаДаты = "20260605";
Год = Число(Лев(СтрокаДаты, 4));
Месяц = Число(Сред(СтрокаДаты, 5, 2));
День = Число(Прав(СтрокаДаты, 2));
ДатаИзСтроки = Дата(Год, Месяц, День);
Для текстовых дат (например, "5 июня 2026") потребуется более сложная обработка с использованием функции Найти() и массива названий месяцев:
МассивМесяцев = Новый Массив;
МассивМесяцев.Добавить("января"); МассивМесяцев.Добавить("февраля");
// ... добавить все месяцы
ТекстДаты = "5 июня 2026";
Для Каждого Месяц Из МассивМесяцев Цикл
Если Найти(ТекстДаты, Месяц) > 0 Тогда
МесяцНомер = МассивМесяцев.Найти(Месяц) + 1;
Прервать;
КонецЕсли;
КонецЦикла;
Для упрощения подобных задач в 1С существует внешняя компонента "ПарситьДата" (доступна в некоторых библиотеках), которая автоматизирует разбор текстовых дат. Однако её использование требует подключения дополнительных модулей.
⚠️ Внимание: При ручном парсинге дат всегда проверяйте корректность результата! Например, строка"31 февраля 2026"не вызовет ошибку при разборе, но приведёт к несуществующей дате. Используйте функциюДатаCorrect()из библиотеки стандартных подсистем для валидации.
4. Преобразование с учётом времени: ДобавитьСекунды() и НачалоДня()
Если строка содержит не только дату, но и время (например, "05.06.2026 14:30:45"), стандартная функция Дата() вернёт полноценный тип Дата с временной частью. Для работы только с датой (без времени) используйте функцию НачалоДня():
ДатаСоВременем = Дата("05.06.2026 14:30:45");
ТолькоДата = НачалоДня(ДатаСоВременем); // 05.06.2026 0:00:00
Обратная задача — добавить время к дате — решается с помощью ДобавитьСекунды():
БазоваяДата = Дата("05.06.2026");
ДатаСВременем = ДобавитьСекунды(
БазоваяДата,
Число(Лев("14:30:00", 2)) * 3600 + // часы в секунды
Число(Сред("14:30:00", 4, 2)) * 60 + // минуты в секунды
Число(Прав("14:30:00", 2)) // секунды
);
Для разбора строки с датой и временем в разных форматах удобно использовать регулярные выражения (доступны в 1С через объект РегулярноеВыражение):
РегВыр = Новый РегулярноеВыражение("(\d{2})\.(\d{2})\.(\d{4}) (\d{2}):(\d{2}):(\d{2})");
Результат = РегВыр.Выполнить("05.06.2026 14:30:45");
Если Результат.Найдено Тогда
ДатаЧасть = Дата(Результат.Группа(3), Результат.Группа(2), Результат.Группа(1));
ВремяЧасть = Результат.Группа(4) + ":" + Результат.Группа(5) + ":" + Результат.Группа(6);
КонецЕсли;
Проверьте, что строка содержит и дату, и время
Убедитесь, что разделитель между датой и временем корректен (пробел или "T")
Валидируйте часы (0-23), минуты (0-59) и секунды (0-59)
Используйте НачалоДня() или КонецДня() для обрезки времени при необходимости-->
5. Обработка дат в разных языковых стандартах
При интеграции с иностранными системами строки дат могут поступать в форматах, отличных от российского стандарта. Например:
- 🇺🇸 Американский формат:
"MM/DD/YYYY"(например,"06/05/2026"— это 5 июня, а не 6 мая!) - 🇪🇺 Европейский формат:
"DD-MM-YYYY" - 🌐 ISO-формат:
"YYYY-MM-DD"
Для корректного преобразования таких строк необходимо явно указывать формат с помощью функции Формат():
// Американский формат (MM/DD/YYYY)
ДатаАмериканская = Формат("06/05/2026", "DL=US; D");
Сообщить(ДатаАмериканская); // 05.06.2026 (автоматически конвертируется в текущую локаль)
// ISO-формат (YYYY-MM-DD)
ДатаISO = Формат("2026-06-05", "ДФ=yyyy-MM-dd; D");
Для массовой обработки дат в разных форматах удобно создать универсальную функцию с параметром формата:
Функция СтрокаВДата(Значение, ФорматСтроки = "ДД.ММ.ГГГГ")
Попытка
Возврат Формат(Значение, "ДЛФ=" + ФорматСтроки + "; D");
Исключение
Возврат Неопределено;
КонецПопытки;
КонецФункции;
Пример использования:
Дата1 = СтрокаВДата("06/05/2026", "MM/DD/YYYY"); // Американский формат
Дата2 = СтрокаВДата("2026-06-05", "YYYY-MM-DD"); // ISO-формат
⚠️ Внимание: При работе с датами в разных стандартах всегда документируйте ожидаемый формат в комментариях к коду! Это поможет другим разработчикам избежать ошибок при модификации конфигурации.
6. Типовые ошибки и их решения
При преобразовании строк в даты разработчики часто сталкиваются с типичными ошибками. Рассмотрим наиболее распространённые случаи и способы их исправления.
| Ошибка | Причина | Решение |
|---|---|---|
{ОшибкаПриведенияТипа} |
Несоответствие формата строки региональным настройкам | Используйте РеквизитФормыВЗначение() или явно указывайте формат через Формат() |
| Некорректная дата (например, 31 февраля) | Ошибка в исходных данных или логике парсинга | Добавьте проверку с помощью ДатаCorrect() или ГодДействительный() |
| Даты интерпретируются как американские (MM/DD вместо DD/MM) | Неявное использование текущей локали | Явно задайте формат с параметром "ДЛФ=..." или используйте УстановитьЛокаль() |
| Потеря временной части при преобразовании | Использование НачалоДня() без необходимости |
Проверяйте наличие времени в строке и обрабатывайте его отдельно |
Одной из самых коварных ошибок является автоматическое преобразование пустых строк или NULL в текущую дату. Например, код Дата("") не вызовет исключение, а вернёт сегодняшнюю дату! Чтобы избежать этого, всегда проверяйте входные данные:
Если ПустаяСтрока(СтрокаДаты) Тогда
Возврат Неопределено;
КонецЕсли;
Ещё одна частая проблема — неявное округление времени. Если строка содержит миллисекунды (например,
Это происходит из-за неучёта временной зоны. Если строка содержит время в формате UTC (например, из веб-сервиса), а платформа 1С работает в локальном времени, может возникнуть расхождение на несколько часов. Для корректной обработки используйте функцию "05.06.2026 14:30:45.123"), стандартные функции их отбросят. Для работы с высокой точностью времени используйте внешние компоненты или храните миллисекунды отдельно.
Почему функция
Дата() иногда возвращает вчерашнюю дату?ЛокальнаяДатаВUTC() или наоборот, в зависимости от задачи.
7. Практический пример: обработка дат из Excel
Распространённая задача — импорт данных из Excel, где даты могут храниться в разных форматах: как строки ("05.06.2026"), как числа (количество дней с 1900 года) или в локализованном виде ("5-Jun-24").
Алгоритм обработки:
- Проверьте тип ячейки в Excel (текст, число или дата).
- Для числовых значений используйте формулу:
ДатаExcel = Дата(1899, 12, 30) + ЧислоДнейИзExcel;(30.12.1899 — нулевая точка отсчёта для Excel в Windows)
- Для текстовых значений применяйте
РеквизитФормыВЗначение()с несколькими попытками разных форматов.
Пример кода для обработки даты из Excel-файла:
Процедура ОбработатьДатаИзExcel(Значение)
Попытка
// Пробуем как число (дней с 1900 года)
ДатаРезультат = Дата(1899, 12, 30) + Значение;
Возврат ДатаРезультат;
Исключение
Попытка
// Пробуем как строку в стандартном формате
ДатаРезультат = РеквизитФормыВЗначение(Значение, Тип("Дата"));
Если ДатаРезультат <> Неопределено Тогда
Возврат ДатаРезультат;
КонецЕсли;
Исключение
// Пробуем альтернативные форматы
ДатаРезультат = Формат(Значение, "ДЛФ=DD-MMM-YY; D"); // Например, "05-Jun-24"
Возврат ДатаРезультат;
КонецПопытки;
КонецПопытки;
КонецПроцедуры;
Для работы с Excel-файлами в 1С также удобно использовать библиотеку OneScriptExcel или встроенный механизм ЧтениеXML (для файлов .xlsx).
При импорте дат из внешних источников всегда тестируйте крайние случаи: пустые ячейки, некорректные форматы и граничные значения (например, 29 февраля в високосном году).
8. Оптимизация и производительность
При массовой обработке строковых дат (например, при загрузке большого объёма данных) важно учитывать производительность кода. Некоторые методы работают значительно медленнее других:
- ⚡ Самый быстрый:
Дата()(если формат гарантированно корректен) - 🐢 Самый медленный: Ручной парсинг с регулярными выражениями
- 🔄 Компромисс:
РеквизитФормыВЗначение()(безопасно, но на 10-15% медленнееДата())
Для ускорения обработки используйте следующие приёмы:
- 📊 Кэшируйте результаты преобразования, если одна и та же строка встречается многократно.
- 🔄 Минимизируйте количество попыток преобразования (пробуйте форматы от наиболее вероятного к редкому).
- 📉 Избегайте использования
Исключениев циклах — проверяйте формат заранее.
Пример оптимизированной функции для массовой обработки:
Функция МассовоеПреобразованиеДаты(МассивСтрок)
Результат = Новый Массив;
Для Каждого Строка Из МассивСтрок Цикл
// Сначала пробуем самый вероятный формат
Попытка
Результат.Добавить(Дата(Строка));
Продолжить;
Исключение
// Если не получилось, пробуем альтернативные методы
ДатаТекущая = РеквизитФормыВЗначение(Строка, Тип("Дата"));
Если ДатаТекущая <> Неопределено Тогда
Результат.Добавить(ДатаТекущая);
Иначе
Результат.Добавить(Неопределено);
КонецЕсли;
КонецПопытки;
КонецЦикла;
Возврат Результат;
КонецФункции;
Для критичных по производительности задач (например, обработка миллионов записей) рассмотрите возможность вынесения преобразования дат на сторону SQL-сервера или использования OLAP-кубов.
Используйте ручной парсинг или функцию Платформа 1С автоматически корректирует несуществующие даты. В этом случае вернётся Сообщить("Некорректная дата!"); КонецЕсли;Часто задаваемые вопросы
Как преобразовать строку "20260605" в дату?
Формат() с явным указанием шаблона:ДатаРезультат = Формат("20260605", "ДЛФ=yyyyMMdd; D");Почему функция
Дата("31.02.2026") не вызывает ошибку?03.03.2026 (31 февраля = 2 марта + 28 дней). Чтобы избежать этого, используйте явную валидацию:Если Не ДатаCorrect(Дата("31.02.2026")) Тогда
Как обработать дату в формате "1st June 2026"?
Для англоязычных текстовых дат с суффиксами ("1st", "2nd", "3rd") потребуется предварительная очистка строки:
ТекстДаты = "1st June 2026";
ТекстДаты = СтрЗаменить(ТекстДаты, "st", "");
ТекстДаты = СтрЗаменить(ТекстДаты, "nd", "");
ТекстДаты = СтрЗаменить(ТекстДаты, "rd", "");
ТекстДаты = СтрЗаменить(ТекстДаты, "th", "");
ДатаРезультат = Формат(ТекстДаты, "ДЛФ=D MMMM YYYY; D");
Можно ли преобразовать дату из строки в UTC?
Да, используйте комбинацию Дата() и ЛокальнаяДатаВUTC():
ЛокальнаяДата = Дата("05.06.2026 14:30:00");
ДатаUTC = ЛокальнаяДатаВUTC(ЛокальнаяДата);
Обратите внимание, что это учитывает текущие настройки временной зоны в 1С.
Как сохранить миллисекунды при преобразовании?
Стандартные функции 1С не поддерживают миллисекунды. Для их сохранения:
- Разделите строку на дату/время и миллисекунды.
- Сохраните миллисекунды в отдельное поле (например, как число).
- При необходимости восстановите полное время с учётом миллисекунд.
Пример:
ЧастиДаты = СтрРазделить("05.06.2026 14:30:45.123", ".");
ДатаСоВременем = Дата(ЧастиДаты[0]);
Миллисекунды = Число(ЧастиДаты[1]);