Как программа Windows может временно изменить свой часовой пояс?

Я написал функцию, чтобы вернуть значение time_t, соответствующее полуночи в данный день. Когда нет полуночи за данный день, он возвращает самое раннее время; такая ситуация может возникнуть, например, когда Египет переходит на летнее время. В этом году смена времени вступает в силу в полночь в ночь на 29 апреля, поэтому часы идут непосредственно с 23:59 до 01:00.

Теперь я пишу модульные тесты для этой функции, и один из тестов должен повторить сценарий Египта. В Unix я могу выполнить это следующим образом:

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

После этого дальнейшие вызовы localtime ведут себя так, как будто они находятся в Египте, а не в Миннесоте, и мои тесты проходят. Однако простая настройка переменной окружения не оказывает никакого влияния на Windows. Что я могу сделать, чтобы unit test подумал, что это где-то в другом месте, не затрагивая остальные программы, запущенные в системе?

Ответ 1

Использовать изоляцию /Mocking framework - единственное, что я знаю на данный момент, это Isolator ++, который в настоящее время находится в бета-версии, я уверен, что вы можете получить копию, попросив одного у хороших людей Typemock.

Ответ 2

Отметьте _ putenv_s и _tzset. Теоретически вы должны установить переменную среды TZ для вашего процесса с помощью _putenv_s, а затем использовать _tzset, чтобы установить фактический локальный часовой пояс для вашего процесса, к которому установлена ​​переменная среды TZ.

Я знаю, что это работает в Linux с putenv и tzset, а также из документации _putenv_s и _tzset, похоже, что вы должны сделать то же самое с ними в Windows. Я на самом деле не пытался это сделать.

Ответ 3

Пожалуйста, не вызывайте SetTimeZoneInformation - в Windows нет потока или определенного для конкретного процесса понятия часового пояса. Как говорят другие, самым простым способом является издевка кода часового пояса - с помощью Pex/Mocks вы можете издеваться над статическими методами, что означает, что вы можете подключить стандартный код часового пояса .NET, чтобы заменить его своим собственным. Если вы используете C/С++, вам просто нужно подключить код, чтобы информация TZ была макетируемой.

Ответ 4

С VS 2008 (С++ native) мне удалось изменить поведение localtime(), изменив переменную _timezone.

Я согласен, это не простой способ сделать, но по крайней мере это может быть обходным путем.

Конечно, вам нужно сделать математику самостоятельно, чтобы найти количество секунд между UTC и вашим "новым" часовым поясом.

Ответ 5

Я использовал setlocale(LC_ALL, "deu_aut") для переключения настроек языка/страны в Австрию, объявленных в locale.h. К сожалению, я не нашел строку language/country для egypt, но, возможно, это дает вам подсказку.

Ответ 6

У меня точно такое же требование:

- > некоторые процессы должны быть привязаны к UTC, а другие - к часовому поясу, отличному от системного часового пояса Windows

После нескольких месяцев (прерывания) исследования я подхожу к выводу, что в Windows можно установить только "UTC" или "текущий" системный часовой пояс. Таким образом, можно сделать следующее:

     - set TZ="UTC" 
     - unset TZ

Ответ 7

Установите привязку к GetTimeZoneInformation, которая переопределяет системные данные с вашими собственными настройками.