Ответ 1
Использовать изоляцию /Mocking framework - единственное, что я знаю на данный момент, это Isolator ++, который в настоящее время находится в бета-версии, я уверен, что вы можете получить копию, попросив одного у хороших людей Typemock.
Я написал функцию, чтобы вернуть значение time_t
, соответствующее полуночи в данный день. Когда нет полуночи за данный день, он возвращает самое раннее время; такая ситуация может возникнуть, например, когда Египет переходит на летнее время. В этом году смена времени вступает в силу в полночь в ночь на 29 апреля, поэтому часы идут непосредственно с 23:59 до 01:00.
Теперь я пишу модульные тесты для этой функции, и один из тестов должен повторить сценарий Египта. В Unix я могу выполнить это следующим образом:
putenv("TZ", "Egypt", true);
tzset();
После этого дальнейшие вызовы localtime
ведут себя так, как будто они находятся в Египте, а не в Миннесоте, и мои тесты проходят. Однако простая настройка переменной окружения не оказывает никакого влияния на Windows. Что я могу сделать, чтобы unit test подумал, что это где-то в другом месте, не затрагивая остальные программы, запущенные в системе?
Использовать изоляцию /Mocking framework - единственное, что я знаю на данный момент, это Isolator ++, который в настоящее время находится в бета-версии, я уверен, что вы можете получить копию, попросив одного у хороших людей Typemock.
Отметьте _ putenv_s и _tzset. Теоретически вы должны установить переменную среды TZ для вашего процесса с помощью _putenv_s, а затем использовать _tzset, чтобы установить фактический локальный часовой пояс для вашего процесса, к которому установлена переменная среды TZ.
Я знаю, что это работает в Linux с putenv и tzset, а также из документации _putenv_s и _tzset, похоже, что вы должны сделать то же самое с ними в Windows. Я на самом деле не пытался это сделать.
Пожалуйста, не вызывайте SetTimeZoneInformation - в Windows нет потока или определенного для конкретного процесса понятия часового пояса. Как говорят другие, самым простым способом является издевка кода часового пояса - с помощью Pex/Mocks вы можете издеваться над статическими методами, что означает, что вы можете подключить стандартный код часового пояса .NET, чтобы заменить его своим собственным. Если вы используете C/С++, вам просто нужно подключить код, чтобы информация TZ была макетируемой.
С VS 2008 (С++ native) мне удалось изменить поведение localtime()
, изменив переменную _timezone
.
Я согласен, это не простой способ сделать, но по крайней мере это может быть обходным путем.
Конечно, вам нужно сделать математику самостоятельно, чтобы найти количество секунд между UTC и вашим "новым" часовым поясом.
Я использовал setlocale(LC_ALL, "deu_aut")
для переключения настроек языка/страны в Австрию, объявленных в locale.h
. К сожалению, я не нашел строку language/country для egypt, но, возможно, это дает вам подсказку.
У меня точно такое же требование:
- > некоторые процессы должны быть привязаны к UTC, а другие - к часовому поясу, отличному от системного часового пояса Windows
После нескольких месяцев (прерывания) исследования я подхожу к выводу, что в Windows можно установить только "UTC" или "текущий" системный часовой пояс. Таким образом, можно сделать следующее:
- set TZ="UTC" - unset TZ
Установите привязку к GetTimeZoneInformation, которая переопределяет системные данные с вашими собственными настройками.
Вы видели SetTimeZoneInformation функцию Win32 API?