Строка в дату в 1С БСП: функция СтрокаВДату и её две реализации
Универсальный разбор — СтроковыеФункцииКлиентСервер.СтрокаВДату(Значение, ЧастьДаты):
понимает разделители . / -, порядок «день-месяц-год» и
«год-месяц-день», двузначный год, названия месяцев и время. Упрощённый вариант —
ОбщегоНазначенияКлиентСервер.СтрокаВДату(Значение): он пробует штатное приведение
платформы, а затем два порядка следования частей — ДД ММ ГГГГ и ММ ДД ГГГГ.
Ни одна из них не выбрасывает исключение: если строку разобрать не удалось, вернётся пустая дата
Дата(1, 1, 1). Результат всегда проверяйте через ЗначениеЗаполнено().
Где в БСП лежат функции преобразования строки в дату
В библиотеке стандартных подсистем нет единой точки входа «1С БСП дата из строки». Экспортных функций
с именем СтрокаВДату две, они лежат в разных общих модулях и написаны независимо:
-
СтроковыеФункцииКлиентСервер.СтрокаВДату(Знач Значение, ЧастьДаты = Неопределено)— полноценный парсер пользовательского ввода и внешних выгрузок; -
ОбщегоНазначенияКлиентСервер.СтрокаВДату(Знач Значение)— компактное приведение, областьПриведениеЗначениярядом сЭтоЧисло().
Оба модуля клиент-серверные и не помечены как «Вызов сервера», поэтому вызывать их можно и из формы, и из серверного кода без лишнего обращения к серверу. Имя функции одинаковое, поведение — нет, и это главный источник расхождений: код, отлаженный на одном модуле, после замены имени модуля начинает возвращать другие даты.
СтроковыеФункцииКлиентСервер.СтрокаВДату: какие форматы принимает
Это основная функция БСП для разбора «грязных» строк. Порядок работы такой: значение обрезается по
краям, неразрывные пробелы, переводы строк и табуляции заменяются на обычный пробел, строка переводится
в верхний регистр, затем делается попытка штатного приведения через
ОписаниеТипов("Дата") с квалификатором. Если платформа строку не поняла, включается
ручной разбор.
// Общий модуль СтроковыеФункцииКлиентСервер, доступен на клиенте и на сервере
Д1 = СтроковыеФункцииКлиентСервер.СтрокаВДату("23.02.1980"); // 23.02.1980 00:00:00
Д2 = СтроковыеФункцииКлиентСервер.СтрокаВДату("23/02/80"); // 23.02.1980 00:00:00
Д3 = СтроковыеФункцииКлиентСервер.СтрокаВДату("2024-05-17"); // 17.05.2024 00:00:00
Д4 = СтроковыеФункцииКлиентСервер.СтрокаВДату("20240517"); // 17.05.2024 00:00:00
Д5 = СтроковыеФункцииКлиентСервер.СтрокаВДату("170524"); // 17.05.2024 00:00:00
Д6 = СтроковыеФункцииКлиентСервер.СтрокаВДату("дата: 17-05-2024 г."); // 17.05.2024 00:00:00
Если Не ЗначениеЗаполнено(Д6) Тогда
// строку разобрать не удалось
КонецЕсли;
Что фактически разбирается по коду функции:
-
Любые нецифровые разделители. Разделителем считается всё, что не цифра, поэтому
17.05.2024,17/05/2024и17-05-2024обрабатываются одинаково. -
Мусор по краям. Перед первой и после последней цифры текст отбрасывается —
"дата: 17-05-2024 г."разберётся корректно. -
Оба порядка частей. Если первая группа цифр состоит из четырёх символов, она
считается годом (
2024-05-17), иначе первой идёт день (17.05.2024). -
Двузначный год. Порог — 30: год меньше 30 трактуется как 20xx, остальные как 19xx.
Так
"23/02/80"становится 1980 годом, а"01.01.29"— 2029. - Сплошные цифры. Строка из 6 цифр читается как ДДММГГ, из 8 — сначала как ГГГГММДД, а если такой даты не существует, как ДДММГГГГ.
-
Названия месяцев. Перед разбором функция в цикле по 12 месяцам подставляет вместо
названия его номер, используя шаблоны
Формат(Дата, "ДФ=ММММ")иФормат(Дата, "ДФ=MMM")в верхнем регистре. Регистр исходной строки значения не имеет, а вот форма и язык названия должны совпадать с тем, что даёт платформа в текущем сеансе, — это стоит проверить на своей базе.
Параметр ЧастьДаты: почему теряется время
Второй параметр — значение системного перечисления ЧастиДаты. Функция строит из него
Новый КвалификаторыДаты(ЧастьДаты) и использует квалификатор при приведении, а заодно сама
решает, разбирать ли дату и время. Если передано не значение типа ЧастиДаты, параметр
молча заменяется на ЧастиДаты.Дата — то есть по умолчанию время из строки отбрасывается.
Строка = "17.05.2024 14:30:05";
// По умолчанию — только дата, время обнуляется
Д1 = СтроковыеФункцииКлиентСервер.СтрокаВДату(Строка); // 17.05.2024 00:00:00
// Дата и время
Д2 = СтроковыеФункцииКлиентСервер.СтрокаВДату(Строка, ЧастиДаты.ДатаВремя); // 17.05.2024 14:30:05
// Только время, дата остаётся пустой
Д3 = СтроковыеФункцииКлиентСервер.СтрокаВДату(Строка, ЧастиДаты.Время); // 01.01.0001 14:30:05
Время в строке распознаётся как последний фрагмент после пробела. Он отделяется от даты, разбирается по разделителям на часы, минуты и секунды и приводится к виду ЧЧММСС. Отдельная проверка защищает от ложного срабатывания: фрагмент из двух или четырёх цифр без разделителей считается частью даты (например, годом), а не временем.
При ЧастиДаты.Время дата принудительно заменяется на 00010101, поэтому
результат — пустая дата с нужным временем. Это удобно, когда из строки нужно вытащить только момент
суток, чтобы потом прибавить его к дате документа.
ОбщегоНазначенияКлиентСервер.СтрокаВДату: упрощённое приведение
Вторая реализация короче и живёт в области ПриведениеЗначения. Сначала она проверяет
заполненность строки, затем пробует привести значение штатным
ОписаниеТипов("Дата").ПривестиЗначение(). Если результат — непустая дата, он и
возвращается. Дальше начинается собственный разбор.
// Общий модуль ОбщегоНазначенияКлиентСервер
Д1 = ОбщегоНазначенияКлиентСервер.СтрокаВДату("17.05.2024 14:30:05"); // 17.05.2024 14:30:05
Д2 = ОбщегоНазначенияКлиентСервер.СтрокаВДату("05/17/2024"); // 17.05.2024 00:00:00
Д3 = ОбщегоНазначенияКлиентСервер.СтрокаВДату(""); // 01.01.0001 00:00:00
Д4 = ОбщегоНазначенияКлиентСервер.СтрокаВДату("17 мая 2024"); // 01.01.0001 00:00:00
Алгоритм ручного разбора здесь такой:
- строка длиннее 25 символов сразу даёт пустую дату;
- из строки посимвольно набираются группы цифр; групп меньше трёх — пустая дата;
- недостающие группы (часы, минуты, секунды) дополняются нулями до шести;
- первая попытка — трактовка исходного порядка как ДД ММ ГГГГ: части переставляются в ГГГГММДДЧЧММСС и приводятся к дате;
-
если такой даты не существует, вторая попытка — порядок ММ ДД ГГГГ, поэтому американское
05/17/2024тоже разберётся; - обе попытки провалились — возвращается
Дата(1, 1, 1).
Важно: время здесь не отбрасывается — если в строке есть часы и минуты, они попадут в результат,
аналога ЧастьДаты у этой функции нет. Логики достройки века тоже нет: двузначный год
группа не превращает в четырёхзначный, и разбор опирается только на то, что сможет принять
ОписаниеТипов.
Чем отличаются две реализации СтрокаВДату
-
Управление временем. В
СтроковыеФункцииКлиентСервервремя по умолчанию отбрасывается и включается черезЧастиДаты.ДатаВремя. ВОбщегоНазначенияКлиентСервервремя всегда идёт в результат, если оно было в строке. -
Двузначный год. Обрабатывается только в
СтроковыеФункцииКлиентСервер(порог 30). Вторая функция такой логики не содержит. -
Названия месяцев. Поддерживаются только в
СтроковыеФункцииКлиентСервер; для второй реализации буквы — просто разделители, и строка без трёх групп цифр даст пустую дату. -
Порядок частей.
СтроковыеФункцииКлиентСерверопределяет год по длине первой группы (4 цифры — год).ОбщегоНазначенияКлиентСерверперебирает два варианта: сначала ДД ММ ГГГГ, затем ММ ДД ГГГГ. - Ограничение длины. 25 символов — только во второй функции, и только для ветки ручного разбора.
Практический вывод: пользовательский ввод, CSV, обмен с внешними системами и любые «неизвестные»
форматы разбирайте через СтроковыеФункцииКлиентСервер. Вторая функция уместна там, где
формат почти нормализован, и нужно лишь подстраховаться от перестановки дня и месяца.
Что вернётся при некорректной строке
Обе функции спроектированы как «безопасные»: любое непонятное значение превращается в пустую дату
Дата(1, 1, 1), то есть 01.01.0001 00:00:00. Исключение не возбуждается, лог не пишется,
признака «разобрано / не разобрано» в возвращаемом значении нет. Поэтому проверка результата —
обязанность вызывающего кода.
ЗначениеИзФайла = СокрЛП(Ячейка);
Дата = СтроковыеФункцииКлиентСервер.СтрокаВДату(ЗначениеИзФайла, ЧастиДаты.ДатаВремя);
Если Не ЗначениеЗаполнено(Дата) Тогда
ТекстОшибки = СтрШаблон("Строка %1 не распознана как дата, строка файла %2",
ЗначениеИзФайла, НомерСтроки);
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстОшибки);
Продолжить;
КонецЕсли;
Отдельная ловушка — «частично разобранная» строка. Если в значении три группы цифр, разбор формально
удастся, даже когда исходный формат был другим. Например, строка с номером и датой вида
"12-345-2024" вернёт не пустую дату, а результат интерпретации групп как дня, месяца и
года. Пустая дата ловит только полный провал разбора, а не смысловую ошибку, — сверяйте формат
источника заранее.
Когда достаточно платформенных Дата() и XMLЗначение()
Если формат строки известен и стабилен, функции БСП не нужны — платформа справится быстрее и строже.
// Жёсткий формат ГГГГММДДЧЧММСС — литерал платформы
Д1 = Дата("20240517143005"); // 17.05.2024 14:30:05
// ISO 8601 из веб-сервиса или JSON: строгий разбор, ошибка формата — исключение
Попытка
Д2 = XMLЗначение(Тип("Дата"), "2024-05-17T14:30:05");
Исключение
Д2 = Дата(1, 1, 1);
КонецПопытки;
// Приведение по описанию типов — тот же механизм, что использует БСП внутри
ОписаниеДаты = Новый ОписаниеТипов("Дата");
Д3 = ОписаниеДаты.ПривестиЗначение("20240517");
Ориентир по выбору: XMLЗначение() — для обменов, где формат гарантирован схемой и любое
отклонение должно быть ошибкой; Дата() — для собственных строк вида ГГГГММДД;
ОписаниеТипов("Дата").ПривестиЗначение() — когда нужно приведение без исключения, но и
без эвристик БСП. Строки со смещением часового пояса (2024-05-17T14:30:05+03:00) корректно
разбирает XMLЗначение(), а не СтрокаВДату: для функций БСП знак смещения —
обычный разделитель, и лишние группы цифр ломают разбор.
Частые ошибки при преобразовании строки в дату в БСП
-
Ждут исключение при неверном формате. Его не будет: обе функции вернут
Дата(1, 1, 1). Без проверкиЗначениеЗаполнено()в документы попадёт 01.01.0001, и обнаружится это уже в отчётах. -
Пропало время.
СтроковыеФункцииКлиентСервер.СтрокаВДату()без второго параметра работает какЧастиДаты.Датаи обнуляет часы и минуты. Для строк с временем передавайтеЧастиДаты.ДатаВремя. -
В ЧастьДаты передают строку или число. Значение не типа
ЧастиДатымолча заменяется наЧастиДаты.Дата. Ошибки не будет, время просто исчезнет. Плюс параметр объявлен безЗнач: переданная переменная перезапишется значениемЧастиДаты.Датав вызывающем коде. -
Меняют модуль, не меняя ожиданий. Замена
СтроковыеФункцииКлиентСервернаОбщегоНазначенияКлиентСерверубирает поддержку двузначного года и названий месяцев, но добавляет время в результат. -
Неоднозначность дня и месяца. Для
"05.06.2024"обе функции выберут первый подходящий вариант — 5 июня. Американский порядок распознаётся, только когда день больше 12 делает первый вариант невозможным. -
Двузначный год у дат рождения. Порог 30 в
СтроковыеФункцииКлиентСерверозначает, что"01.01.30"станет 1930 годом, а"01.01.29"— 2029. Для исторических дат передавайте четырёхзначный год. -
ISO-строка с таймзоной. Смещение
+03:00добавляет лишние группы цифр и приводит к пустой дате. Такие значения разбирайтеXMLЗначение(Тип("Дата"), ...). - Длинная строка в ОбщегоНазначенияКлиентСервер. Больше 25 символов — ручной разбор не запускается вообще, результат сразу пустая дата.
Частые вопросы про СтрокаВДату в БСП
В каком модуле БСП лежит функция преобразования строки в дату?
Их две: СтроковыеФункцииКлиентСервер.СтрокаВДату(Знач Значение, ЧастьДаты = Неопределено)
и ОбщегоНазначенияКлиентСервер.СтрокаВДату(Знач Значение). Первая — универсальный
парсер с поддержкой двузначного года, названий месяцев и времени, вторая — упрощённое приведение
с перебором порядков ДД ММ ГГГГ и ММ ДД ГГГГ. Оба модуля доступны и на клиенте, и на сервере.
Что вернёт СтрокаВДату, если строку не удалось разобрать?
Пустую дату Дата(1, 1, 1) — 01.01.0001 00:00:00. Исключение не возбуждается, поэтому
результат нужно проверять через ЗначениеЗаполнено(), иначе некорректные строки тихо
превратятся в пустую дату в данных.
Когда вместо БСП достаточно платформенных Дата() и XMLЗначение()?
Когда формат строки известен заранее. Дата("ГГГГММДДЧЧММСС") подходит для собственных
нормализованных строк, XMLЗначение(Тип("Дата"), ...) — для ISO 8601 из обменов, где
нарушение формата должно приводить к ошибке. Функции БСП нужны там, где формат заранее неизвестен
или пришёл от пользователя.
ИИ Консоль кода 1С
Лайт
Для ознакомления с возможностями
- Полный набор инструментов без урезаний
- Без ввода карты
Старт
Для индивидуального использования
- До 5 конфигураций
- Встроенный агент запросов 1С
-
≈ 100 задач Подробнее про лимиты
- Техническая поддержка
Продвинутый
Популярный выборДля интенсивного использования или команд
- До 15 конфигураций
- Встроенный агент запросов 1С
-
≈ 300 задач Подробнее про лимиты
-
Свои подписки Codex, Claude и любые OpenAI-совместимые
-
Внешние обработки без Конфигуратора
- Приоритетная техническая поддержка