How can a Windows program temporarily change its t

2019-03-15 13:03发布

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?

8条回答
We Are One
2楼-- · 2019-03-15 13:05

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.

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-03-15 13:07

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.

查看更多
Root(大扎)
4楼-- · 2019-03-15 13:17

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.

查看更多
乱世女痞
5楼-- · 2019-03-15 13:21

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.

查看更多
forever°为你锁心
6楼-- · 2019-03-15 13:24

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

查看更多
三岁会撩人
7楼-- · 2019-03-15 13:27

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.

查看更多
登录 后发表回答