开发者

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 environmen开发者_JAVA技巧t 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?


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.


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.


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.


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.


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.


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


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


Have you seen the SetTimeZoneInformation Win32 API function?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜