Vishnu Lal
Vishnu Lal

Reputation: 189

how to get timestamp in c

I want to get timestamp for my log in c. i have written a function to get timestamp. But when i return the variable i m getting different value.

My code:

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

char* get_timestamp(){
   time_t rawtime;
   struct tm * timeinfo;
   char buffer[16];
   time (&rawtime);
   timeinfo = localtime (&rawtime);
   strftime (buffer,16,"%G%m%d%H%M%S",timeinfo);
   puts(buffer);
   return buffer; 
}

int main() 
{
   puts(get_timestamp());
   return 0;
}

output:

20130315204815
Ir?0315204815

Can anyone help out from this... Thank you.

Upvotes: 4

Views: 10824

Answers (5)

Xofo
Xofo

Reputation: 1278

In answering this question I wanted a function that was simple, thread friendly, did not return a char* (which is often tedious to manage), thread-safe and could stand on its own feet. I have an aversion to functions that return char* or pointers that must be managed.

The function below does not call malloc.

The function takes no parameters and returns a timestamp. I think it works well.

struct Timestamp {
    time_t seconds;
    long milliseconds;
    char timestring[32];
};


struct Timestamp getTimestamp()
{
char   timebuffer[32]     = {0};
struct timeval  tv        = {0};
struct tm      *tmval     = NULL;
struct tm       gmtval    = {0};
struct timespec curtime   = {0};

struct Timestamp timestamp;

int i = 0;

// Get current time
clock_gettime(CLOCK_REALTIME, &curtime);


// Set the fields
timestamp.seconds      = curtime.tv_sec;
timestamp.milliseconds = round(curtime.tv_nsec/1.0e6);

if((tmval = gmtime_r(&timestamp.seconds, &gmtval)) != NULL)
{
    // Build the first part of the time
    strftime(timebuffer, sizeof timebuffer, "%Y-%m-%d %H:%M:%S", &gmtval);

    // Add the milliseconds part and build the time string
    snprintf(timestamp.timestring, sizeof timestamp.timestring, "%s.%03ld", timebuffer, timestamp.milliseconds); 
}

return timestamp;
}

int main()
{
    char   timebuffer[64]     = {0};
    int i = 0;
    struct timespec sleeptime = {0, 5000000L};

    struct Timestamp timestamp;

    for (i=0; i < 20; i++)
    {
        timestamp = getTimestamp();
        printf("Time is: %s \n", timestamp.timestring);
        nanosleep(&sleeptime, NULL);
    }

    return 0;
}

Upvotes: 1

fvu
fvu

Reputation: 32953

As the other said, you're using data that resides on the stack and stops existing once you leave the function that declared it. I see two simple possibilities to solve this problem:

Option 1: allocate the buffer variable in the calling function, and pass a pointer into get_timestamp

void get_timestamp( char *buffer, size_t buffersize ) {
    ....
    strftime (buffer,buffersize,"%G%m%d%H%M%S",timeinfo);
}

int main() 
{
   char buffer[16];
   puts(get_timestamp(buffer,16));
   return 0;
}

Note/Edit: I folded unwind's very valid remark regarding passing the size of buffer into this suggested solution.

Option 2: if you cannot or don't want to change the signature of your function you can use a static variable, but don't forget that static variables can cause issues in multithreaded programs.

static char buffer[16];

char* get_timestamp(){
   ... 
}

int main() 
{
   puts(get_timestamp());
   return 0;
}

You could of course use malloc but that seems overkill in this situation, and is more error prone than the two fixes I described.

Upvotes: 2

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158469

You are returning a pointer to a stack variable and therefore it is not valid to use after the function returns:

 char buffer[16];

Will be allocated on the stack in the function. When you return the stack is cleaned up and buffer is no longer valid. With minimal changes this is probably a better function signature:

void get_timestamp( char *buffer, size_t buffLen  )

The assumption being that you have properly allocated space for buffer before calling get_timestamp.

Upvotes: 4

stdcall
stdcall

Reputation: 28880

The string you're returning is an automatic variable. When you exit the function accessing this variable is impossible. According to the specs it's undefined behavior. Use malloc to allocate the string and you'll be fine. Just don't forget to free it afterwards.

Upvotes: 1

user1944441
user1944441

Reputation:

buffer[16] is a local array, which stops existing at the end of char* get_timestamp() function. Then you return a pointer to an array that does not exist.

Upvotes: 6

Related Questions