Rob Kennedy
Rob Kennedy

Reputation: 163297

How can a Windows program temporarily change its time zone?

I've written a function to return the time_t value corresponding to midnight on a given day. When there is no midnight for a given day, it returns the earliest time available; that situation can occur, for example, when Egypt enters daylight-saving time. This year, the time change takes effect at midnight on the night of April 29, so the clock goes directly from 23:59 to 01:00.

Now I'm writing unit tests for this function, and one of the tests should replicate the Egypt scenario. In Unix, I can accomplish it like this:

putenv("TZ", "Egypt", true);
tzset();

After doing that, further calls to localtime behave as if they're in Egypt instead of Minnesota, and my tests pass. Merely setting the environment variable doesn't have any effect on Windows, though. What can I do to make the unit test think it's somewhere else without affecting the rest of the programs running on the system?

Upvotes: 14

Views: 6970

Answers (8)

Frederic Maria
Frederic Maria

Reputation: 2431

With VS 2008 (C++ native) I was able to modify the behavior of localtime() by changing the _timezone variable.

I agree, this is not a clean way to do, but at least this could be a workaround.

Of course, you need to do the math by yourself to find the number of seconds between UTC and your 'new' timezone.

Upvotes: 1

Alex
Alex

Reputation: 5668

Install a hook to GetTimeZoneInformation, which overrides system data with your own preferences.

Upvotes: 0

Ana Betts
Ana Betts

Reputation: 74652

Please don't call SetTimeZoneInformation - there is no thread or process-specific notion of a time zone in Windows. As others say, the easiest way is to mock out the timezone code - with Pex/Mocks, you can mock out even static methods, which means you can hook the standard .NET Timezone code to replace it with your own. If you're using C/C++, you just need to wire up the code to have the TZ info be mockable.

Upvotes: 2

Jonathan M Davis
Jonathan M Davis

Reputation: 38287

Check out _putenv_s and _tzset. In theory, you should be able to set the TZ environment variable for your process with _putenv_s and then use _tzset to set the actual local time zone for your process to what the TZ environment variable is set to.

I know that this works on Linux with putenv and tzset, and from the documentation of _putenv_s and _tzset, it appears that you should be able to do the same with them on Windows. I haven't actually tried it though.

Upvotes: 4

Dror Helper
Dror Helper

Reputation: 30800

Use Isolation/Mocking framework - the only one I know of at the moment is Isolator++ which is currently in beta, I'm sure that you can get a copy by asking for one from the good people of Typemock.

Upvotes: 3

Alex
Alex

Reputation: 124

I have exactly the same requirement:

->some processes must be stuck to UTC and others to some timezone different from the Windows system timezone

After months of (interrupted) study I fall to the conclusion that on Windows it is only possible to set "UTC" or "current" system time zone. So only the following may be done:

     - set TZ="UTC" 
     - unset TZ

Upvotes: 0

Christian Ammer
Christian Ammer

Reputation: 7542

I used setlocale(LC_ALL, "deu_aut") to switch the language/country settings to Austria - declared in locale.h. Sadly i haven't found a language/country string for egypt, but perhaps this gives you a hint.

Upvotes: 0

LBushkin
LBushkin

Reputation: 131726

Have you seen the SetTimeZoneInformation Win32 API function?

Upvotes: -2

Related Questions