tags:

views:

47

answers:

5

In the following code, I try to get the local time and greenwich time and find the difference between them. But the output shows both the time values are equal:

diff=0 iTm1=16:34 iTm2=16:34 <-----[gmtime is 13:34 actualy]

When I just retreive gmtime, it works correctly. But when I retreive both local and gmtime, gmtime becomes equal to localtime.

#include <stdio.h>
#include <time.h>
int main()
{
        time_t iTime;
        struct tm * iTm1;
        struct tm * iTm2;
        int iTimeDifferenceInMinutes;

        time(&iTime);
        iTm1=gmtime(&iTime);
        iTm2=localtime(&iTime);
        iTimeDifferenceInMinutes=(int)((iTm2->tm_hour - iTm1->tm_hour)) * 60;
        printf("diff=%d iTm1=%d:%d iTm2=%d:%d\n", iTimeDifferenceInMinutes,
                        iTm1->tm_hour, iTm1->tm_min,
                        iTm2->tm_hour, iTm2->tm_min);
}

I have a mistake but I couldn't find it... May someone show me my fault please..?

A: 

Both localtime and gmtime use static memory in the clib for their processing. So when you use one, it overwrites the previous call.

You need to call gmtime, then pull the variables you want out and store it in a separate location. Then call localtime, and do your comparison.

OR, you can use the reentrant versions of these calls (localtime_r, gmtime_r) which you have to supply your own memory, but there won't be any overwriting of data.

I recommend getting used to using the reentrant versions of these calls, then bugs like this won't show their ugly head!

Starkey
A: 
ninjalj
+1  A: 

The gmtime and localtime functions each return a pointer to a fixed buffer. It seems that on your implementation, they use the same buffer, so the call to gmtime fills that buffer, and then the call to localtime fills that buffer with different data.

If you have gmtime_r and localtime_r, use them. (You may need to include the line #define _POSIX_SOURCE or something similar before #include <time.h>) You'll need to allocate memory for the two struct tm objects.

struct tm local_tm, gm_tm;
time(&iTime);
gmtime_r(&iTime, &gm_tm);
localtime_r(&iTime, &local_tm);

Older systems don't have the _r versions (they were added because the plain versions can't easily be used in a multithreaded program). Then you have to copy the data before the next call to either of the two functions.

struct tm local_tm, gm_tm;
time(&iTime);
memcpy(&gm_tm, gmtime(&iTime), sizeof(gm_tm));
memcpy(&local_tm, localtime(&iTime), sizeof(local_tm));
Gilles
+1  A: 

Your mistake in using pointers to struct tm without actually having a variable holding the memory. Here is a repaired version:

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

int main()
{
    time_t iTime;
    struct tm iTm1;
    struct tm iTm2;
    int iTimeDifferenceInMinutes;

    time(&iTime);
    iTm1=*gmtime(&iTime);
    iTm2=*localtime(&iTime);
    iDiff=(int)((iTm2.tm_hour - iTm1.tm_hour)) * 60;
    printf("diff=%d iTm1=%d:%d iTm2=%d:%d\n", iDiff,
       iTm1.tm_hour, iTm1.tm_min,
       iTm2.tm_hour, iTm2.tm_min);
}
Dirk Eddelbuettel
A: 

Thank you all! I understand my problem.I think it would be better if I do not use _r versions of the time functions because I the program will work on an embedded device(several platforms) and I don't know if the toolchains's support for reentrant functions are enough.

Thanks again.

xyzt