tanvi rustagi
tanvi rustagi

Reputation: 21

how to convert struct tm to time_t in c++

the given function is a part of a class which is used to handle date and time.the file i parse needs to convert the given string data to time_t yet mktime does not work. why?

 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;

}

Upvotes: 2

Views: 8036

Answers (3)

Detonar
Detonar

Reputation: 1429

Usually time_t is defined as 64 bit integer which resolves in a range of

-2^63 to +2^63-1 (-9223372036854775808 to +9223372036854775807)

which is roughly from -292 bilion years to +292 from the epoch.

However. If, fpor some reason, on your system time_t is just defined as 32 bit integer (16 bit embedded system or weird architecture or header files) we get a range from

2^31 to 2^31-1 (-2147483648 to +2147483647)

being roughly from -68 years to +68 years.

You could solve this problem by redefining time_t before calling mktime().

#define time_t long int

or if really using an 16 bit system

#define time_t long long int

Upvotes: 0

Drax
Drax

Reputation: 13278

From the mktime(3) man page:

time_t ... represents the number of seconds elapsed since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).

Then you have the fields of struct tm and particularly this one:

tm_year

The number of years since 1900.

So basicaly if the tm_year is set to 0 and we do the math correctly, we get a 70 year difference that needs to be expressed in seconds, and that's probably too big.

You can solve this by initialising your struct tm value to the Epoch and use that as a base reference:

 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;
}

Upvotes: 1

Anton Malyshev
Anton Malyshev

Reputation: 8861

Clearing the struct before usage usually helps in this case:

struct tm neww;
memset((void *)&neww, 0, sizeof(tm));

Upvotes: 0

Related Questions