Windows程序如何暂时更改其时区?

时间:2010-04-09 21:21:20

标签: c++ windows unit-testing timezone

我写了一个函数来返回给定日期对应午夜的time_t值。当某一天没有午夜时,它会返回最早的可用时间;例如,当埃及进入夏令时时,就会发生这种情况。今年,时间变更将于4月29日晚上午夜生效,因此时钟从23:59直接到01:00。

现在我正在为这个函数编写单元测试,其中一个测试应该复制埃及场景。在Unix中,我可以像这样完成它:

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

在这样做之后,对localtime的进一步调用就像他们在埃及而不是明尼苏达一样,我的测试通过了。但是,仅仅设置环境变量对Windows没有任何影响。如果不影响系统上运行的其他程序,我该怎么做才能让单元测试认为它在其他地方?

8 个答案:

答案 0 :(得分:3)

使用隔离/模拟框架 - 我目前唯一知道的是Isolator++目前处于测试阶段,我相信你可以通过向Typemock的好人索取一个副本来获得副本

答案 1 :(得分:2)

查看 _putenv_s _tzset 。理论上,您应该能够使用 _putenv_s 为您的流程设置 TZ 环境变量,然后使用 _tzset 设置实际的本地时区为您的流程设置 TZ 环境变量。

我知道这适用于Linux上的 putenv tzset ,以及 _putenv_s _tzset ,似乎您应该能够在Windows上对它们执行相同的操作。我实际上并没有尝试过它。

答案 2 :(得分:2)

请不要调用SetTimeZoneInformation - Windows中没有时区的线程或进程特定概念。正如其他人所说,最简单的方法是模拟时区代码 - 使用Pex / Mocks,你甚至可以模拟静态方法,这意味着你可以挂钩标准的.NET时区代码来替换它自己的代码。如果你正在使用C / C ++,你只需要连接代码就可以使TZ信息变得可模糊。

答案 3 :(得分:1)

使用VS 2008(C ++ native),我可以通过更改localtime()变量来修改_timezone的行为。

我同意,这不是一个干净的方法,但至少这可能是一种解决方法。

当然,您需要自己进行数学计算,以找出UTC与您的“'”之间的秒数。时区。

答案 4 :(得分:0)

我使用setlocale(LC_ALL, "deu_aut")将语言/国家/地区设置切换为奥地利 - 在locale.h中声明。可悲的是,我还没有找到埃及的语言/国家/地区字符串,但也许这会给你一个提示。

答案 5 :(得分:0)

我有完全相同的要求:

- >某些进程必须停留在UTC,其他进程必须停留在与Windows系统时区不同的某个时区

经过数月(中断)研究后,我得出的结论是,在Windows上只能设置“UTC”或“当前”系统时区。所以只能做以下事情:

     - set TZ="UTC" 
     - unset TZ

答案 6 :(得分:0)

为GetTimeZoneInformation安装一个钩子,它使用您自己的首选项覆盖系统数据。

答案 7 :(得分:-1)

您是否看过SetTimeZoneInformation Win32 API函数?