2013-04-04 3 views
2

Я пытаюсь получить количество секунд, прошедших с эпохи. Код:Время с эпохи -1

long parseTime(string time) { 

    cout << "Time entered = " << time << endl; 

    long timeSinceEpoch; 

    //takes in time in string format - date + time and returns seconds from epoch. 
    /* Steps: 
    * 1. Remove trailing and leading spaces. 
    * 2. Check format of date. 
    * 3. Convert to epoch. 
    */ 

    //remove trailing and leading spaces. 
    /* 
    unsigned int leading = 0, trailing = 0; 
    string whitespace = " \t"; 

    leading = time.find_first_not_of(whitespace); 
    trailing = time.find_last_not_of(whitespace); 

    string newTime = time.substr(leading, (trailing - leading + 1)); 
    cout << "Old time = " << time << " new time = " << newTime << endl; 
    */ 
    string newTime = time; 

    struct tm t; 

    if(newTime.find("/") != string::npos) { 
    //format of date is mm/dd/yyyy. followed by clock in hh:mm (24 hour clock). 
    cout << "Time format contains slashes." << endl; 
    if(strptime(newTime.c_str(), "%m/%e/%Y %H:%M", &t) == NULL) { 
     cout << "Error. Check string for formatting." << endl; 
    } 
    } else if(newTime.find("-") != string::npos) { 
    //format of date is yyyy-mm-dd hh:mm:ss (hh in 24 hour clock format). 
    if(strptime(newTime.c_str(), "%Y-%m-%e %H:%M:%S", &t) == NULL) { 
    cout << "Error. Check string for formatting of new date." << endl; 
    } 
    } 

    if(t.tm_isdst) { 
    t.tm_isdst = 0; 
    } 

    timeSinceEpoch = mktime(&t); 
    cout << "Time since epoch = " << timeSinceEpoch << endl; 

    return timeSinceEpoch; 
} 

Теперь, когда строка, содержащая дату и время передается функция:
3/26/2013 3:17
Это приводит к времени с началом эпохи = -1. Вот выход из отладчика:

Breakpoint 2, parseTime (time=...) at informationExtractor.cpp:44 
44  cout << "Time entered = " << time << endl; 
(gdb) n 
Time entered = 3/26/2013 3:17 
66  string newTime = time; 
(gdb) 
70  if(newTime.find("/") != string::npos) { 
(gdb) p newTime 
$3 = {static npos = <optimized out>, 
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 
    _M_p = 0x8004ab0c "3/26/2013 3:17"}} 
(gdb) n 
72   cout << "Time format contains slashes." << endl; 
(gdb) 
Time format contains slashes. 
73   if(strptime(newTime.c_str(), "%m/%e/%Y %H:%M", &t) == NULL) { 
(gdb) 
83  if(t.tm_isdst) { 
(gdb) p newTime.c_str()@strlen(newTime.c_str()) 
Only values in memory can be extended with '@'. 
(gdb) n 
84   t.tm_isdst = 0; 
(gdb) p newTime 
$4 = {static npos = <optimized out>, 
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 
    _M_p = 0x8004ab0c "3/26/2013 3:17"}} 
(gdb) n 
87  timeSinceEpoch = mktime(&t); 
(gdb) p t 
$5 = {tm_sec = 1628993312, tm_min = 17, tm_hour = 3, tm_mday = 26, tm_mon = 2, tm_year = 113, tm_wday = 2, tm_yday = 84, 
    tm_isdst = 0} 
(gdb) n 
88  cout << "Time since epoch = " << timeSinceEpoch << endl; 
(gdb) 
Time since epoch = -1 
90  return timeSinceEpoch; 
(gdb) 

Если вы заметили, tm_sec в t является 1628993312, а timesinceEpoch -1. tm_sec также находится в пределах диапазона для long, который является типом данных timesinceEpoch. Любые идеи о том, почему и как их решить, приветствуются.

ответ

3

Дело в том, что в вашем коде tm_sec является неинициализированным значением. Значение должно быть от 0 до 59. Поэтому добавьте эту строку кода в свою первую ветвь if.

if(strptime(newTime.c_str(), "%m/%e/%Y %H:%M", &t) == NULL) { 
    cout << "Error. Check string for formatting." << endl; 
} 
t.tm_sec = 0; // initialise seconds field 
+0

'tm_sec' установлен в 0 после того, как он был инициализирован с' strptime'? как это будет работать? Кроме того, вывод отладчика показывает, что 'tm_sec' (время с эпохи) инициализируется до 1628993312 до того, как будет установлено значение -1 после вызова mktime. – Sriram

+1

Я хочу сказать, что он не инициализируется strptime, в вашей строке формата нет% S. – john

+0

Я не уверен, что понял это. '% S' находится в секундах, а строка времени, введенная в функцию, не имеет секунд, только часы: минуты. – Sriram

1

john is right. strptime не инициализирует tm и только коснуться полей, которые явно указаны (see "Notes" of strptime(3)), так t.tm_sec не инициализирован.

Для предотвращения такого рода ошибки, вы можете объявить varialbes с инициализацией

struct tm t = { 0 }; // zero filled 

 Смежные вопросы

  • Нет связанных вопросов^_^