Reputation: 98
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
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 thattm
should be initialized before the call.
And memset
is used as above in the example from the same page.
Upvotes: 7
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