gpt4 book ai didi

c++ - 使用 WinAPI 进行夏令时和 UTC 到本地时间的转换

转载 作者:可可西里 更新时间:2023-11-01 13:53:39 25 4
gpt4 key购买 nike

我正在尝试查看从本地时间转换为 UTC 时间以及反之亦然的 WindAPI 是否符合夏令时。例如,我们以 LocalFileTimeToFileTime 为例应用程序接口(interface)。它的描述指出:

LocalFileTimeToFileTime uses the current settings for the time zone and daylight saving time. Therefore, if it is daylight saving time, this function will take daylight saving time into account, even if the time you are converting is in standard time.

所以我正在用这段代码测试它:

//Say, if DST change takes place on Mar-8-2015 at 2:00:00 AM
//when the clock is set 1 hr forward

//Let's check the difference between two times:
SYSTEMTIME st1_local = {2015, 3, 0, 8, 1, 30, 0, 0}; //Mar-8-2015 1:30:00 AM
SYSTEMTIME st2_local = {2015, 3, 0, 8, 3, 30, 0, 0}; //Mar-8-2015 3:30:00 AM

//Convert to file-time format
FILETIME ft1_local, ft2_local;
VERIFY(::SystemTimeToFileTime(&st1_local, &ft1_local));
VERIFY(::SystemTimeToFileTime(&st2_local, &ft2_local));

//Then convert from local to UTC time
FILETIME ft1_utc, ft2_utc;
VERIFY(::LocalFileTimeToFileTime(&ft1_local, &ft1_utc));
VERIFY(::LocalFileTimeToFileTime(&ft2_local, &ft2_utc));

//Get the difference
LONGLONG iiDiff100ns = (((LONGLONG)ft2_utc.dwHighDateTime << 32) | ft2_utc.dwLowDateTime) -
(((LONGLONG)ft1_utc.dwHighDateTime << 32) | ft1_utc.dwLowDateTime);

//Convert from 100ns to seconds
LONGLONG iiDiffSecs = iiDiff100ns / 10000000LL;

//I would expect 1 hr
ASSERT(iiDiffSecs == 3600); //But I get 7200, which is 2 hrs!

那么我在这里缺少什么?

最佳答案

SystemTimeToFileTime() 将其第一个参数解释为 UTC 时间(没有 DST 的概念),因此您的 ft1_localft2_local 对象由于您正在更改数据格式,因此始终相隔两个小时,但不是实际时间点。 LocalFileTimeToFileTime() 将对您传递给它的任何内容应用相同的偏移量,因此 ft1_utcft2_utc 将始终相隔两个小时,而且.

正如文档所说,“LocalFileTimeToFileTime 使用时区和夏令时的当前设置”(强调我的),所以如果在当前时间你'例如,如果你比 UTC 晚了四个小时,它只会从你传递给它的任何时间中减去四个小时,不管那个时间最初是否代表夏令时另一边的某个时间。

编辑:根据评论,这里是您如何在标准 C 中获得两个本地时间之间的秒差:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
struct tm start_time;
start_time.tm_year = 115;
start_time.tm_mon = 2;
start_time.tm_mday = 8;
start_time.tm_hour = 1;
start_time.tm_min = 30;
start_time.tm_sec = 0;
start_time.tm_isdst = -1;

struct tm end_time;
end_time.tm_year = 115;
end_time.tm_mon = 2;
end_time.tm_mday = 8;
end_time.tm_hour = 3;
end_time.tm_min = 30;
end_time.tm_sec = 0;
end_time.tm_isdst = -1;

time_t start_tm = mktime(&start_time);
time_t end_tm = mktime(&end_time);

if ( start_tm == -1 || end_tm == -1 ) {
fputs("Couldn't get local time.", stderr);
exit(EXIT_FAILURE);
}

double seconds_diff = difftime(end_tm, start_tm);
printf("There are %.1f seconds difference.\n", seconds_diff);

return EXIT_SUCCESS;
}

哪些输出:

paul@thoth:~/src$ ./difftime
There are 3600.0 seconds difference.
paul@thoth:~/src$

如你所料。

请注意,使用 struct tm:

  • tm_year 以自 1900 年以来的年数表示,因此要获得 2015,我们写 115

  • tm_mon 在 0 到 11 的范围内,所以 March 是 2,而不是 3。

  • 其他时间成员如你所料

  • tm_isdst 设置为 -1 时,mktime() 将尝试自行查明 DST 是否生效在我们提供的本地时间,这是我们希望它在此处执行的操作。

关于c++ - 使用 WinAPI 进行夏令时和 UTC 到本地时间的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23304702/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com