Skip to content

Исправление ошибки преобразования времени#341

Open
ivanmolodec wants to merge 19 commits into
developfrom
339-fix-error
Open

Исправление ошибки преобразования времени#341
ivanmolodec wants to merge 19 commits into
developfrom
339-fix-error

Conversation

@ivanmolodec

@ivanmolodec ivanmolodec commented Oct 16, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • Bug Fixes

    • Унифицирована и укреплена обработка преобразования дат из строк: надёжный парсинг ISO (с/без миллисекунд), безопасный разбор форматов с разделителями и без, корректная сборка даты/времени, повторная попытка и возврат даты‑по‑умолчанию при ошибках или пустых входах; отдельная логика для веб‑клиента.
  • New Features

    • Добавлены экспортируемые вспомогательные функции: безопасное преобразование строки в число и извлечение только даты при разделителе‑пробеле.
  • Tests

    • Добавлен набор модульных тестов, покрывающих ISO‑парсинг, миллисекунды, пустые/неверные значения и веб‑сценарии.
  • Chores

    • Обновлена конфигурация метаданных для нового тестового модуля.

Note

Strengthens ПреобразоватьДатуИзСтрокиПоФормату with safer ISO/format parsing (incl. web client), adds helpers, and introduces unit tests with config updates.

  • Common module (src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl):
    • Date parsing robustness:
      • Handle empty inputs for ВхЗначение/НомерФормата; default to Дата(1,1,1,0,0,0) on errors.
      • For format "0_0_0": strip milliseconds before XMLЗначение (desktop); add manual ISO parser for web client.
      • Safer parsing for other formats: support 3-part time arrays, validate parts count/length, safe number conversion, try-catch Дата(...), cap to max date.
    • New helpers: ПолучитьТолькоДатуЕслиРазделительПробел, БезопасноПреобразоватьСтрокуВЧисло; replace older implementation of the former.
  • Tests:
    • Add module пбп_СтроковыеФункцииКлиентСервер_Тесты with cases for ISO parsing (with/without ms), empty/invalid inputs, web-client parsing, and 3-element time split.
    • Update src/cfe/YAXUnit/Configuration.xml to include the new test module.

Written by Cursor Bugbot for commit c56e998. This will update automatically on new commits. Configure here.

…0_0_0 и добавлены юнит-тесты (#339)

- Заменён Формат() на XMLЗначение(Тип("Дата"), Строка(ВхЗначение)) в ветке веб-клиента
- Добавлены YAXUnit тесты для проверки парсинга ISO строк с форматом 0_0_0
- Тесты покрывают: обычную ISO строку, ISO с миллисекундами, пустые значения
…начение на ручной парсинг ISO даты (#339)

- Заменён XMLЗначение на альтернативный алгоритм парсинга ISO строк в веб-клиенте
- Используется СтрРазделить и СтрокаВЧисло для безопасного парсинга
- Добавлена обработка миллисекунд и некорректных данных
- Расширены тесты: добавлены клиентские тесты для проверки веб-клиента
- Исправлена ошибка синтаксического контроля "XMLЗначение не определена в веб-клиенте"
…о issue #339

- Заменена строка МинутыСекунды = МассивРазделителей[1] на проверку количества элементов
- Добавлена логика: если МассивРазделителей.Количество() = 3, то объединяем элементы [1] и [2]
- Добавлен тест ТестДолженКорректноОбрабатыватьМассивРазделителейС3Элементами для проверки исправления
- Исправлена ошибка парсинга времени в форматах с 3 разделителями (например, "2024-01-02 15:30:45")
@coderabbitai

coderabbitai Bot commented Oct 16, 2025

Copy link
Copy Markdown

Walkthrough

Переработан парсер даты в функции ПреобразоватьДатуИзСтрокиПоФормату: введены безопасные преобразования строк→чисел, ветвление для веб-/не‑веб‑клиента (ISO‑разбор с миллисекундами), расширенный разбор форматов с/без разделителей, ограничение максимальной даты и новые экспортные утилиты; добавлены серверные unit‑тесты и метаданные YAXUnit.

Changes

Cohort / File(s) Изменение
Основной модуль логики
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl
Существенно переработан ПреобразоватьДатуИзСтрокиПоФормату: объединена валидация входов, добавлены ветви для веб‑ и не‑веб‑клиента (ISO‑парсинг, миллисекунды), безопасные преобразования частей даты/времени, поддержка AM/PM, проверки длин/валидности, ограничение даты; добавлены экспортные функции БезопасноПреобразоватьСтрокуВЧисло и ПолучитьТолькоДатуЕслиРазделительПробел.
Метаданные тестового модуля
src/cfe/YAXUnit/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты.xml
Добавлен XML‑описатель серверного CommonModule для тестов (UUID, имя, свойства модуля).
Тестовый модуль
src/cfe/YAXUnit/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты/Ext/Module.bsl
Новый тестовый модуль с ИсполняемыеСценарии() и набором юнит‑тестов для ПреобразоватьДатуИзСтрокиПоФормату (ISO с/без миллисекунд, пустые/некорректные входы, веб‑ветвь, массив разделителей).
Конфигурация YAXUnit
src/cfe/YAXUnit/Configuration.xml
Добавлены записи о новом CommonModule тестов в конфигурацию YAXUnit.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Вызов
    participant Module as ПреобразоватьДатуИзСтрокиПоФормату
    participant Helper as БезопасноПреобразоватьСтрокуВЧисло
    rect rgba(230,245,255,0.7)
    Caller->>Module: Вход(ВхЗначение, НомерФормата, ВебКлиент, ...)
    alt НомерФормата = "0_0_0" и ВебКлиент = true
        Module->>Module: Разделить "T" -> дата / время (ISO)
        Module->>Helper: Преобразовать части времени (часы, минуты, сек, дробь)
        Module-->Caller: Собранная Дата или ДатаПоУмолчанию
    else НомерФормата = "0_0_0" и ВебКлиент = false
        Module->>Module: Парсинг XML/ISO, обработка миллисекунд
        Module->>Helper: Безопасные преобразования частей в числа
        Module-->Caller: Дата или ДатаПоУмолчанию
    else Другие форматы (с/без разделителей)
        Module->>Module: Разбор по разделителям, AM/PM, проверки длины/валидности
        Module->>Helper: Безопасная конверсия строк в числа
        Module-->Caller: Дата или ДатаПоУмолчанию
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Проверить ветвления для веб‑клиента (ISO‑разбор, дробная часть секунд) и корректность разделения по "T".
  • Проверить разбор форматов без разделителей и соответствие ожиданию (длины, порядок YYYY/MM/DD и пр.).
  • Аудит БезопасноПреобразоватьСтрокуВЧисло и граничных проверок при создании даты (ограничение до 3999‑12‑31).
  • Прогон и валидация новых YAXUnit тестов и метаданных.

Possibly related issues

Possibly related PRs

Suggested reviewers

  • thvvmas

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed Заголовок "Исправление ошибки преобразования времени" (Fix time conversion error) точно отражает основное назначение pull request — исправление и улучшение функции ПреобразоватьДатуИзСтрокиПоФормату путём добавления безопасного парсинга, обработки граничных случаев и поддержки различных форматов даты-времени. Заголовок ясен, описательный и охватывает центральную часть изменений. Хотя PR включает дополнительные компоненты (тесты, вспомогательные функции, регистрация конфигурации), основная задача — исправление ошибок в преобразовании времени, что адекватно отражено в названии.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 339-fix-error

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…енён СтрокаВЧисло на безопасную функцию (#339)

- Заменён СтрокаВЧисло на вспомогательную функцию БезопасноПреобразоватьСтрокуВЧисло
- Добавлена функция БезопасноПреобразоватьСтрокуВЧисло с обработкой исключений
- Исправлены ошибки синтаксического контроля: "СтрокаВЧисло не определена в веб-клиенте"
- Функция теперь корректно работает во всех клиентах 1С без синтаксических ошибок

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (2)

180-180: Избыточное преобразование в строку.

Параметр ВхЗначение уже имеет тип Строка согласно описанию функции. Преобразование Строка(ВхЗначение) является избыточным.

Примените этот diff:

-			ДатаВремяСтрока = Строка(ВхЗначение);
+			ДатаВремяСтрока = ВхЗначение;

186-200: Рассмотрите более строгую валидацию числовых значений.

Использование СтрокаВЧисло() с параметрами по умолчанию (0, 0) возвращает 0 при ошибке парсинга, что может скрыть некорректные данные. Рассмотрите возможность явной проверки результата или использование блока try/catch для каждой операции парсинга.

Пример улучшенной валидации:

Попытка
	Год = Число(ЧастиДаты[0]);
	Месяц = Число(ЧастиДаты[1]);
	День = Число(ЧастиДаты[2]);
	
	Если Год <= 0 Или Месяц <= 0 Или Месяц > 12 Или День <= 0 Или День > 31 Тогда
		ПреобразованнаяДата = Дата(1, 1, 1, 0, 0, 0);
		Возврат ПреобразованнаяДата;
	КонецЕсли;
Исключение
	ПреобразованнаяДата = Дата(1, 1, 1, 0, 0, 0);
	Возврат ПреобразованнаяДата;
КонецПопытки;
src/cfe/YAXUnit/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты/Ext/Module.bsl (1)

70-81: Рассмотрите добавление тестов для граничных случаев.

Текущие тесты хорошо покрывают основные сценарии ошибок, но можно дополнительно добавить тесты для:

  • Минимальных и максимальных допустимых дат
  • Различных временных зон (если поддерживается)
  • Дат с разными форматами разделителей

Пример дополнительного теста:

Процедура ТестДолженОбрабатыватьГраничныеДаты() Экспорт
	
	// Минимальная дата
	МинДата = Дата(1, 1, 1, 0, 0, 0);
	Результат1 = пбп_СтроковыеФункцииКлиентСервер.ПреобразоватьДатуИзСтрокиПоФормату("0001-01-01T00:00:00", "0_0_0");
	ЮТест.ОжидаетЧто(Результат1).Равно(МинДата);
	
	// Максимальная дата
	МаксДата = Дата(3999, 12, 31, 23, 59, 59);
	Результат2 = пбп_СтроковыеФункцииКлиентСервер.ПреобразоватьДатуИзСтрокиПоФормату("3999-12-31T23:59:59", "0_0_0");
	ЮТест.ОжидаетЧто(Результат2).Равно(МаксДата);
	
КонецПроцедуры
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e953e2e and 10244d3.

📒 Files selected for processing (3)
  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (2 hunks)
  • src/cfe/YAXUnit/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты.xml (1 hunks)
  • src/cfe/YAXUnit/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты/Ext/Module.bsl (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: ivanmolodec
PR: firstBitSportivnaya/PSSL#0
File: :0-0
Timestamp: 2024-07-29T10:13:46.428Z
Learning: User: ivanmolodec
URL: https://github.com/firstBitSportivnaya/PSSL/pull/52
Timestamp: 2024-04-19T09:46:50.450Z
Learning: Use the Russian language for all interactions related to the repository `firstBitSportivnaya/PSSL`.
🔇 Additional comments (4)
src/cfe/YAXUnit/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты.xml (1)

1-23: Конфигурация тестового модуля корректна.

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

src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (1)

177-208: Хорошая реализация обработки ошибок для веб-клиента.

Добавление блока try/catch и явной проверки наличия разделителя "T" обеспечивает надежную обработку ошибок и корректный fallback к значению по умолчанию при некорректном формате данных.

src/cfe/YAXUnit/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты/Ext/Module.bsl (2)

1-97: Хорошее покрытие основных сценариев тестами.

Тестовый модуль покрывает ключевые аспекты функциональности:

  • Парсинг ISO формата без миллисекунд
  • Игнорирование миллисекунд
  • Обработка пустых значений
  • Парсинг в веб-клиенте
  • Обработка ошибок
  • Корректная обработка массива с 3 элементами (исправление issue #339)

83-95: Тест корректно проверяет исправление issue #339.

Тест явно проверяет сценарий с тремя элементами разделителей (формат "2024-01-02 15:30:45" с форматом "3_1_1"), что соответствует описанию исправляемой ошибки.

… работы YAxUnit (#339)

- Переместил пбп_СтроковыеФункцииКлиентСервер_Тесты из расширения YAXUnit в основную конфигурацию
- Исправлены методы регистрации тестов: заменены ДобавитьСерверныйТест/ДобавитьКлиентскийТест на ДобавитьТест
- Тестовый модуль теперь находится в src/cf/CommonModules/ согласно архитектуре YAxUnit
- Удалены дублирующие файлы из расширения YAXUnit
- Тесты теперь должны корректно запускаться через YAxUnit

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты/Ext/Module.bsl (1)

57-68: Возможное дублирование теста.

Этот тест идентичен тесту ТестДолженПарситьISOБезМиллисекунд (строки 21-31). Если цель — проверить специфическое поведение веб-клиента, тест должен явно проверять различия в поведении между клиентами. Если различий нет, рассмотрите возможность удаления дублирующего теста.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74158b8 and 3e6fa4a.

📒 Files selected for processing (2)
  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты.xml (1 hunks)
  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты/Ext/Module.bsl (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: ivanmolodec
PR: firstBitSportivnaya/PSSL#0
File: :0-0
Timestamp: 2024-07-29T10:13:46.428Z
Learning: User: ivanmolodec
URL: https://github.com/firstBitSportivnaya/PSSL/pull/52
Timestamp: 2024-04-19T09:46:50.450Z
Learning: Use the Russian language for all interactions related to the repository `firstBitSportivnaya/PSSL`.
🔇 Additional comments (7)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты.xml (1)

1-23: Конфигурация метаданных корректна.

Файл метаданных правильно определяет тестовый модуль с корректными настройками для серверного выполнения. Все флаги установлены соответствующим образом для тестового модуля.

src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты/Ext/Module.bsl (6)

3-14: Регистрация тестов выполнена корректно.

Процедура правильно регистрирует набор тестов с описательными именами.


21-31: Тест корректно проверяет парсинг ISO даты без миллисекунд.

Проверка типа и значения результата выполнена правильно.


33-43: Тест корректно проверяет игнорирование миллисекунд.

Важная проверка граничного случая, когда миллисекунды должны игнорироваться при парсинге.


45-55: Тест корректно проверяет обработку пустых значений.

Проверка обоих сценариев (пустая строка и пустой формат) выполнена правильно.


70-81: Тест корректно проверяет обработку ошибок.

Хорошее покрытие обработки ошибок: проверяются как некорректный формат строки, так и семантически некорректные значения даты.


83-95: Отличное покрытие исправления ошибки #339.

Тест правильно проверяет корректную обработку массива разделителей с 3 элементами, что является основной целью данного PR. Хорошая практика — явное указание на issue в комментарии.

- Возвращён тестовый модуль пбп_СтроковыеФункцииКлиентСервер_Тесты в расширение YAXUnit
- Удалены дублирующие файлы из основной конфигурации
- Исправлена архитектура размещения тестов согласно вашему замечанию

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/cfe/YAXUnit/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты/Ext/Module.bsl (2)

57-68: Полное дублирование теста.

Данный тест идентичен ТестДолженПарситьISOБезМиллисекунд (строки 21-31). Если веб-клиент требует отдельной проверки, тест должен иметь специфичные условия или проверки. В противном случае это избыточное дублирование кода.

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


1-97: Рекомендация: расширение покрытия тестами.

Текущее покрытие тестами хорошо охватывает основные сценарии. Для более полного покрытия можно рассмотреть добавление тестов для:

  • Граничных случаев (например, 29 февраля високосного/невисокосного года)
  • ISO формата с временной зоной (Z или +00:00)
  • Других разделителей дат
  • Граничных значений годов

Это не критично для текущей функциональности, но может улучшить устойчивость кода к крайним случаям.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e6fa4a and dffd66f.

📒 Files selected for processing (2)
  • src/cfe/YAXUnit/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты.xml (1 hunks)
  • src/cfe/YAXUnit/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты/Ext/Module.bsl (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/cfe/YAXUnit/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты.xml
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: ivanmolodec
PR: firstBitSportivnaya/PSSL#0
File: :0-0
Timestamp: 2024-07-29T10:13:46.428Z
Learning: User: ivanmolodec
URL: https://github.com/firstBitSportivnaya/PSSL/pull/52
Timestamp: 2024-04-19T09:46:50.450Z
Learning: Use the Russian language for all interactions related to the repository `firstBitSportivnaya/PSSL`.
🔇 Additional comments (6)
src/cfe/YAXUnit/CommonModules/пбп_СтроковыеФункцииКлиентСервер_Тесты/Ext/Module.bsl (6)

3-14: Структура регистрации тестов выглядит корректно.

Все тестовые процедуры правильно зарегистрированы в тестовом наборе.


21-31: Тест базового ISO формата реализован корректно.

Проверка типа результата и соответствия ожидаемому значению выполняется правильно.


33-43: Тест игнорирования миллисекунд реализован корректно.

Проверка правильно валидирует, что миллисекунды игнорируются при парсинге.


45-55: Тест обработки пустых значений реализован корректно.

Покрываются оба сценария: пустая входная строка и пустой формат.


70-81: Тест обработки ошибок реализован корректно.

Покрываются важные сценарии: некорректная строка и значения вне допустимого диапазона.


83-95: Тест для исправления issue #339 реализован корректно.

Проверка правильно валидирует обработку массива разделителей с 3 элементами и использует другой формат "3_1_1".

- Добавлен пбп_СтроковыеФункцииКлиентСервер_Тесты в src/cfe/YAXUnit/Configuration.xml
- Теперь YAXUnit должен корректно обнаруживать и запускать тесты для этого модуля
- Удалён дублирующийся xr:ContainedObject для CommonModule из файла src/cfe/YAXUnit/Configuration.xml
- Исправлена ошибка сборки "Неуникальный идентификатор класса хранимого объекта"
- Запись о модуле в ChildObjects оставлена, как и должно быть
- Исправлена логика парсинга часов, минут и секунд.
- Добавлено явное преобразование часов в число перед созданием объекта Дата.
- Учтены случаи, когда в строке времени могут отсутствовать секунды.
- Тест ТестДолженКорректноОбрабатыватьМассивРазделителейС3Элементами теперь должен проходить успешно.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (2)

177-209: ISO‑парсинг в веб‑клиенте: нужны проверки границ массивов и безопасная обработка секунд/таймзоны

Сейчас возможны обращения по несуществующим индексам (ЧастиДатаВремя[1], ЧастиВремени[2]) при “укороченных” строках; это ведёт к исключению и падению в дефолт, хотя можно разобрать корректнее. Заодно стоит игнорировать суффикс 'Z' и секунды при отсутствии 3‑го элемента.

Примените патч (минимальные правки внутри текущего блока):

-				ЧастиДатаВремя = СтрРазделить(ДатаВремяСтрока, "T");
-				ЧастиДаты = СтрРазделить(ЧастиДатаВремя[0], "-");
-				ЧастиВремени = СтрРазделить(ЧастиДатаВремя[1], ":");
-				
-				// Используем безопасное преобразование для веб-клиента
-				Год = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[0], 1);
-				Месяц = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[1], 1);
-				День = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[2], 1);
-				
-				Часы = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[0], 0);
-				Минуты = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[1], 0);
-				
-				// Обрабатываем секунды (могут быть с миллисекундами)
-				СекундыСтрока = ЧастиВремени[2];
-				Если СтрНайти(СекундыСтрока, ".") > 0 Тогда
-					ЧастиСекунды = СтрРазделить(СекундыСтрока, ".");
-					Секунды = БезопасноПреобразоватьСтрокуВЧисло(ЧастиСекунды[0], 0);
-				Иначе
-					Секунды = БезопасноПреобразоватьСтрокуВЧисло(СекундыСтрока, 0);
-				КонецЕсли;
-				
-				ПреобразованнаяДата = Дата(Год, Месяц, День, Часы, Минуты, Секунды);
+				ЧастиДатаВремя = СтрРазделить(ДатаВремяСтрока, "T");
+				Если ЧастиДатаВремя.Количество() < 2 Тогда
+					ПреобразованнаяДата = Дата(1, 1, 1, 0, 0, 0);
+				Иначе
+					ЧастиДаты   = СтрРазделить(ЧастиДатаВремя[0], "-");
+					ЧастиВремени= СтрРазделить(ЧастиДатаВремя[1], ":");
+					Если ЧастиДаты.Количество() < 3 ИЛИ ЧастиВремени.Количество() < 2 Тогда
+						ПреобразованнаяДата = Дата(1, 1, 1, 0, 0, 0);
+					Иначе
+						// Безопасные преобразования
+						Год   = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[0], 1);
+						Месяц = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[1], 1);
+						День  = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[2], 1);
+						Часы   = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[0], 0);
+						Минуты = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[1], 0);
+						// Секунды: берём 3-й элемент при наличии, иначе "0"; отбрасываем суффикс 'Z'
+						СекундыСтрока = ?(ЧастиВремени.Количество() >= 3, ЧастиВремени[2], "0");
+						Если Прав(СекундыСтрока, 1) = "Z" ИЛИ Прав(СекундыСтрока, 1) = "z" Тогда
+							СекундыСтрока = Лев(СекундыСтрока, СтрДлина(СекундыСтрока) - 1);
+						КонецЕсли;
+						Если СтрНайти(СекундыСтрока, ".") > 0 Тогда
+							ЧастиСекунды = СтрРазделить(СекундыСтрока, ".");
+							Если ЧастиСекунды.Количество() = 0 Тогда
+								Секунды = 0;
+							Иначе
+								Секунды = БезопасноПреобразоватьСтрокуВЧисло(ЧастиСекунды[0], 0);
+							КонецЕсли;
+						Иначе
+							Секунды = БезопасноПреобразоватьСтрокуВЧисло(СекундыСтрока, 0);
+						КонецЕсли;
+						ПреобразованнаяДата = Дата(Год, Месяц, День, Часы, Минуты, Секунды);
+					КонецЕсли;
+				КонецЕсли;

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

Based on learnings


233-237: Потенциальный выход за границы: проверяйте Количество() перед обращением к индексам

Если у МассивРазделителей меньше 2 элементов, обращение к [1] упадёт. Предлагаю явную развилку:

-				Если МассивРазделителей.Количество() = 3 Тогда
+				Если МассивРазделителей.Количество() >= 3 Тогда
 					МинутыСекунды = МассивРазделителей[1] + ":" + МассивРазделителей[2];
-				Иначе
+				ИначеЕсли МассивРазделителей.Количество() >= 2 Тогда
 					МинутыСекунды = МассивРазделителей[1];
+				Иначе
+					МинутыСекунды = "00:00";
 				КонецЕсли;
🧹 Nitpick comments (3)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (3)

207-210: Выровняйте ограничение максимальной даты в веб‑ветке с серверной

После try/catch в веб‑ветке нет ограничения “до 3999‑12‑31”, тогда как ниже для обычного парсинга оно есть. Добавьте кэп, чтобы поведение было единообразным.

 		Исключение
 			ПреобразованнаяДата = Дата(1, 1, 1, 0, 0, 0);
 		КонецПопытки;
+		// Ограничение максимальной датой по аналогии с обычной веткой
+		Если ПреобразованнаяДата > Дата(3999, 12, 31, 23, 59, 59) Тогда
+			ПреобразованнаяДата = Дата(3999, 12, 31, 23, 59, 59);
+		КонецЕсли;

319-330: Единообразие: используйте безопасный конвертер и для минут/секунд/часов

Чтобы исключить случайные исключения и упростить обработку нечисловых значений, лучше везде применять БезопасноПреобразоватьСтрокуВЧисло.

-			МинутыЧисло = Число(МассивСекМин[0]);
+			МинутыЧисло = БезопасноПреобразоватьСтрокуВЧисло(МассивСекМин[0], 0);
 			Если МассивСекМин.Количество() > 1 Тогда
-				СекундыЧисло = Число(МассивСекМин[1]);
+				СекундыЧисло = БезопасноПреобразоватьСтрокуВЧисло(МассивСекМин[1], 0);
 			Иначе
 				СекундыЧисло = 0;
 			КонецЕсли;
-		...
-		ЧасыЧисло = Число(Часы);
+		...
+		ЧасыЧисло = БезопасноПреобразоватьСтрокуВЧисло(Часы, 0);

348-357: LGTM: безопасный конвертер числа

Функция корректно страхует ошибки. Можно слегка усилить нормализацией пробелов/типа.

 Функция БезопасноПреобразоватьСтрокуВЧисло(СтрокаЗначение, ЗначениеПоУмолчанию = 0)
 	
 	Попытка
-		Возврат Число(СтрокаЗначение);
+		ЛокСтрока = Строка(СтрокаЗначение);
+		ЛокСтрока = СокрЛП(ЛокСтрока);
+		Возврат Число(ЛокСтрока);
 	Исключение
 		Возврат ЗначениеПоУмолчанию;
 	КонецПопытки;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fb0b511 and e2b6a95.

📒 Files selected for processing (1)
  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: ivanmolodec
PR: firstBitSportivnaya/PSSL#0
File: :0-0
Timestamp: 2024-07-29T10:13:46.428Z
Learning: User: ivanmolodec
URL: https://github.com/firstBitSportivnaya/PSSL/pull/52
Timestamp: 2024-04-19T09:46:50.450Z
Learning: Use the Russian language for all interactions related to the repository `firstBitSportivnaya/PSSL`.
🔇 Additional comments (1)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (1)

340-341: Подтвердить наличие тестов для ISO-вариантов и уточнить безопасность преобразований

Первый поиск подтвердил отсутствие тестов с суффиксом Z, смещениями времени (+HH:MM, -HH:MM) и строк без секунд. В модуле обнаружены прямые вызовы Число( на потенциально опасных местах:

  • Линия 239: Число(МассивРазделителейДатаВремя[МассивРазделителейДатаВремя.Количество() - 1]) — преобразование элемента массива без предварительной валидации
  • Линии 318, 320: Число(МассивСекМин[0]) и Число(МассивСекМин[1]) — доступ к элементам массива без проверки границ

Требуется ручная проверка:

  1. Добавить тесты для ISO-формата с Z и смещениями времени (включая случаи без секунд)
  2. Убедиться, что значения в массивах всегда валидны перед вызовом Число(), или использовать безопасный wrapper БезопасноПреобразоватьСтрокуВЧисло()

…переменной Часы (#339)

- Инициализирована переменная `Часы` в начале блока `Иначе`.
- Это предотвращает ошибку, возникавшую при вызове `Число(Часы)` с неопределенным значением.
- Ошибка "Тип не определен" при выполнении тестов должна быть устранена.
…трок (#339)

- Добавлена обработка исключений при использовании `XMLЗначение` для предотвращения падения тестов.
- Реализовано отсечение миллисекунд из строки даты, так как `XMLЗначение` их не поддерживает.
- Функция теперь корректно возвращает пустую дату (`Дата(1,1,1)`) при получении некорректной строки или формата с миллисекундами.
- Это должно исправить ошибки "Тип не определен" и "Ошибка при вызове метода контекста (XMLЗначение)".

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (2)

187-219: Добавьте проверки границ массивов при разборе ISO‑строки (web).

Возможны выходы за границы: ЧастиДатаВремя[1], ЧастиДаты[0..2], ЧастиВремени[2], ЧастиСекунды[0]. Нужны проверки Количество() перед индексами и безопасные значения по умолчанию.

Рекомендуемый патч:

-            Если СтрНайти(ДатаВремяСтрока, "T") > 0 Тогда
-                ЧастиДатаВремя = СтрРазделить(ДатаВремяСтрока, "T");
-                ЧастиДаты = СтрРазделить(ЧастиДатаВремя[0], "-");
-                ЧастиВремени = СтрРазделить(ЧастиДатаВремя[1], ":");
+            Если СтрНайти(ДатаВремяСтрока, "T") > 0 Тогда
+                ЧастиДатаВремя = СтрРазделить(ДатаВремяСтрока, "T");
+                Если ЧастиДатаВремя.Количество() < 2 Тогда
+                    ПреобразованнаяДата = Дата(1,1,1,0,0,0); Возврат ПреобразованнаяДата;
+                КонецЕсли;
+                ЧастиДаты = СтрРазделить(ЧастиДатаВремя[0], "-");
+                Если ЧастиДаты.Количество() < 3 Тогда
+                    ПреобразованнаяДата = Дата(1,1,1,0,0,0); Возврат ПреобразованнаяДата;
+                КонецЕсли;
+                ЧастиВремени = СтрРазделить(ЧастиДатаВремя[1], ":");
                 
-                // Используем безопасное преобразование для веб-клиента
-                Год = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[0], 1);
-                Месяц = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[1], 1);
-                День = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[2], 1);
+                // Безопасные значения по умолчанию
+                Год = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[0], 1);
+                Месяц = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[1], 1);
+                День = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[2], 1);
                 
-                Часы = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[0], 0);
-                Минуты = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[1], 0);
+                Часы = 0; Минуты = 0; Секунды = 0;
+                Если ЧастиВремени.Количество() >= 1 Тогда
+                    Часы = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[0], 0);
+                КонецЕсли;
+                Если ЧастиВремени.Количество() >= 2 Тогда
+                    Минуты = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[1], 0);
+                КонецЕсли;
                 
-                // Обрабатываем секунды (могут быть с миллисекундами)
-                СекундыСтрока = ЧастиВремени[2];
-                Если СтрНайти(СекундыСтрока, ".") > 0 Тогда
-                    ЧастиСекунды = СтрРазделить(СекундыСтрока, ".");
-                    Секунды = БезопасноПреобразоватьСтрокуВЧисло(ЧастиСекунды[0], 0);
-                Иначе
-                    Секунды = БезопасноПреобразоватьСтрокуВЧисло(СекундыСтрока, 0);
-                КонецЕсли;
+                // Секунды и дробные секунды/зона
+                Если ЧастиВремени.Количество() >= 3 Тогда
+                    СекундыСтрока = ЧастиВремени[2];
+                    // Убираем Z/±смещение, если есть
+                    Плюс = СтрНайти(СекундыСтрока, "+");
+                    Минус = СтрНайти(СекундыСтрока, "-");
+                    Если Плюс > 0 Тогда СекундыСтрока = Лев(СекундыСтрока, Плюс - 1); КонецЕсли;
+                    Если Минус > 0 Тогда СекундыСтрока = Лев(СекундыСтрока, Минус - 1); КонецЕсли;
+                    СекундыСтрока = СтрЗаменить(СекундыСтрока, "Z", "");
+                    Если СтрНайти(СекундыСтрока, ".") > 0 Тогда
+                        ЧастиСекунды = СтрРазделить(СекундыСтрока, ".");
+                        Если ЧастиСекунды.Количество() > 0 Тогда
+                            Секунды = БезопасноПреобразоватьСтрокуВЧисло(ЧастиСекунды[0], 0);
+                        КонецЕсли;
+                    Иначе
+                        Секунды = БезопасноПреобразоватьСтрокуВЧисло(СекундыСтрока, 0);
+                    КонецЕсли;
+                КонецЕсли;

244-248: Индексация МассивРазделителей[1] без проверки количества элементов.

При Количество() < 2 будет выход за границы. Добавьте ветку с проверкой и дефолтом.

Предлагаемый патч:

-                Если МассивРазделителей.Количество() = 3 Тогда
+                Если МассивРазделителей.Количество() >= 3 Тогда
                     МинутыСекунды = МассивРазделителей[1] + ":" + МассивРазделителей[2];
-                Иначе
-                    МинутыСекунды = МассивРазделителей[1];
+                ИначеЕсли МассивРазделителей.Количество() >= 2 Тогда
+                    МинутыСекунды = МассивРазделителей[1];
+                Иначе
+                    МинутыСекунды = "00:00";
                 КонецЕсли;
🧹 Nitpick comments (1)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (1)

359-369: Небольшая полировка «БезопасноПреобразоватьСтрокуВЧисло».

Опционально: пропускайте числовые значения как есть и подрежьте пробелы.

 Функция БезопасноПреобразоватьСтрокуВЧисло(СтрокаЗначение, ЗначениеПоУмолчанию = 0)
 	
 	Попытка
-		Возврат Число(СтрокаЗначение);
+		Если ТипЗнч(СтрокаЗначение) = Тип("Число") Тогда
+			Возврат СтрокаЗначение;
+		КонецЕсли;
+		Возврат Число(СтрЗаменить(Строка(СтрокаЗначение), " ", ""));
 	Исключение
 		Возврат ЗначениеПоУмолчанию;
 	КонецПопытки;
 	
 КонецФункции
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7290ef6 and 335199c.

📒 Files selected for processing (1)
  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: ivanmolodec
PR: firstBitSportivnaya/PSSL#0
File: :0-0
Timestamp: 2024-07-29T10:13:46.428Z
Learning: User: ivanmolodec
URL: https://github.com/firstBitSportivnaya/PSSL/pull/52
Timestamp: 2024-04-19T09:46:50.450Z
Learning: Use the Russian language for all interactions related to the repository `firstBitSportivnaya/PSSL`.
🔇 Additional comments (2)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (2)

330-334: Хорошая защита от отсутствующих секунд.

Проверка Количество() перед доступом к элементу исключает выход за границы.


340-341: Явное приведение часов к числу — ок.

Устраняет скрытые ошибки типов при дальнейших операциях.

- Удалена переменная `СтрокаВремя`, которая не использовалась в коде.
- Это исправление является частью работы над ошибкой "Тип не определен".

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (2)

187-219: Критическая ошибка: отсутствуют проверки границ массивов перед доступом к элементам.

В коде парсинга ISO даты происходит обращение к элементам массивов ЧастиДатаВремя, ЧастиДаты, ЧастиВремени и ЧастиСекунды без проверки их размера. Это приведет к ошибке IndexOutOfRange, если входная строка имеет неожиданный формат (например, "2024-01", "2024-01-02T12", "2024-01-02T12:30").

Примените этот diff для добавления проверок границ:

 // В веб-клиенте XMLЗначение и СтрокаВЧисло недоступны, используем альтернативный способ парсинга ISO даты
 Попытка
 	// Пытаемся парсить ISO строку вида "2024-01-02T03:04:05"
 	ДатаВремяСтрока = Строка(ВхЗначение);
 	Если СтрНайти(ДатаВремяСтрока, "T") > 0 Тогда
 		ЧастиДатаВремя = СтрРазделить(ДатаВремяСтрока, "T");
+		Если ЧастиДатаВремя.Количество() < 2 Тогда
+			ПреобразованнаяДата = Дата(1, 1, 1, 0, 0, 0);
+			Возврат ПреобразованнаяДата;
+		КонецЕсли;
+		
 		ЧастиДаты = СтрРазделить(ЧастиДатаВремя[0], "-");
+		Если ЧастиДаты.Количество() < 3 Тогда
+			ПреобразованнаяДата = Дата(1, 1, 1, 0, 0, 0);
+			Возврат ПреобразованнаяДата;
+		КонецЕсли;
+		
 		ЧастиВремени = СтрРазделить(ЧастиДатаВремя[1], ":");
+		Если ЧастиВремени.Количество() < 3 Тогда
+			ПреобразованнаяДата = Дата(1, 1, 1, 0, 0, 0);
+			Возврат ПреобразованнаяДата;
+		КонецЕсли;
 		
 		// Используем безопасное преобразование для веб-клиента
 		Год = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[0], 1);
 		Месяц = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[1], 1);
 		День = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[2], 1);
 		
 		Часы = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[0], 0);
 		Минуты = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[1], 0);
 		
 		// Обрабатываем секунды (могут быть с миллисекундами)
 		СекундыСтрока = ЧастиВремени[2];
 		Если СтрНайти(СекундыСтрока, ".") > 0 Тогда
 			ЧастиСекунды = СтрРазделить(СекундыСтрока, ".");
+			Если ЧастиСекунды.Количество() > 0 Тогда
 				Секунды = БезопасноПреобразоватьСтрокуВЧисло(ЧастиСекунды[0], 0);
+			Иначе
+				Секунды = 0;
+			КонецЕсли;
 		Иначе
 			Секунды = БезопасноПреобразоватьСтрокуВЧисло(СекундыСтрока, 0);
 		КонецЕсли;

175-185: Критическая ошибка: усечение по первой точке повреждает даты с разделителем-точкой.

Текущая логика находит первую точку во всей строке и усекает по ней. Это некорректно обрабатывает даты формата dd.MM.yyyy (например, строка "31.12.2024T12:30:45.123" будет усечена до "31"). Усечение должно применяться только к дробным секундам и суффиксам часового пояса после разделителя "T".

Примените этот diff для корректного усечения только миллисекунд и суффиксов часового пояса:

 Попытка
 	СтрокаДаты = Строка(ВхЗначение);
-	ПозицияТочки = СтрНайти(СтрокаДаты, ".");
-	Если ПозицияТочки > 0 Тогда
-		// Отсекаем миллисекунды, т.к. XMLЗначение их не поддерживает
-		СтрокаДаты = Лев(СтрокаДаты, ПозицияТочки - 1);
-	КонецЕсли;
+	ПозицияT = СтрНайти(СтрокаДаты, "T");
+	Если ПозицияT > 0 Тогда
+		// Ищем спец-символы только в части времени
+		ПозицияТочки = СтрНайти(СтрокаДаты, ".", ПозицияT);
+		ПозицияZ = СтрНайти(СтрокаДаты, "Z", ПозицияT);
+		ПозицияПлюс = СтрНайти(СтрокаДаты, "+", ПозицияT);
+		ПозицияМинус = СтрНайти(СтрокаДаты, "-", ПозицияT);
+		
+		// Находим первый встреченный спец-символ
+		ПозицияСреза = 0;
+		Если ПозицияТочки > 0 И (ПозицияСреза = 0 Или ПозицияТочки < ПозицияСреза) Тогда
+			ПозицияСреза = ПозицияТочки;
+		КонецЕсли;
+		Если ПозицияZ > 0 И (ПозицияСреза = 0 Или ПозицияZ < ПозицияСреза) Тогда
+			ПозицияСреза = ПозицияZ;
+		КонецЕсли;
+		Если ПозицияПлюс > 0 И (ПозицияСреза = 0 Или ПозицияПлюс < ПозицияСреза) Тогда
+			ПозицияСреза = ПозицияПлюс;
+		КонецЕсли;
+		Если ПозицияМинус > 0 И (ПозицияСреза = 0 Или ПозицияМинус < ПозицияСреза) Тогда
+			ПозицияСреза = ПозицияМинус;
+		КонецЕсли;
+		
+		Если ПозицияСреза > 0 Тогда
+			// Отсекаем дробные секунды и часовой пояс
+			СтрокаДаты = Лев(СтрокаДаты, ПозицияСреза - 1);
+		КонецЕсли;
+	КонецЕсли;
 	ПреобразованнаяДата = XMLЗначение(Тип("Дата"), СтрокаДаты);
🧹 Nitpick comments (1)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (1)

358-367: Отличная утилита: безопасное преобразование строк в числа.

Функция БезопасноПреобразоватьСтрокуВЧисло корректно обрабатывает исключения при преобразовании и возвращает значение по умолчанию, что предотвращает сбои при некорректных данных. Реализация подходит для использования в веб-клиенте, где СтрокаВЧисло недоступна.

Для улучшения документации можно добавить JSDoc-комментарий:

+// Безопасное преобразование строки в число для веб-клиента
+//
+// Параметры:
+//  СтрокаЗначение      - Строка - Преобразуемая строка
+//  ЗначениеПоУмолчанию - Число  - Значение, возвращаемое при ошибке (по умолчанию 0)
+//
+// Возвращаемое значение:
+//  Число - Преобразованное число или значение по умолчанию
+//
-// Безопасное преобразование строки в число для веб-клиента
 Функция БезопасноПреобразоватьСтрокуВЧисло(СтрокаЗначение, ЗначениеПоУмолчанию = 0)
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 335199c and c099c45.

📒 Files selected for processing (1)
  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: ivanmolodec
PR: firstBitSportivnaya/PSSL#0
File: :0-0
Timestamp: 2024-07-29T10:13:46.428Z
Learning: User: ivanmolodec
URL: https://github.com/firstBitSportivnaya/PSSL/pull/52
Timestamp: 2024-04-19T09:46:50.450Z
Learning: Use the Russian language for all interactions related to the repository `firstBitSportivnaya/PSSL`.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (3)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (3)

222-222: Хорошая защита: инициализация переменной.

Инициализация Часы = 0 в ветке Иначе предотвращает использование неинициализированной переменной и гарантирует корректную работу кода в строках 262, 339.


329-333: Отличная защита: проверка границ массива.

Проверка МассивСекМин.Количество() > 1 перед обращением к элементу [1] корректно предотвращает ошибку IndexOutOfRange и использует безопасное значение по умолчанию СекундыЧисло = 0.


339-339: Хорошая практика: явное преобразование типа.

Явное преобразование ЧасыЧисло = Число(Часы) улучшает читаемость кода и обеспечивает единообразие с обработкой МинутыЧисло и СекундыЧисло.

…рмату (#339)

Функция `ПреобразоватьДатуИзСтрокиПоФормату` была полностью переписана с целью упрощения и повышения надежности.

Ключевые изменения:
- **Упрощена логика**: Вместо сложной и запутанной структуры, новая реализация последовательно и предсказуемо парсит дату и время.
- **Обернуто в Попытку**: Вся логика преобразования обернута в единый блок `Попытка-Исключение` для надежной обработки любых ошибок.
- **Гарантированная инициализация**: Все переменные (`Год`, `Месяц`, `День`, `Часы` и т.д.) теперь инициализируются в начале, что исключает ошибки `Тип не определен`.
- **Надежный парсинг**: Логика парсинга даты и времени была унифицирована и сделана более устойчивой к некорректным входным данным.
- **Удалены ненужные функции**: Вспомогательная функция `ПолучитьТолькоДатуЕслиРазделительПробел` была удалена за ненадобностью.

Эти изменения должны окончательно решить все проблемы с преобразованием дат и сделать код более поддерживаемым.
Исправлена синтаксическая ошибка в функции `ПреобразоватьДатуИзСтрокиПоФормату`. Несуществующая функция `Врех` была заменена на правильную `ВРег` для приведения строки к верхнему регистру при проверке на `AM/PM`.

Эта ошибка приводила к невозможности компиляции модуля и, как следствие, к непрохождению юнит-тестов.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e39869 and f52041d.

📒 Files selected for processing (1)
  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: ivanmolodec
PR: firstBitSportivnaya/PSSL#0
File: :0-0
Timestamp: 2024-07-29T10:13:46.428Z
Learning: User: ivanmolodec
URL: https://github.com/firstBitSportivnaya/PSSL/pull/52
Timestamp: 2024-04-19T09:46:50.450Z
Learning: Use the Russian language for all interactions related to the repository `firstBitSportivnaya/PSSL`.
📚 Learning: 2024-12-12T15:04:03.415Z
Learnt from: denisushakov
PR: firstBitSportivnaya/PSSL#163
File: src/cf/CommonModules/пбп_ПредопределенныеЗначенияСлужебный/Ext/Module.bsl:375-411
Timestamp: 2024-12-12T15:04:03.415Z
Learning: В процедуре `ОбработатьДублиИдентификаторов` в файле `src/cf/CommonModules/пбп_ПредопределенныеЗначенияСлужебный/Ext/Module.bsl` допустимо удалять строки из `ТаблицаПредопределенных` внутри цикла, если перебор осуществляется по массиву строк для удаления, а не по самой таблице.

Applied to files:

  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl
📚 Learning: 2025-04-09T16:04:00.903Z
Learnt from: thvvmas
PR: firstBitSportivnaya/PSSL#247
File: src/cf/DataProcessors/пбп_УниверсальнаяЗагрузкаИзФайлаЧерезТабличныйДокумент/Forms/Форма/Ext/Form/Module.bsl:430-439
Timestamp: 2025-04-09T16:04:00.903Z
Learning: В коде проекта PSSL процедура пбп_Переадресация.ЗапуститьПрограмму содержит проверку выполнения запускаемых внешних команд, поэтому нет необходимости добавлять дополнительную проверку при её вызове.

Applied to files:

  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot

- Гарантирована инициализация переменной `ПреобразованнаяДата` в ветке для веб-клиента.
- Упрощена и исправлена логика определения компонентов даты.
- Удалены лишние проверки и код, приводивший к ошибке `Тип не определен`.

Это изменение должно окончательно решить проблему с падением тестов и обеспечить стабильную работу функции преобразования дат.
- Восстановлена первоначальная, более простая структура функции `ПреобразоватьДатуИзСтрокиПоФормату`, отменив неудачный рефакторинг.
- Реализовано оригинальное предложение из issue для корректной обработки времени с секундами.
- Добавлены проверки на всех этапах парсинга и безопасное преобразование в числа, чтобы избежать ошибок `Тип не определен` и падений на некорректных данных.
- Весь сложный парсинг обернут в `Попытка`, чтобы гарантировать возврат значения по умолчанию в случае ошибки.

Этот коммит отменяет предыдущие сложные изменения и реализует простое и надежное решение, которое должно окончательно закрыть issue.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (3)

173-183: Обрезка по первой точке ломает форматы дат с точками-разделителями.

Поиск точки идёт с начала строки (строка 175), что приведёт к некорректной обрезке дат вида 15.10.2024T12:30:45.123 — отсечётся на первой точке в дате. Необходимо ограничить поиск специальных символов (точка, Z, ±) только частью после разделителя T.

Примените этот diff для исправления:

-			ПозицияТочки = СтрНайти(СтрокаДаты, ".");
-			Если ПозицияТочки > 0 Тогда
-				// Отсекаем миллисекунды, т.к. XMLЗначение их не поддерживает
-				СтрокаДаты = Лев(СтрокаДаты, ПозицияТочки - 1);
-			КонецЕсли;
+			ПозицияT = СтрНайти(СтрокаДаты, "T");
+			Если ПозицияT > 0 Тогда
+				// Ищем спец-символы только в части времени
+				ПозицияТочки = СтрНайти(СтрокаДаты, ".", , , ПозицияT);
+				ПозицияZ = СтрНайти(СтрокаДаты, "Z", , , ПозицияT);
+				ПозицияПлюс = СтрНайти(СтрокаДаты, "+", , , ПозицияT);
+				ПозицияМинус = СтрНайти(СтрокаДаты, "-", , , ПозицияT);
+				
+				ПозицияСреза = 0;
+				Для Каждого Поз Из Новый Массив Из (ПозицияТочки, ПозицияZ, ПозицияПлюс, ПозицияМинус) Цикл
+					Если Поз > 0 И (ПозицияСреза = 0 Или Поз < ПозицияСреза) Тогда
+						ПозицияСреза = Поз;
+					КонецЕсли;
+				КонецЦикла;
+				
+				Если ПозицияСреза > 0 Тогда
+					// Отсекаем дробные секунды/часовой пояс
+					СтрокаДаты = Лев(СтрокаДаты, ПозицияСреза - 1);
+				КонецЕсли;
+			КонецЕсли;

185-212: Отсутствуют проверки границ массивов перед доступом к элементам.

В коде парсинга ISO даты множественные обращения к элементам массивов без проверки их наличия:

  • Строки 191-192: доступ к ЧастиДатаВремя[0] и [1] без проверки размера
  • Строки 194-196: доступ к ЧастиДаты[0], [1], [2] без проверки
  • Строки 197-198, 200: доступ к ЧастиВремени[0], [1], [2] без проверки (особенно критично для [2] — секунды могут отсутствовать в строке вида 2025-10-29T13:45)

Это приведёт к ошибкам выхода за границы массива при неожиданных форматах входной строки.

Примените этот diff для добавления проверок:

 		// В веб-клиенте XMLЗначение недоступна, используем альтернативный способ парсинга ISO даты
+		ПреобразованнаяДата = Дата(1, 1, 1, 0, 0, 0);
 		Попытка
 			ДатаВремяСтрока = Строка(ВхЗначение);
 			Если СтрНайти(ДатаВремяСтрока, "T") > 0 Тогда
 				ЧастиДатаВремя = СтрРазделить(ДатаВремяСтрока, "T");
+				Если ЧастиДатаВремя.Количество() < 2 Тогда
+					Возврат ПреобразованнаяДата;
+				КонецЕсли;
+				
 				ЧастиДаты = СтрРазделить(ЧастиДатаВремя[0], "-");
+				Если ЧастиДаты.Количество() < 3 Тогда
+					Возврат ПреобразованнаяДата;
+				КонецЕсли;
+				
 				ЧастиВремени = СтрРазделить(ЧастиДатаВремя[1], ":");
+				Если ЧастиВремени.Количество() < 2 Тогда
+					Возврат ПреобразованнаяДата;
+				КонецЕсли;
 				
 				Год = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[0], 1);
 				Месяц = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[1], 1);
 				День = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[2], 1);
 				Часы = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[0], 0);
 				Минуты = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[1], 0);
 				
-				СекундыСтрока = ЧастиВремени[2];
-				Если СтрНайти(СекундыСтрока, ".") > 0 Тогда
-					ЧастиСекунды = СтрРазделить(СекундыСтрока, ".");
-					Секунды = БезопасноПреобразоватьСтрокуВЧисло(ЧастиСекунды[0], 0);
-				Иначе
-					Секунды = БезопасноПреобразоватьСтрокуВЧисло(СекундыСтрока, 0);
-				КонецЕсли;
+				// Обрабатываем секунды (могут отсутствовать)
+				Секунды = 0;
+				Если ЧастиВремени.Количество() > 2 Тогда
+					СекундыСтрока = ЧастиВремени[2];
+					Если СтрНайти(СекундыСтрока, ".") > 0 Тогда
+						ЧастиСекунды = СтрРазделить(СекундыСтрока, ".");
+						Если ЧастиСекунды.Количество() > 0 Тогда
+							Секунды = БезопасноПреобразоватьСтрокуВЧисло(ЧастиСекунды[0], 0);
+						КонецЕсли;
+					Иначе
+						Секунды = БезопасноПреобразоватьСтрокуВЧисло(СекундыСтрока, 0);
+					КонецЕсли;
+				КонецЕсли;

235-239: Добавьте проверку перед доступом к МассивРазделителей[1].

Условие на строке 235 проверяет только случай Количество() = 3, но в ветке Иначе (строка 238) происходит безусловный доступ к МассивРазделителей[1]. Если массив содержит только 1 элемент, возникнет ошибка выхода за границы массива.

Примените этот diff:

 			Если РазрядыФормата[1] = "1" Тогда
 				Часы = МассивРазделителейДатаВремя[МассивРазделителейДатаВремя.Количество() - 1];
 				Если МассивРазделителей.Количество() = 3 Тогда
 					МинутыСекунды = МассивРазделителей[1] + ":" + МассивРазделителей[2];
-				Иначе
+				ИначеЕсли МассивРазделителей.Количество() >= 2 Тогда
 					МинутыСекунды = МассивРазделителей[1];
+				Иначе
+					МинутыСекунды = "00:00";
 				КонецЕсли;
🧹 Nitpick comments (1)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (1)

359-379: Хорошее добавление безопасного преобразования, но стоит пересмотреть размещение.

Функция БезопасноПреобразоватьСтрокуВЧисло (строки 371-379) корректно реализована и экспортируется, что делает её частью публичного API. Однако она размещена в области #Область СлужебныеПроцедурыИФункции, что предполагает внутреннее использование.

Рассмотрите возможность перемещения экспортируемой функции в область #Область ПрограммныйИнтерфейс для соответствия организационной структуре модуля и явного обозначения публичного API.

Вспомогательная функция ПолучитьТолькоДатуЕслиРазделительПробел (строки 359-368) правильно размещена как служебная.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 17ca82f and 3e52f81.

📒 Files selected for processing (1)
  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (7 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: ivanmolodec
PR: firstBitSportivnaya/PSSL#0
File: :0-0
Timestamp: 2024-07-29T10:13:46.428Z
Learning: User: ivanmolodec
URL: https://github.com/firstBitSportivnaya/PSSL/pull/52
Timestamp: 2024-04-19T09:46:50.450Z
Learning: Use the Russian language for all interactions related to the repository `firstBitSportivnaya/PSSL`.
📚 Learning: 2025-08-08T12:38:08.400Z
Learnt from: thvvmas
PR: firstBitSportivnaya/PSSL#327
File: src/cf/EventSubscriptions/пбп_РегистрыСведенийПриЗаписи.xml:17-17
Timestamp: 2025-08-08T12:38:08.400Z
Learning: В PR firstBitSportivnaya/PSSL#327 общий модуль src/cf/CommonModules/пбп_ОбработкаСобытий/Ext/Module.bsl присутствует и содержит экспортную процедуру ПриЗаписи(Источник, Отказ, Параметр3 = Неопределено, Параметр4 = Неопределено, Параметр5 = Неопределено, Параметр6 = Неопределено); использование её в подписке src/cf/EventSubscriptions/пбп_РегистрыСведенийПриЗаписи.xml корректно.

Applied to files:

  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl
📚 Learning: 2024-12-12T15:04:03.415Z
Learnt from: denisushakov
PR: firstBitSportivnaya/PSSL#163
File: src/cf/CommonModules/пбп_ПредопределенныеЗначенияСлужебный/Ext/Module.bsl:375-411
Timestamp: 2024-12-12T15:04:03.415Z
Learning: В процедуре `ОбработатьДублиИдентификаторов` в файле `src/cf/CommonModules/пбп_ПредопределенныеЗначенияСлужебный/Ext/Module.bsl` допустимо удалять строки из `ТаблицаПредопределенных` внутри цикла, если перебор осуществляется по массиву строк для удаления, а не по самой таблице.

Applied to files:

  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl
📚 Learning: 2025-08-08T12:05:06.019Z
Learnt from: thvvmas
PR: firstBitSportivnaya/PSSL#327
File: src/cf/CommonModules/пбп_ЗадачиОбработкаСобытий/Ext/Module.bsl:24-30
Timestamp: 2025-08-08T12:05:06.019Z
Learning: Модуль BSL src/cf/CommonModules/пбп_ЗадачиОбработкаСобытий/Ext/Module.bsl в репозитории firstBitSportivnaya/PSSL является каркасом для будущих модификаций; на текущем этапе он намеренно пуст и не подлежит изменению/удалению. Подтверждено пользователем thvvmas в PR #327.

Applied to files:

  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl
📚 Learning: 2025-08-08T12:46:43.559Z
Learnt from: thvvmas
PR: firstBitSportivnaya/PSSL#327
File: src/cf/CommonModules/пбп_ОбработкаСобытий/Ext/Module.bsl:137-140
Timestamp: 2025-08-08T12:46:43.559Z
Learning: В репозитории firstBitSportivnaya/PSSL (PR #327) принято правило: для событий ПередЗаписью/ПриЗаписи/ПередУдалением источники подписок не являются типами менеджеров (CatalogManager, DocumentManager и т.п.). Подписки создаются для объектов, наборов записей и КонстантаМенеджерЗначения, где доступно свойство ОбменДанными. Следовательно, в файле src/cf/CommonModules/пбп_ОбработкаСобытий/Ext/Module.bsl допустима прямая проверка Источник.ОбменДанными.Загрузка без дополнительной проверки наличия свойства.

Applied to files:

  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl
📚 Learning: 2025-04-09T16:04:00.903Z
Learnt from: thvvmas
PR: firstBitSportivnaya/PSSL#247
File: src/cf/DataProcessors/пбп_УниверсальнаяЗагрузкаИзФайлаЧерезТабличныйДокумент/Forms/Форма/Ext/Form/Module.bsl:430-439
Timestamp: 2025-04-09T16:04:00.903Z
Learning: В коде проекта PSSL процедура пбп_Переадресация.ЗапуститьПрограмму содержит проверку выполнения запускаемых внешних команд, поэтому нет необходимости добавлять дополнительную проверку при её вызове.

Applied to files:

  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (1)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (1)

272-276: Отличная работа с защитой от граничных случаев!

Добавленные проверки границ массивов (строки 272-276, 298-301, 326-330) и блок try-catch для конструктора даты (строки 338-342) значительно повышают надёжность функции и предотвращают ошибки при некорректных входных данных.

Also applies to: 298-301, 326-330, 338-342

- Добавлена проверка на пустой `НомерФормата`, чтобы избежать ошибки "Индекс находится за границами массива".
- Добавлена проверка на `Неопределено` после `XMLЗначение` для устранения ошибки "Тип не определен".
- Вспомогательная функция `ПолучитьТолькоДатуЕслиРазделительПробел` сделана экспортной согласно требованию.
Внесены изменения в логику серверного парсинга ISO-дат, чтобы гарантировать возврат значения типа `Дата` и исключить `Неопределено`. Переменная `ПреобразованнаяДата` теперь инициализируется значением по умолчанию в начале блока `Попытка`.
Инициализирую `ПреобразованнаяДата` значением по умолчанию в самом начале функции, чтобы гарантировать возврат корректного типа данных.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (1)

243-255: КРИТИЧЕСКАЯ ОШИБКА: Использование неинициализированной переменной МинутыСекунды.

В ветке Иначе (строки 243-255) код использует переменную МинутыСекунды на строках 247, 253 и 254, но эта переменная устанавливается только в ветке Если (строки 239, 241). В ветке Иначе переменная остаётся пустой строкой (инициализация на строке 221), что делает логику обработки AM/PM (строки 247-254) нерабочей.

Похоже, что в этой ветке отсутствует код установки МинутыСекунды из элементов МассивРазделителей.

Требуется установить МинутыСекунды перед использованием. Например:

 			Иначе
+				// Устанавливаем МинутыСекунды из оставшихся частей
+				Если МассивРазделителей.Количество() = 3 Тогда
+					МинутыСекунды = МассивРазделителей[1] + ":" + МассивРазделителей[2];
+				ИначеЕсли МассивРазделителей.Количество() >= 2 Тогда
+					МинутыСекунды = МассивРазделителей[1];
+				Иначе
+					МинутыСекунды = "00:00";
+				КонецЕсли;
+				
 				ЧасыБезСдвигаЧисло = БезопасноПреобразоватьСтрокуВЧисло(МассивРазделителейДатаВремя[МассивРазделителейДатаВремя.Количество() - 1]);
♻️ Duplicate comments (2)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (2)

189-215: КРИТИЧЕСКАЯ ОШИБКА: Отсутствуют проверки границ массивов перед доступом к элементам.

Код напрямую обращается к элементам массивов без проверки их размера, что приведёт к ошибке выхода за границы массива:

  • Строка 193: ЧастиДатаВремя[0] и строка 195: ЧастиДатаВремя[1] - нет проверки, что массив содержит минимум 2 элемента
  • Строки 194-199: ЧастиДаты[0], [1], [2] - нет проверки на 3 элемента
  • Строки 200-201, 203: ЧастиВремени[0], [1], [2] - нет проверки на 3 элемента (особенно критично для строк без секунд, например "2025-10-29T13:45")

Примените исправление:

 		// В веб-клиенте XMLЗначение недоступна, используем альтернативный способ парсинга ISO даты
 		Попытка
 			ДатаВремяСтрока = Строка(ВхЗначение);
 			Если СтрНайти(ДатаВремяСтрока, "T") > 0 Тогда
 				ЧастиДатаВремя = СтрРазделить(ДатаВремяСтрока, "T");
+				Если ЧастиДатаВремя.Количество() < 2 Тогда
+					ПреобразованнаяДата = Дата(1, 1, 1, 0, 0, 0);
+					Возврат ПреобразованнаяДата;
+				КонецЕсли;
 				ЧастиДаты = СтрРазделить(ЧастиДатаВремя[0], "-");
+				Если ЧастиДаты.Количество() < 3 Тогда
+					ПреобразованнаяДата = Дата(1, 1, 1, 0, 0, 0);
+					Возврат ПреобразованнаяДата;
+				КонецЕсли;
 				ЧастиВремени = СтрРазделить(ЧастиДатаВремя[1], ":");
+				Если ЧастиВремени.Количество() < 2 Тогда
+					ПреобразованнаяДата = Дата(1, 1, 1, 0, 0, 0);
+					Возврат ПреобразованнаяДата;
+				КонецЕсли;
 				
 				Год = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[0], 1);
 				Месяц = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[1], 1);
 				День = БезопасноПреобразоватьСтрокуВЧисло(ЧастиДаты[2], 1);
 				Часы = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[0], 0);
 				Минуты = БезопасноПреобразоватьСтрокуВЧисло(ЧастиВремени[1], 0);
 				
-				СекундыСтрока = ЧастиВремени[2];
-				Если СтрНайти(СекундыСтрока, ".") > 0 Тогда
-					ЧастиСекунды = СтрРазделить(СекундыСтрока, ".");
-					Секунды = БезопасноПреобразоватьСтрокуВЧисло(ЧастиСекунды[0], 0);
-				Иначе
-					Секунды = БезопасноПреобразоватьСтрокуВЧисло(СекундыСтрока, 0);
-				КонецЕсли;
+				Секунды = 0;
+				Если ЧастиВремени.Количество() > 2 Тогда
+					СекундыСтрока = ЧастиВремени[2];
+					Если СтрНайти(СекундыСтрока, ".") > 0 Тогда
+						ЧастиСекунды = СтрРазделить(СекундыСтрока, ".");
+						Если ЧастиСекунды.Количество() > 0 Тогда
+							Секунды = БезопасноПреобразоватьСтрокуВЧисло(ЧастиСекунды[0], 0);
+						КонецЕсли;
+					Иначе
+						Секунды = БезопасноПреобразоватьСтрокуВЧисло(СекундыСтрока, 0);
+					КонецЕсли;
+				КонецЕсли;

238-242: КРИТИЧЕСКАЯ ОШИБКА: Небезопасный доступ к элементу массива в ветке Иначе.

Проверка на строке 238 требует ровно 3 элемента (Количество() = 3), но в ветке Иначе (строка 241) происходит обращение к МассивРазделителей[1] без гарантии, что массив содержит хотя бы 2 элемента. Если массив содержит только 1 элемент, произойдёт ошибка выхода за границы массива.

Примените исправление:

 			Если РазрядыФормата[1] = "1" Тогда
 				Часы = МассивРазделителейДатаВремя[МассивРазделителейДатаВремя.Количество() - 1];
 				Если МассивРазделителей.Количество() = 3 Тогда
 					МинутыСекунды = МассивРазделителей[1] + ":" + МассивРазделителей[2];
-				Иначе
+				ИначеЕсли МассивРазделителей.Количество() >= 2 Тогда
 					МинутыСекунды = МассивРазделителей[1];
+				Иначе
+					МинутыСекунды = "00:00";
 				КонецЕсли;
🧹 Nitpick comments (2)
src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (2)

171-187: Рассмотрите более надёжную обработку миллисекунд и часовых поясов в ISO-строках.

Текущая логика обрезает строку по первой точке, что работает для простых случаев, но не обрабатывает суффиксы часовых поясов (Z, +03:00, -05:00). Для более корректной работы с различными вариантами ISO 8601 рекомендуется:

  • Искать точку только после разделителя "T"
  • Дополнительно удалять суффиксы часовых поясов перед передачей в XMLЗначение

Можно применить улучшенный вариант:

-			ПозицияТочки = СтрНайти(СтрокаДаты, ".");
-			Если ПозицияТочки > 0 Тогда
-				// Отсекаем миллисекунды, т.к. XMLЗначение их не поддерживает
-				СтрокаДаты = Лев(СтрокаДаты, ПозицияТочки - 1);
-			КонецЕсли;
+			ПозицияT = СтрНайти(СтрокаДаты, "T");
+			Если ПозицияT > 0 Тогда
+				// Ищем спец-символы только в части времени
+				ПозицияТочки = СтрНайти(СтрокаДаты, ".", ПозицияT);
+				Если ПозицияТочки > 0 Тогда
+					СтрокаДаты = Лев(СтрокаДаты, ПозицияТочки - 1);
+				КонецЕсли;
+				// Удаляем суффиксы часовых поясов Z, +HH:MM, -HH:MM
+				СтрокаДаты = СтрЗаменить(СтрокаДаты, "Z", "");
+				ПозицияПлюс = СтрНайти(СтрокаДаты, "+", ПозицияT);
+				Если ПозицияПлюс > 0 Тогда
+					СтрокаДаты = Лев(СтрокаДаты, ПозицияПлюс - 1);
+				КонецЕсли;
+				ПозицияМинус = СтрНайти(СтрокаДаты, "-", ПозицияT + 1);
+				Если ПозицияМинус > 0 Тогда
+					СтрокаДаты = Лев(СтрокаДаты, ПозицияМинус - 1);
+				КонецЕсли;
+			КонецЕсли;

374-382: Уточните использование Число() вместо СтрокаВЧисло() и видимость функции.

Функция использует Число() для преобразования, что может работать иначе, чем традиционная СтрокаВЧисло() (например, в обработке пробелов или локализованных форматов). Также функция помечена как Экспорт в области служебных функций.

Рассмотрите:

  1. Использование Число(СтрЗаменить(СтрокаЗначение, " ", "")) для явной очистки пробелов
  2. Удаление модификатора Экспорт, если функция используется только внутри модуля
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d45491 and c56e998.

📒 Files selected for processing (1)
  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl (6 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: ivanmolodec
Repo: firstBitSportivnaya/PSSL PR: 0
File: :0-0
Timestamp: 2024-07-29T10:13:46.428Z
Learning: User: ivanmolodec
URL: https://github.com/firstBitSportivnaya/PSSL/pull/52
Timestamp: 2024-04-19T09:46:50.450Z
Learning: Use the Russian language for all interactions related to the repository `firstBitSportivnaya/PSSL`.
Learnt from: thvvmas
Repo: firstBitSportivnaya/PSSL PR: 327
File: src/cf/CommonModules/пбп_ЗадачиОбработкаСобытий/Ext/Module.bsl:24-30
Timestamp: 2025-08-08T12:05:06.019Z
Learning: Модуль BSL src/cf/CommonModules/пбп_ЗадачиОбработкаСобытий/Ext/Module.bsl в репозитории firstBitSportivnaya/PSSL является каркасом для будущих модификаций; на текущем этапе он намеренно пуст и не подлежит изменению/удалению. Подтверждено пользователем thvvmas в PR #327.
📚 Learning: 2024-12-12T15:04:03.415Z
Learnt from: denisushakov
Repo: firstBitSportivnaya/PSSL PR: 163
File: src/cf/CommonModules/пбп_ПредопределенныеЗначенияСлужебный/Ext/Module.bsl:375-411
Timestamp: 2024-12-12T15:04:03.415Z
Learning: В процедуре `ОбработатьДублиИдентификаторов` в файле `src/cf/CommonModules/пбп_ПредопределенныеЗначенияСлужебный/Ext/Module.bsl` допустимо удалять строки из `ТаблицаПредопределенных` внутри цикла, если перебор осуществляется по массиву строк для удаления, а не по самой таблице.

Applied to files:

  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl
📚 Learning: 2025-08-08T12:05:06.019Z
Learnt from: thvvmas
Repo: firstBitSportivnaya/PSSL PR: 327
File: src/cf/CommonModules/пбп_ЗадачиОбработкаСобытий/Ext/Module.bsl:24-30
Timestamp: 2025-08-08T12:05:06.019Z
Learning: Модуль BSL src/cf/CommonModules/пбп_ЗадачиОбработкаСобытий/Ext/Module.bsl в репозитории firstBitSportivnaya/PSSL является каркасом для будущих модификаций; на текущем этапе он намеренно пуст и не подлежит изменению/удалению. Подтверждено пользователем thvvmas в PR #327.

Applied to files:

  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl
📚 Learning: 2025-08-08T12:46:43.559Z
Learnt from: thvvmas
Repo: firstBitSportivnaya/PSSL PR: 327
File: src/cf/CommonModules/пбп_ОбработкаСобытий/Ext/Module.bsl:137-140
Timestamp: 2025-08-08T12:46:43.559Z
Learning: В репозитории firstBitSportivnaya/PSSL (PR #327) принято правило: для событий ПередЗаписью/ПриЗаписи/ПередУдалением источники подписок не являются типами менеджеров (CatalogManager, DocumentManager и т.п.). Подписки создаются для объектов, наборов записей и КонстантаМенеджерЗначения, где доступно свойство ОбменДанными. Следовательно, в файле src/cf/CommonModules/пбп_ОбработкаСобытий/Ext/Module.bsl допустима прямая проверка Источник.ОбменДанными.Загрузка без дополнительной проверки наличия свойства.

Applied to files:

  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl
📚 Learning: 2025-04-09T16:04:00.903Z
Learnt from: thvvmas
Repo: firstBitSportivnaya/PSSL PR: 247
File: src/cf/DataProcessors/пбп_УниверсальнаяЗагрузкаИзФайлаЧерезТабличныйДокумент/Forms/Форма/Ext/Form/Module.bsl:430-439
Timestamp: 2025-04-09T16:04:00.903Z
Learning: В коде проекта PSSL процедура пбп_Переадресация.ЗапуститьПрограмму содержит проверку выполнения запускаемых внешних команд, поэтому нет необходимости добавлять дополнительную проверку при её вызове.

Applied to files:

  • src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot

Comment on lines 362 to 371

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Добавьте проверку размера массива и уточните видимость функции.

Функция перебирает элементы до Количество() - 2, что вызовет ошибку, если массив содержит менее 2 элементов. Также функция помечена как Экспорт в области служебных функций, что необычно — служебные функции обычно не экспортируются.

Примените исправление:

 Функция ПолучитьТолькоДатуЕслиРазделительПробел(МассивРазделителейДатаВремя) Экспорт
 	
+	Если МассивРазделителейДатаВремя.Количество() < 2 Тогда
+		Возврат "";
+	КонецЕсли;
+	
 	ТолькоДата = "";
 	Для Счетчик = 0 По МассивРазделителейДатаВремя.Количество() - 2 Цикл

Также рассмотрите возможность удаления модификатора Экспорт, если функция предназначена только для внутреннего использования модулем.

🤖 Prompt for AI Agents
In src/cf/CommonModules/пбп_СтроковыеФункцииКлиентСервер/Ext/Module.bsl around
lines 362-371, the function currently loops to
МассивРазделителейДатаВремя.Количество() - 2 which will throw when the array has
fewer than 2 elements and the function is marked Экспорт though it appears to be
an internal helper. Add a defensive size check at the start (if Количество() < 2
then return "" or appropriate default) and keep the loop bounds safe, and remove
the Экспорт modifier if the function is intended for internal use (or explicitly
document/keep Экспорт only if it must be publicly visible).

@sonar-openbsl-ru-qa-bot

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Общие Кросс-подсистемные изменения

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Исправить ошибку преобразования времени в ОМ пбп_СтроковыеФункцииКлиентСервер

1 participant