jdoeadeer
jdoeadeer

Reputation: 98

Convert string time to unix time and vice versa

I have been trying to simply convert a string "1998-04-11" to a UNIX timestamp which should be 892245600 according to an online converter.

But I keep getting a different result.

    struct tm tm;
    time_t ts;

    strptime("1998-04-11", "%Y-%m-%d", &tm);
    tm.tm_mon = tm.tm_mon -1;
    ts = mktime(&tm);

    printf("%d \n", (int)ts); //unix time-stamp
    printf("%s \n", ctime(&ts)); //human readable date 

Result:

893502901
Sat Apr 25 13:15:01 1998

Can anyone tell me what I am doing wrong?

Upvotes: 7

Views: 5906

Answers (2)

nnn
nnn

Reputation: 4220

Zero the tm structure before calling strptime

memset(&tm, 0, sizeof(struct tm));

From the notes section at: http://man7.org/linux/man-pages/man3/strptime.3.html

In principle, this function does not initialize tm but stores only the values specified. This means that tm should be initialized before the call.

And memset is used as above in the example from the same page.

Upvotes: 7

rileyberton
rileyberton

Reputation: 475

This is a problem of uninitialized memory.

(gdb) p tm
$1 = {tm_sec = 1, tm_min = 0, tm_hour = 4196061, tm_mday = 0, tm_mon = -5984, tm_year = 32767, 
tm_wday = 0, tm_yday = 0, tm_isdst = 4195984, tm_gmtoff = 4195616, 
tm_zone = 0x7fffffffe980 "\001"}

As you can see in the debugger, struct tm has random memory assigned. Making the time_zone offset garbage.

After strptime runs:

(gdb) p tm
$3 = {tm_sec = 1, tm_min = 0, tm_hour = 4196061, tm_mday = 11, tm_mon = 3, tm_year = 98, 
tm_wday = 6, tm_yday = 100, tm_isdst = 4195984, tm_gmtoff = 4195616, 
tm_zone = 0x7fffffffe980 "\001"}

In addition the:

tm.tm_mon = tm.tm_mon -1;

Is unnecessary. Corrected code:

#include <time.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {

struct tm tm;
time_t ts = 0;
memset(&tm, 0, sizeof(tm));

    strptime("1998-04-11", "%Y-%m-%d", &tm);
    ts = mktime(&tm);

    printf("%d \n", (int)ts); //unix time-stamp
    printf("%s \n", ctime(&ts)); //human readable date
}

Output:

892252800
Sat Apr 11 00:00:00 1998

Upvotes: 4

Related Questions