Как преобразовать структуру TM в time_t в C++

Данная функция является частью класса, который используется для обработки даты и времени. анализируемый файл должен преобразовывать данные данной строки в time_t, но mktime не работает. Зачем?

 struct tm DateTimeUtils::makeTime(string arrTime)//accepts in format"2315"means 11.15 pm
{
    struct tm neww;
    string hour = arrTime.substr(0,2);
    int hour_int = stoi(hour);
    neww.tm_hour=hour_int;//when this is directly printed generates correct value


    string minute = arrTime.substr(2,2);
    int minute_int = stoi(minute);
    neww.tm_min=(minute_int);//when this is directly printed generates correct value

    time_t t1 = mktime(&neww);//only returns -1
    cout<<t1;

    return neww;

}

3 ответа

Со страницы руководства mktime(3):

time_t... представляет количество секунд, прошедших с начала эпохи, 1970-01-01 00:00:00 +0000 (UTC).

Тогда у вас есть поля struct tm и особенно этот:

tm_year

Количество лет с 1900 года.

Так что если tm_year установлен в 0 и мы делаем математику правильно, мы получаем 70 разница в году, которая должна быть выражена в секундах, и, вероятно, она слишком велика.

Вы можете решить эту проблему, инициализируя свой struct tm значение эпохи и использовать его в качестве базовой ссылки:

 struct tm DateTimeUtils::makeTime(string arrTime)//accepts in format"2315"means 11.15 pm
{
    time_t tmp = { 0 };
    struct tm neww = *localtime(&tmp);
    string hour = arrTime.substr(0,2);
    int hour_int = stoi(hour);
    neww.tm_hour=hour_int;//when this is directly printed generates correct value


    string minute = arrTime.substr(2,2);
    int minute_int = stoi(minute);
    neww.tm_min=(minute_int);//when this is directly printed generates correct value

    time_t t1 = mktime(&neww);//only returns -1
    cout<<t1;

    return neww;
}

Обычно time_t определяется как 64-битное целое число, которое разрешается в диапазоне

От -2^63 до +2^63-1 (от -9223372036854775808 до +9223372036854775807)

что примерно от -292 миллиардов лет до +292 от эпохи.

Тем не мение. Если, по какой-то причине, в вашей системе time_t просто определяется как 32-битное целое число (16-битная встроенная система или странная архитектура или файлы заголовков), мы получаем диапазон от

2^31 до 2^31-1 (от -2147483648 до +2147483647)

примерно от -68 до +68 лет.

Вы можете решить эту проблему, переопределив time_t перед вызовом mktime(),

#define time_t long int

или если действительно используется 16-битная система

#define time_t long long int

Очистка структуры перед использованием обычно помогает в этом случае:

struct tm neww;
memset((void *)&neww, 0, sizeof(tm));
Другие вопросы по тегам