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?
精彩评论