Перевод string в часы и минуты - страница 3

 
Vladimir Karputov:

Напишите здесь примеры вариантов ввода времени в виде строки. Чтобы можно было точно понять, что если все они обрабатываются корректно, то функция работает правильно.

Например, так и не понял, почему штатная функция + несколько StringReplace (всего 4 строки) не в состоянии решить задачу?

 
fxsaber:

Напишите здесь примеры вариантов ввода времени в виде строки. Чтобы можно было точно понять, что если все они обрабатываются корректно, то функция работает правильно.

Например, так и не понял, почему штатная функция + несколько StringReplace (всего 4 строки) не в состоянии решить задачу?


Самый простой вариант: " s_:34". И это один из безобидных вариантов.

 
Vladimir Karputov:

Самый простой вариант: " s_:34". И это один из безобидных вариантов.


Не понял. Что функция должна выдать при такой строке "1_:34"?

 
fxsaber:

Не понял. Что функция должна выдать при такой строке "1_:34"?


Будет ошибка, так как символ "_" будет заменён на ":"

"1_:34" -> "1::34"

в итоге в строке "1::34" будет найдено два разделителя, а это ошибка.

 
Vladimir Karputov:

Будет ошибка, так как символ "_" будет заменён на ":"

Спрашиваю, что должна вернуть функция?

 
fxsaber:

Спрашиваю, что должна вернуть функция?


При входной строке "1_:34" функция

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Перевод string в часы и минуты

Vladimir Karputov, 2017.09.07 05:44


Спасибо за подсказки.

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

Шаг второй: замена "-" и "_" на корректный разделитель ":", а потом поиск разделителя ":" 

//+------------------------------------------------------------------+
//| Check HH:MM To Time                                              |
//+------------------------------------------------------------------+
bool CheckHHMMToTime(string text)
  {
   bool result=true;
//--- step 1: the number of characters must be at least 3 and not more than 5
   StringTrimRight(text);           // delete spaces to the right
   StringTrimLeft(text);            // delete spaces to the left 
   if(StringLen(text)<3 || StringLen(text)>5)
     {
      Print("Length of the text can't be less than 3 and more than 5");
      return(false);
     }
//--- step 2: search for a separator ":"
   StringReplace(text,"-",":");     // search and replacement of symbol "-"
   StringReplace(text,"_",":");     // search and replacement of symbol "_"
   int search_results=0;
   for(int i=0;i<StringLen(text);i++)
      if(text[i]==':')
         search_results++;
   if(search_results==0)
     {
      Print("Divider \":\" it isn't found");
      return(false);
     }
   if(search_results>1)
     {
      Print("More than one divider \":\" are found");
      return(false);
     }
//---
   return(result);
  }

на данной этапе (пока реализованы только два шага проверок) вернёт "false".

 
Думаю, контрпример будет сложно придумать
datetime StringToTime2( string Str )
{
  static const string Delimeter[] = {"-", "_", ".", ";", "^", "~", "!", "#", "$", ","};

  StringReplace(Str, " ", NULL);  
  
  for (int i = 0; i < ArraySize(Delimeter); i++)
    StringReplace(Str, Delimeter[i], ":");
    
  while (StringReplace(Str, "::", ":"))    
    ;
  
  int Pos = StringFind(Str, ":");
  
  if (Pos == -1)
    Pos = StringLen(Str);
  
  return((((int)StringSubstr(Str, 0, Pos) * 60 + (int)StringSubstr(Str, Pos + 1)) * 60) % (24 * 3600));
//  return(StringToTime(Str));
}

void OnStart()
{
  Print(TimeToString(StringToTime2(" 0 1 -7 0"), TIME_MINUTES));    // 02:10
  Print(TimeToString(StringToTime2(" 25 -7 0"), TIME_MINUTES));     // 02:10
  Print(TimeToString(StringToTime2(" 25 -7 0"), TIME_MINUTES));     // 02:10
  Print(TimeToString(StringToTime2(" 25 :7 03"), TIME_MINUTES));    // 12:43
  Print(TimeToString(StringToTime2("1$1"), TIME_MINUTES));          // 01:01
  Print(TimeToString(StringToTime2("0 0 0 1#0008"), TIME_MINUTES)); // 01:08
  Print(TimeToString(StringToTime2("123^456"), TIME_MINUTES));      // 10:36
  Print(TimeToString(StringToTime2("1_:34"), TIME_MINUTES));        // 01:34
  Print(TimeToString(StringToTime2("1_:34.23"), TIME_MINUTES));     // 01:34
  Print(TimeToString(StringToTime2("110"), TIME_MINUTES));          // 14:00
  Print(TimeToString(StringToTime2("110:"), TIME_MINUTES));         // 14:00
  Print(TimeToString(StringToTime2(":110"), TIME_MINUTES));         // 01:50
  Print(TimeToString(StringToTime2("1_#$2"), TIME_MINUTES));        // 01:02
  Print(TimeToString(StringToTime2(":"), TIME_MINUTES));            // 00:00
  Print(TimeToString(StringToTime2(""), TIME_MINUTES));             // 00:00
}
 
Vladimir Karputov:

Спасибо за подсказки.

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

Шаг второй: замена "-" и "_" на корректный разделитель ":", а потом поиск разделителя ":" 


1. Зачем делать раздельные функции проверки введённой строки и её преобразование в секунды ??? Не рационально ни с какого бока. Если строка совсем безнадёжна, пусть функция выдаст алерт и вернёт WRONG_VALUE, если не совсем - пусть отрихтует и вернёт секунды

2. Пробелы - обычное дело не только до/перед, но и вокруг разделителя :

3. Где вы видели время с подчёркиванием, лубопытно?

4. Если добавите финальную проверку на наличие любого символа, кроме цифр и двоеточия, это исчерпает абсолютное большинство ошибок ввода

 
Alexander Puzanov:

1. Зачем делать раздельные функции проверки введённой строки и её преобразование в секунды ??? Не рационально ни с какого бока. Если строка совсем безнадёжна, пусть функция выдаст алерт и вернёт WRONG_VALUE, если не совсем - пусть отрихтует и вернёт секунды


В секунды никто не преобразует. После всех проверок можно будет идти двумя путями: 

  • или преобразовать проверенную строку в datetime
  • или преобразовать проверенную строку в две переменные объявленные на глобальном программном уровне - часы и минуты.

Alexander Puzanov:

2. Пробелы - обычное дело не только до/перед, но и вокруг разделителя :

Пробел внутри приравнивается в ошибке ввода - если такое встретится - будет ошибка.


Alexander Puzanov:

3. Где вы видели время с подчёркиванием, лубопытно?

От пользователя можно ожидать всё, что угодно. Ничего исключать нельзя.


Alexander Puzanov:

4. Если добавите финальную проверку на наличие любого символа, кроме цифр и двоеточия, это исчерпает абсолютное большинство ошибок ввода

Третий шаг как раз у будет реализовывать проверку "этот символ представляет цифру?".

 
Vladimir Karputov:

В секунды никто не преобразует. После всех проверок можно будет идти двумя путями: 

  • или преобразовать проверенную строку в datetime
  • или преобразовать проверенную строку в две переменные объявленные на глобальном программном уровне - часы и минуты.

Пробел внутри приравнивается в ошибке ввода - если такое встретится - будет ошибка.

От пользователя можно ожидать всё, что угодно. Ничего исключать нельзя.

Третий шаг как раз у будет реализовывать проверку "этот символ представляет цифру?".

Ну уж на явных дебилов не стоит ориентироваться. Если он не умеет ввести формат времени в строку, то скорее всего он не сможет запустить программу в терминале.