Dave's Brain

Browse - programming tips - reentrant time functions

Date: 2007Feb23
Title: re-entrant time functions
Platform: win32
Language: C

The classic C time functions are not thread safe.

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;
}

Add a comment

Sign in to add a comment
Copyright © 2008, dave - Code on Dave's Brain is licensed under the Creative Commons Attribution 2.5 License.