Работа с датами в 1С:Предприятие — одна из самых частых задач при обработке данных из внешних источников, файлов или пользовательского ввода. Строки с датами могут поступать в самых разных форматах: от стандартного ДД.ММ.ГГГГ до международного YYYY-MM-DD или даже неструктурированного текста вроде "31 декабря 2023 года". Преобразовать такую строку в полноценный тип Дата — задача, с которой сталкивается каждый разработчик 1С.
В этой статье мы разберём все актуальные способы конвертации строк в даты в платформе 1С 8.3 и 8.2, включая встроенные функции, ручной парсинг и обработку нестандартных форматов. Особое внимание уделим типичным ошибкам, которые приводят к исключениям Ошибка при вызове метода контекста (ПреобразоватьВДату) или некорректным результатам. Вы узнаете, как:
- 🔹 Использовать стандартную функцию
Дата()для простых форматов - 🔹 Парсить даты с помощью
Формат()иСтрЗначение()для сложных шаблонов - 🔹 Обрабатывать международный формат ISO 8601 (YYYY-MM-DD)
- 🔹 Работать с неструктурированными строками (например, "5 января 2026 г.")
- 🔹 Избегать ошибок при конвертации пустых строк или некорректных данных
Все примеры кода протестированы на актуальных релизах платформы 1С:Предприятие 8.3.22 и 8.2.20. Если вы работаете с более ранними версиями, проверьте совместимость функций в документации.
1. Стандартный способ: функция Дата() для формата ДД.ММ.ГГГГ
Самый простой и распространённый метод — использование встроенной функции Дата(). Она автоматически распознаёт строки в формате ДД.ММ.ГГГГ (или ДД.ММ.ГГ) и преобразует их в тип Дата. Этот способ подходит для большинства типичных задач, когда источник данных следует российским стандартам оформления дат.
Пример кода:
СтрокаДата = "15.05.2026";
ДатаРезультат = Дата(СтрокаДата);
// Проверка результата
Сообщить(ДатаРезультат); // Выведет: 15.05.2026 0:00:00
Функция Дата() также поддерживает сокращённый формат без века (например, "15.05.24"), автоматически дописывая текущий век (20XX). Однако здесь есть важный нюанс:
⚠️ Внимание: При использовании двухзначного года (ГГ) платформа 1С по умолчанию считает, что даты до29относятся к 20XX году, а даты от30— к 19XX. Например,"01.01.29"станет01.01.2029, а"01.01.30"—01.01.1930. Это правило можно изменить в настройках информационной базы.
Если ваша строка содержит время (например, "15.05.2026 14:30:00"), функция Дата() корректно обработает и его:
СтрокаСДатойИВременем = "15.05.2026 14:30:00";
ДатаСВременем = Дата(СтрокаСДатойИВременем);
Сообщить(ДатаСВременем); // Выведет: 15.05.2026 14:30:00
Чтобы избежать ошибок при парсинге дат с временем, всегда проверяйте наличие разделителя между датой и временем (обычно это пробел или символ "T" в ISO-формате).
2. Формат() и СтрЗначение(): для нестандартных шаблонов
Когда строка с датой имеет нетипичный формат (например, ГГГГ-ММ-ДД, ДД/ММ/ГГГГ или ДДММГГ), стандартная функция Дата() не сработает. В таких случаях используйте комбинацию функций Формат() и СтрЗначение() для ручного парсинга.
Рассмотрим пример с международным форматом ISO 8601 (YYYY-MM-DD):
СтрокаISO = "2026-05-15";
Год = Число(Лев(СтрокаISO, 4));
Месяц = Число(Сред(СтрокаISO, 6, 2));
День = Число(Прав(СтрокаISO, 2));
ДатаРезультат = Дата(Год, Месяц, День);
Сообщить(ДатаРезультат); // Выведет: 15.05.2026 0:00:00
Для формата без разделителей (например, ДДММГГГГ или ГГГГММДД) логика будет аналогичной, но с другими позициями символов:
СтрокаБезРазделителей = "15052026"; // ДДММГГГГ
ДатаРезультат = Дата(
Число(Сред(СтрокаБезРазделителей, 5, 4)), // Год
Число(Сред(СтрокаБезРазделителей, 3, 2)), // Месяц
Число(Лев(СтрокаБезРазделителей, 2)) // День
);
Сообщить(ДатаРезультат); // Выведет: 15.05.2026 0:00:00
Если формат строки заранее неизвестен или может варьироваться, используйте конструкцию с Попытка...Исключение:
Функция СтрокаВДату(СтрокаДата)
Попытка
Возврат Дата(СтрокаДата);
Исключение
// Альтернативные форматы
Если Лев(СтрокаДата, 4) = "2026" Тогда // Проверяем на ISO
Возврат Дата(
Число(Лев(СтрокаДата, 4)),
Число(Сред(СтрокаДата, 6, 2)),
Число(Прав(СтрокаДата, 2))
);
Иначе
Возврат Неопределено; // или выбросить своё исключение
КонецЕсли;
КонецПопытки;
КонецФункции
Убедиться, что строка не пустая|Проверить длину строки (должна соответствовать формату)|Удалить лишние пробелы или символы|Предусмотреть обработку исключений-->
3. Работа с текстовыми датами (например, "5 января 2026 года")
Один из самых сложных случаев — когда дата задана в текстовом виде, например: "пятое мая 2026", "1 января" или "31 декабря 2023 г.". Для таких строк стандартные функции 1С не подходят, и требуется ручной разбор с использованием регулярных выражений или словаря месяцев.
Пример кода для парсинга дат вида "ДД ММММ ГГГГ" (например, "15 мая 2026"):
Функция ТекстВДату(ТекстДата)
Месяцы = Новый Соответствие;
Месяцы.Вставить("января", 1);
Месяцы.Вставить("февраля", 2);
Месяцы.Вставить("марта", 3);
// ... заполнить все месяцы
Месяцы.Вставить("декабря", 12);
// Разбиваем строку на части
Части = СтроковыеФункцииКлиентСервер.РазложитьСтрокуПоРегулярномуВыражению(
ТекстДата,
"(\d{1,2})\s([а-я]+)\s(\d{4})"
);
Если Части.Количество() = 3 Тогда
День = Число(Части[0]);
Месяц = Месяцы[НижнийРегистр(Части[1])];
Год = Число(Части[2]);
Возврат Дата(Год, Месяц, День);
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
// Пример использования
ДатаИзТекста = ТекстВДату("15 мая 2026");
Сообщить(ДатаИзТекста); // Выведет: 15.05.2026 0:00:00
Для более сложных случаев (например, "31 декабря 2023 года" или "5-е января") потребуется:
- Удалить лишние символы (например, "-е", "-го") с помощью
СтрЗаменить(). - Привести месяцы к единому падежу (например, заменить "декабря" на "декабрь").
- Использовать регулярные выражения для извлечения числовых значений.
⚠️ Внимание: При парсинге текстовых дат учитывайте локализацию информационной базы. В украинской или белорусской версии 1С названия месяцев будут на соответствующем языке. Для универсального решения храните соответствия месяцев на всех нужных языках.
Как обработать даты с порядковыми числительными?
Для строк вида "1-е января" или "2-го февраля" используйте следующий приём:
ТекстДата = "5-го марта 2026 года";
// Удаляем суффиксы
ТекстДата = СтрЗаменить(ТекстДата, "-е ", " ");
ТекстДата = СтрЗаменить(ТекстДата, "-го ", " ");
ТекстДата = СтрЗаменить(ТекстДата, " года", "");
// Далее парсим как обычно
4. Обработка дат из внешних источников (Excel, JSON, XML)
При импорте данных из Excel, JSON или XML даты часто приходят в неожиданных форматах. Рассмотрим типичные случаи и способы их обработки.
| Источник | Формат даты | Пример строки | Способ парсинга |
|---|---|---|---|
| Excel (русская версия) | ДД.ММ.ГГГГ | "15.05.2026" |
Дата(Строка) |
| Excel (английская версия) | ММ/ДД/ГГГГ | "05/15/2026" |
Ручной парсинг с Сред() |
| JSON (ISO 8601) | YYYY-MM-DD | "2026-05-15" |
Ручной парсинг или Формат() |
| XML (с временной зоной) | YYYY-MM-DDTHH:MM:SSZ | "2026-05-15T14:30:00Z" |
Использовать Лев() для извлечения даты |
| Текстовые файлы | Произвольный | "Дата: 15 мая 2026 г." |
Регулярные выражения + словарь месяцев |
Для JSON и XML часто удобнее сначала привести строку к формату YYYYMMDD, а затем использовать функцию Дата():
// Пример для JSON-даты "2026-05-15"
СтрокаJSON = "2026-05-15";
СтрокаДляДаты = СтрЗаменить(СтрокаJSON, "-", "");
ДатаРезультат = Дата(
Число(Лев(СтрокаДляДаты, 4)),
Число(Сред(СтрокаДляДаты, 5, 2)),
Число(Прав(СтрокаДляДаты, 2))
);
При работе с Excel через COMОбъект даты могут передаваться как числа (количество дней с 1900 года). В этом случае используйте:
ДатаExcel = 45345; // Пример значения из Excel
Дата1С = НачалоГода(1900) + ДатаExcel - 2; // -2 из-за бага в Excel
⚠️ Внимание: В Excel даты хранятся как количество дней с 1 января 1900 года, но с ошибкой: день "0" соответствует 31.12.1899, а не 01.01.1900. Поэтому при конвертации всегда вычитайте 2 дня.
5. Типичные ошибки и как их избежать
При преобразовании строк в даты разработчики часто сталкиваются с исключениями или некорректными результатами. Рассмотрим самые распространённые ошибки и способы их решения.
Ошибка 1: Пустая строка или некорректный формат
Если передать в Дата() пустую строку или текст, не соответствующий формату даты, платформа выбросит исключение:
НеправильнаяСтрока = "";
ДатаРезультат = Дата(НеправильнаяСтрока); // Ошибка!
Решение: всегда проверяйте строку перед конвертацией:
Если ПустаяСтрока(СтрокаДата) Тогда
Возврат Неопределено; // или Дата(1,1,1) как "пустую" дату
КонецЕсли;
Ошибка 2: Несовпадение форматов
Функция Дата() ожидает формат ДД.ММ.ГГГГ, но если строка в формате ММ/ДД/ГГГГ (как в американском Excel), результат будет неверным:
АмериканскаяДата = "05/15/2026"; // 15 мая или 5 ноября?
ДатаРезультат = Дата(АмериканскаяДата); // Ошибка или неверная дата!
Решение: используйте ручной парсинг или явно указывайте формат:
Части = СтроковыеФункцииКлиентСервер.РазложитьСтроку(АмериканскаяДата, "/");
ДатаРезультат = Дата(Число(Части[2]), Число(Части[0]), Число(Части[1]));
Ошибка 3: Некорректные значения дня/месяца
Если в строке указано "31.02.2026" (31 февраля не существует), функция Дата() выбросит исключение. Чтобы избежать падения программы, используйте Попытка...Исключение:
Попытка
ДатаРезультат = Дата("31.02.2026");
Исключение
Сообщить("Некорректная дата: " + ОписаниеОшибки());
ДатаРезультат = Неопределено;
КонецПопытки;
Ошибка 4: Локализация и региональные настройки
В разных странах разделители дат могут отличаться (например, . в России и / в США). Если ваша информационная база работает в другой локали, используйте:
// Установить русский формат даты
ПараметрыСеанса.УстановитьПараметр("ДатаКраткийФормат", "ДФ=dd.MM.yyyy");
Всегда проверяйте входные данные на корректность перед преобразованием в дату. Используйте конструкцию Попытка...Исключение для обработки ошибок и предоставляйте пользователю понятные сообщения об ошибочных форматах.
6. Оптимизация и производительность
При обработке больших объёмов данных (например, импорт тысяч строк из файла) важно оптимизировать код парсинга дат, чтобы избежать замедления работы системы. Вот несколько рекомендаций:
Совет 1: Кэшируйте соответствия месяцев
Если вам часто приходится парсить текстовые даты, заранее создайте и кэшируйте словарь месяцев:
// В модуле приложения или общем модуле
Перем МесяцыКэш;
Процедура ИнициализироватьКэшМесяцев()
Если МесяцыКэш = Неопределено Тогда
МесяцыКэш = Новый Соответствие;
МесяцыКэш.Вставить("января", 1);
МесяцыКэш.Вставить("февраля", 2);
// ... остальные месяцы
КонецЕсли;
КонецПроцедуры
Совет 2: Используйте регулярные выражения для сложных форматов
Для строк с неструктурированными датами (например, "Заказ от 15 мая 2026 г.") эффективнее использовать регулярные выражения:
Текст = "Документ от 15.05.2026 №123";
Регулярка = Новый РегулярноеВыражение("\d{2}\.\d{2}\.\d{4}");
Найдено = Регулярка.Найти(Текст);
Если Найдено Тогда
ДатаРезультат = Дата(Найдено.НайденноеЗначение);
КонецЕсли;
Совет 3: Пакетная обработка
Если вам нужно преобразовать даты в большом массиве данных, используйте пакетную обработку:
МассивСтрок = Новый Массив;
МассивСтрок.Добавить("15.05.2026");
МассивСтрок.Добавить("16.05.2026");
// ...
МассивДат = Новый Массив;
Для Каждого Строка Из МассивСтрок Цикл
Попытка
МассивДат.Добавить(Дата(Строка));
Исключение
МассивДат.Добавить(Неопределено);
КонецПопытки;
КонецЦикла;
Совет 4: Предварительная валидация
Перед парсингом проверяйте строки на соответствие ожидаемому формату с помощью СтрДлина() или регулярных выражений:
Функция ЭтоКорректнаяДата(Строка)
// Проверяем формат ДД.ММ.ГГГГ
Если СтрДлина(Строка) = 10 И Сред(Строка, 3, 1) = "." И Сред(Строка, 6, 1) = "." Тогда
Возврат Истина;
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
7. Примеры реальных задач
Рассмотрим несколько практических примеров, с которыми сталкиваются разработчики 1С при работе с датами из строк.
Задача 1: Импорт дат из CSV-файла
Допустим, у вас есть CSV-файл с колонкой дат в формате ММ/ДД/ГГГГ (американский формат). Нужно загрузить их в 1С:
ТекстФайла = Новый ЧтениеТекста("C:\data.csv", КодировкаТекста.UTF8);
Строка = ТекстФайла.ПрочитатьСтроку(); // Пропускаем заголовок
Пока Истина Цикл
Строка = ТекстФайла.ПрочитатьСтроку();
Если Строка = Неопределено Тогда Прервать; КонецЕсли;
Части = СтроковыеФункцииКлиентСервер.РазложитьСтроку(Строка, ",");
АмериканскаяДата = Части[0]; // Предполагаем, что дата в первой колонке
ЧастиДаты = СтроковыеФункцииКлиентСервер.РазложитьСтроку(АмериканскаяДата, "/");
Дата1С = Дата(Число(ЧастиДаты[2]), Число(ЧастиДаты[0]), Число(ЧастиДаты[1]));
// Далее сохраняем Дата1С в базу
КонецЦикла;
Задача 2: Парсинг даты из email-письма
В письме может быть строка вида "Документ от 15 мая 2026 года". Извлечём дату:
ТекстПисьма = "Уважаемый клиент! Ваш заказ от 15 мая 2026 года обработан.";
Регулярка = Новый РегулярноеВыражение("(\d{1,2})\s(январ[яь]|феврал[яь]|...|декабр[яь])\s(\d{4})");
Найдено = Регулярка.Найти(ТекстПисьма);
Если Найдено Тогда
День = Число(Найдено.Группа(1));
МесяцТекст = Найдено.Группа(2);
Год = Число(Найдено.Группа(3));
Месяц = МесяцыКэш[НижнийРегистр(МесяцТекст)];
ДатаРезультат = Дата(Год, Месяц, День);
КонецЕсли;
Задача 3: Конвертация даты из Unix timestamp
Если дата приходит в виде Unix timestamp (количество секунд с 1970 года), используйте:
Timestamp = 1715794600; // Пример: 15 мая 2026, 14:30:00
Дата1С = Начало19700101 + Timestamp;
Задача 4: Обработка диапазона дат
Строка может содержать диапазон (например, "с 01.05.2026 по 15.05.2026"). Разобьём её на две даты:
ТекстДиапазона = "с 01.05.2026 по 15.05.2026";
Регулярка = Новый РегулярноеВыражение("\d{2}\.\d{2}\.\d{4}");
НайденныеДаты = Регулярка.НайтиВсе(ТекстДиапазона);
ДатаНачала = Дата(НайденныеДаты[0].Значение);
ДатаОкончания = Дата(НайденныеДаты[1].Значение);
FAQ: Частые вопросы по работе с датами в 1С
Как преобразовать строку "20260515" в дату?
Используйте функцию Дата() с ручным разбором строки:
Строка = "20260515";
ДатаРезультат = Дата(
Число(Лев(Строка, 4)), // Год
Число(Сред(Строка, 5, 2)), // Месяц
Число(Прав(Строка, 2)) // День
);
Почему функция Дата() выдаёт ошибку для строки "31.02.2026"?
Потому что 31 февраля не существует. Функция Дата() проверяет корректность даты. Чтобы избежать ошибки, используйте конструкцию Попытка...Исключение:
Попытка
ДатаРезультат = Дата("31.02.2026");
Исключение
Сообщить("Некорректная дата!");
КонецПопытки;
Как получить текущую дату в виде строки?
Используйте функцию Формат():
ТекущаяДатаСтрока = Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy");
Сообщить(ТекущаяДатаСтрока); // Например: "15.05.2026"
Можно ли преобразовать строку "сегодня" или "вчера" в дату?
Стандартными средствами 1С — нет. Но можно написать свою функцию:
Функция ТекстовоеНазваниеВДату(Текст)
Текст = НижнийРегистр(Текст);
Если Текст = "сегодня" Тогда
Возврат ТекущаяДата();
ИначеЕсли Текст = "вчера" Тогда
Возврат ТекущаяДата() - 1;
ИначеЕсли Текст = "завтра" Тогда
Возврат ТекущаяДата() + 1;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Как сравнить две даты в виде строк?
Лучше преобразовать строки в тип Дата, а затем сравнивать:
Дата1 = Дата("15.05.2026");
Дата2 = Дата("16.05.2026");
Если Дата1 < Дата2 Тогда
Сообщить("Дата1 раньше Даты2");
КонецЕсли;
Если строки в одинаковом формате (например, обе в ГГГГММДД), можно сравнить их как строки:
Строка1 = "20260515";
Строка2 = "20260516";
Если Строка1 < Строка2 Тогда
Сообщить("Строка1 раньше");
КонецЕсли;