Работа над ошибками. С датой

У одного клиента спустя какое-то время стали загружаться не все даты из Excel.

Беглый анализ показал, что всему виной функция преобразования даты и времени из строки.

Вот ее код:

Функция СтрокаДаты_ДД_ММ_ГГГГ_ЧЧ_ММ_СС_ВДату(Строка)
    //Примеры: 2012-06-21 22:30:25 или 2012-06-21 22:30
	Попытка
		Д = Число(Сред(Строка, 1, 2));
		М = Число(Сред(Строка, 4, 2));
		Г = Число(Сред(Строка, 7, 4));
		ЧЧ = Число(Сред(Строка, 12, 2));
		ММ = Число(Сред(Строка, 15, 2));
		Попытка
			СС = Число(Сред(Строка, 18, 2));
		Исключение
			СС = 0; //Если секунд нет
		КонецПопытки;
		Возврат Дата(Г, М, Д, ЧЧ, ММ, СС);
	Исключение
	КонецПопытки;    
КонецФункции  

Видно, что функция не работала если количество часов содержит одну, а не две цифры. К ним начали попадать данные из точек, работающих с 9 утра и всё сломалось. Хотя раньше работало, потому что точки открывались в 10.

Пришлось поправить, привлек ИИ к этой задаче:

Функция СтрокаДаты_ДД_ММ_ГГГГ_ЧЧ_ММ_СС_ВДату(Строка)
    // Примеры: 2012-06-21 22:30:25 или 2012-06-21 9:30 или 2012-06-21 09:30  
	//Работает и с короткой датой 9:30
    Попытка
        Д = Число(Сред(Строка, 1, 2));
        М = Число(Сред(Строка, 4, 2));
        Г = Число(Сред(Строка, 7, 4));
        
        // Извлекаем время
        ВремяСтрока = Сред(Строка, 12);
        ЧЧ = 0;
        ММ = 0;
        СС = 0;

        // Проверяем наличие времени
        Если Найти(" ", ВремяСтрока) > 0 Тогда
            ВремяСтрока = Сред(ВремяСтрока, 1, Найти(" ", ВремяСтрока) - 1);
        КонецЕсли;

        // Разделяем время на часы, минуты и секунды
        ЧастиВремени = СтрРазделить(ВремяСтрока, ":");
        
        ЧЧ = Число(ЧастиВремени[0]);  
		
        Если ЧастиВремени.Количество() > 1 Тогда
            ММ = Число(ЧастиВремени[1]);
        КонецЕсли;
        
        Если ЧастиВремени.Количество() > 2 Тогда
            СС = Число(ЧастиВремени[2]);
			//Если СС = 0 Тогда СС = 1; КонецЕсли;
        КонецЕсли;

        Возврат Дата(Г, М, Д, ЧЧ, ММ, СС);
	Исключение 
    КонецПопытки;    
КонецФункции

Кстати, комментарии с примерами неправильные, формат именно ДД.ММ.ГГГГ.

Но в целом результат не нравится. Хочется чтобы она любые разделители воспринимала. Озадачил ИИ и она решила элегантно путем замены не цифровых символов на пробелы. С моими подсказками получился код:

Функция ИзвлечьДатаВремя(Знач Строка) Экспорт
    ДатаВремя = Неопределено;
    
    // Заменяем все нецифровые символы на пробел
    Для Индекс = 1 По СтрДлина(Строка) Цикл
        Символ = Сред(Строка, Индекс, 1);
        Если Символ < "0" Или Символ > "9" Тогда
            Строка = СтрЗаменить(Строка, Символ, " ");
        КонецЕсли;
    КонецЦикла;

    // Удаляем лишние пробелы
    Строка = СтрЗаменить(Строка, "  ", " ");
    Пока Найти(Строка, "  ") > 0 Цикл
        Строка = СтрЗаменить(Строка, "  ", " ");
    КонецЦикла;

    // Разбиваем строку на части
    МассивЧастей = СтрРазделить(Строка, " ");
    
    // Инициализируем переменные с нулями
    День = 0;
    Месяц = 0;
    Год = 0;
    Часы = 0;
    Минуты = 0;
    Секунды = 0;

    // Заполняем части даты и времени из массива
    Если МассивЧастей.Количество() > 0 Тогда
        День = Число(МассивЧастей[0]);
    КонецЕсли;

    Если МассивЧастей.Количество() > 1 Тогда
        Месяц = Число(МассивЧастей[1]);
    КонецЕсли;

    Если МассивЧастей.Количество() > 2 Тогда
        Год = Число(МассивЧастей[2]);
        // Если год меньше 2000, добавляем 2000
        Если Год < 2000 Тогда
            Год = Год + 2000;
        КонецЕсли;
    КонецЕсли;

    Если МассивЧастей.Количество() > 3 Тогда
        Часы = Число(МассивЧастей[3]);
    КонецЕсли;

    Если МассивЧастей.Количество() > 4 Тогда
        Минуты = Число(МассивЧастей[4]);
    КонецЕсли;

    Если МассивЧастей.Количество() > 5 Тогда
        Секунды = Число(МассивЧастей[5]);
    КонецЕсли;

    // Формируем дату и время
	Попытка
 	   ДатаВремя = Дата(Год, Месяц, День, Часы, Минуты, Секунды);
	Исключение
	КонецПопытки;

    Возврат ДатаВремя;
КонецФункции

Результаты:

Обработку можно погонять, прилагаю:

Также добавил вариант для формата год-месяц-день-часы-минуты-секунды:

Функция ИзвлечьДатаВремя(Знач Строка) Экспорт
    ДатаВремя = Неопределено;

    // Удаляем все нецифровые символы и заменяем на пробелы
    Строка = СтрЗаменить(Строка, "[^0-9]", " ");
    
    // Удаляем лишние пробелы
    Строка = СтрЗаменить(Строка, " +", " "); // Заменяем несколько пробелов на один

    // Разбиваем строку на части
    МассивЧастей = СтрРазделить(Строка, " ");
    
    // Инициализируем переменные с нулями
    Год = 0;
    Месяц = 0;
    День = 0;
    Часы = 0;
    Минуты = 0;
    Секунды = 0;

    // Заполняем части даты и времени из массива
    Если МассивЧастей.Количество() > 0 Тогда
        Год = Число(МассивЧастей[0]);
        // Если год меньше 2000, добавляем 2000
        Если Год < 2000 Тогда
            Год = Год + 2000;
        КонецЕсли;
    КонецЕсли;

    Если МассивЧастей.Количество() > 1 Тогда
        Месяц = Число(МассивЧастей[1]);
    КонецЕсли;

    Если МассивЧастей.Количество() > 2 Тогда
        День = Число(МассивЧастей[2]);
    КонецЕсли;

    Если МассивЧастей.Количество() > 3 Тогда
        Часы = Число(МассивЧастей[3]);
    КонецЕсли;

    Если МассивЧастей.Количество() > 4 Тогда
        Минуты = Число(МассивЧастей[4]);
    КонецЕсли;

    Если МассивЧастей.Количество() > 5 Тогда
        Секунды = Число(МассивЧастей[5]);
    КонецЕсли;

    // Формируем дату и время
    Попытка
        ДатаВремя = Дата(Год, Месяц, День, Часы, Минуты, Секунды);
    Исключение
        ДатаВремя = Неопределено; // В случае ошибки возвращаем Неопределено
    КонецПопытки;

    Возврат ДатаВремя;
КонецФункции
image_pdfimage_print

fixin

Программирую на 1С с 1999 года. В 1С просто Гений. В 2020 году ушел из офиса на вольные хлеба фриланса. Принимаю заказы.

Вам может также понравиться...

комментария 4

  1. Ёжик:

    Говнокод детектед
    Строка = СтрЗаменить(Строка, » «, » «);
    Пока Найти(Строка, » «) > 0 Цикл
    Строка = СтрЗаменить(Строка, » «, » «);
    КонецЦикла;

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *