Reputation: 268
I am trying to diff two dates in C, but I receive such output:
future date: 18-11-2013 22:8
current date: 18-11-2013 22:8
Here comes my code:
#include <stdio.h>
#include <time.h>
int main(int argc, char *argv[])
{
// 2 years ahead
time_t unixtime = time(NULL);
struct tm *future = localtime(&unixtime);
future->tm_year += 2;
// current time
time_t unixtime_now = time(NULL);
struct tm *current = localtime(&unixtime_now);
printf("future date: %d-%d-%d %d:%d\n", future->tm_mday, 1 + future->tm_mon, 1900 + future->tm_year, future->tm_hour, future->tm_min);
printf("current date: %d-%d-%d %d:%d\n", current->tm_mday, 1 + current->tm_mon, 1900 + current->tm_year, current->tm_hour, current->tm_min);
return 0;
}
Upvotes: 0
Views: 814
Reputation: 229342
That's because localtime() is not reentrant.
When you do
struct tm *future = localtime(&unixtime);
...
struct tm *current = localtime(&unixtime_now);
the first call returns a pointer to some static location managed by the runtime. The second call uses that same location to store the data. So now both future
and current
point to the exact same thing.
You need to copy out the struct tm
into storage that you manage yourself: e.g.
struct tm future = *localtime(&unixtime);
...
struct tm current = *localtime(&unixtime_now);
Or use the more appropriate localtime_r
function if it's available on your platform.
struct tm future;
localtime_r(&unixtime, &future);
...
struct tm current;
localtime_r(&unixtime, ¤t);
Upvotes: 2
Reputation: 5919
The return value of localtime
is a pointer to a statically allocated struct which may be overwritten by further calls to date/time functions. If you want to keep the pointed-to data around for longer, you need to make a copy of it, or use another function such as localtime_r
.
See the localtime(3) man page:
The localtime() function converts the calendar time timep to broken-down time representation, expressed relative to the user's specified timezone. The function acts as if it called tzset(3) and sets the external variables tzname with information about the current timezone, timezone with the difference between Coordinated Universal Time (UTC) and local standard time in seconds, and daylight to a nonzero value if daylight savings time rules apply during some part of the year. The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the date and time functions. The localtime_r() function does the same, but stores the data in a user-supplied struct. It need not set tzname, timezone, and daylight.
Upvotes: 2