Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 940
jdoeadeer Avatar asked Nov 29 '15 15:11

jdoeadeer


People also ask

How do I convert timestamp to time in Unix?

The getTime method returns the number of milliseconds since the Unix Epoch (1st of January, 1970 00:00:00). To get a Unix timestamp, we have to divide the result from calling the getTime() method by 1000 to convert the milliseconds to seconds. What is this?

How do I convert time to Unix timestamp in Excel?

Convert date to timestamp Select a blank cell, suppose Cell C2, and type this formula =(C2-DATE(1970,1,1))*86400 into it and press Enter key, if you need, you can apply a range with this formula by dragging the autofill handle. Now a range of date cells have been converted to Unix timestamps.

How is Unix time calculated?

The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z).

Is Unix time in milliseconds or seconds?

Unix is an operating system originally developed in the 1960s. Unix time is a way of representing a timestamp by representing the time as the number of seconds since January 1st, 1970 at 00:00:00 UTC.


2 Answers

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.

like image 159
nnn Avatar answered Nov 14 '22 07:11

nnn


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
like image 24
rileyberton Avatar answered Nov 14 '22 07:11

rileyberton