Date: 2007Feb23
Platform: win32
Language: C
Keywords: time, date
Q. C/C++: The classic C time functions are not thread safe. What should I do?
A. Update: use localtime_s() if you're on Windows.
If your code has threads you should *not* use localtime(), gmtime(), asctime().
They all modify hidden global variables.
Here's the code for localtime_r() which is thread-safe...
// Helper function from MSDN Q167296
static void UnixTimeToFileTime(const time_t t, LPFILETIME pft)
{
LONGLONG ll;
ll = Int32x32To64(t, 10000000) + 116444736000000000;
pft->dwLowDateTime = (DWORD)ll;
pft->dwHighDateTime = ll >> 32;
}
struct tm *localtime_r(const time_t *clock, struct tm *result)
{
FILETIME ft;
SYSTEMTIME st;
SYSTEMTIME lst;
if (clock == NULL || result == NULL) return NULL;
ZeroMemory(result, sizeof(struct tm));
UnixTimeToFileTime(*clock, &ft);
FileTimeToSystemTime(&ft, &st);
SystemTimeToTzSpecificLocalTime(NULL, &st, &lst);
result->tm_year = lst.wYear - 1900;
result->tm_mon = lst.wMonth - 1;
result->tm_wday = lst.wDayOfWeek;
result->tm_mday = lst.wDay;
result->tm_hour = lst.wHour;
result->tm_min = lst.wMinute;
result->tm_sec = lst.wSecond;
result->tm_isdst = -1; // Don't know
result->tm_yday = -1; // Don't know
return result;
}
Or simply use the Windows API functions (which are reentrant):
SYSTEMTIME lt;
GetLocalTime(<); // The time on this computer
SYSTEMTIME st;
SystemTime(&st); // The GMT time
They are higher resolution too. But not portable.