And Old Bug In Windows CRT – time() Is Affected By Timezone Change

The standard C run-time (CRT) time() function for windows is documented thus

“The time function returns the number of seconds elapsed since midnight (00:00:00), January 1, 1970, coordinated universal time, according to the system clock. The return value is stored in the location given by timer. This parameter may be NULL, in which case the return value is not stored.”

So you would think that UTC is immune from local timezone information.

In windows its not.

time_t ltime;
t = time(&ltime);
t = 1163025749
The time in Reykjavik,ICELAND is (10:42pm) Wednesday
Change timezone
t = time(&ltime);
t = 1163007749
The time in Reykjavik,ICELAND is (5:42pm) Wednesday

To be immune from timezone changes during execution of your application you need to call _tzset() before you call time()

While trolling through the documentation I found this foreboding Y2Kish gem.

“In Visual C++ 2005, time is a wrapper for _time64 and time_t is, by default, equivalent to __time64_t. If you need to force the compiler to interpret time_t as the old 32-bit time_t, you can define _USE_32BIT_TIME_T. This is not recommended because your application may fail after January 18, 2038; the use of this macro is not allowed on 64-bit platforms.”

 

 

About James McParlane

CTO Massive Interactive. Ex Computer Whiz Kid - Now Grumpy Old Guru.
This entry was posted in C#. Bookmark the permalink.

1 Response to And Old Bug In Windows CRT – time() Is Affected By Timezone Change

  1. emerson says:

    I had similar problems with daylight savings when i was dealing with dates and times. I wanted my internal representations to be completely timezone free.

    I would rather that the user always sets the time using the current timezone, or simply adds the timezone offset at the end of any calculation. Having the system assume things about timezones is just asking for trouble when you move an application from one machine to another. When i construct a Time object as 12 midnight, i dont want to find out that the system has added an hour for dalylight savings, thats just evil.

    My primary concern in the solution below was with dst, but i think localtime() calls tzset() as well so you get the added bonus of not being affected by timezone changes.

    http://www.opengroup.org/onlinepubs/009695399/functions/localtime_r.html

    bool Time::Construct()
    {
    // We wan’t to create a localised time, including timezone offset as this should
    // report the current time as seen on the system. No where else do these time
    // routines deal with localised time. This is so that assigning a specific value
    // to time doesn’t result in it being reported differently or coverted in any way.
    // Times are often converted or taken from other sources and should be left alone
    // unless we specifically want localised time like now.
    timeb time;
    ftime(&time);

    struct tm * pointer = localtime((time_t*)&time.time);
    struct tm local = *pointer;
    local.tm_isdst=0;
    time_t seconds = mktime(&local);
    Construct(seconds);

    return true;
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s