我写一些代码,将在多个互通系统上运行。 我使用的时间(),以获得time_t的,但这导致与系统之间的时差问题,所以我想在time_t的格林尼治标准时间。 我一直在寻找通过time.h中的功能,但目前还不清楚我怎么可以肯定,我会得到正确的时间。 这是我想出迄今:
time_t t = time();
struct tm *gtm = gmtime(&t);
time_t gt = mktime(gtm);
现在,这似乎让我的机器上正确的答案,但我想知道这是否正常工作普遍之前,我推了,即使其他机器的时钟设置为本地时间或GMT或在不同的时区或任何。 我担心的原因是因为mktime的。 在说明书中,它说,它解释tm结构为“本地时间表示日历时间。” 这听起来好像它不会返回GMT时间,虽然这似乎是我的机器上。 此外,当我打印出来的GT,它是领先的T 4个小时,这似乎是正确的。 但是,如果我运行以下命令:
time_t t = time();
struct tm *gtm = gmtime(&t);
struct tm *ltm = localtime(&t);
printf("%d, %d\n", gtm->tm_hour, ltm->tm_hour);
小时是相同的,均为当地时间,这是不是我的预期。
根据记录,在另一个答案,我看到了参考timegm(),这听起来很完美,但它并不在我的系统上存在。
因此,在短期,我怎么在格林尼治标准时间time_t的任何Windows机器C对?
编辑:已添加,因为我没有使用MSVCRT删除MSVCRT标签。
time_t的总是UTC,顾名思义。 所以,时间()你想要做什么。 时区才开始发挥作用,当你的time_t和破旧的时间表示之间的转换。
如果你有在破旧的时间表示UTC时间,你需要暂时切换时区为UTC,使用mktime()转换为time_t的,并且切换时区回来了,就像这样:
time_t convert_utc_tm_to_time_t (struct tm *tm)
{
char *tz;
time_t result;
/* temporarily set timezone to UTC for conversion */
tz = getenv("TZ");
if (tz) {
tz = strdup (tz);
if (!tz) {
// out of memory
return -1;
}
}
setenv("TZ", "", 1);
tzset();
tm->tm_isidst = 0;
result = mktime (tm);
/* restore timezone */
if (tz) {
setenv("TZ", tz, 1);
free (tz);
}
else {
unsetenv("TZ");
}
tzset();
return result;
}
使用gmtime()
只要你想在你的GMT时间身影。 localtime
将在本地时区报告的时间,只能由GMT时,本地时区也GMT。
Windows有它自己的代码和数据结构的处理时间和时区。 使用Windows特定的C代码得到GMT,你可以使用GetSystemTime()
你可以找到它在这个网址的更多信息: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724390(v=vs.85).aspx
请注意,Windows使用其自己的日期/时间结构,但也有详细的GetSystemTime()
及其相关页面。 总之, GetSystemTime()
获取当前系统日期和时间,在协调世界时(UTC)(也称为GMT)表示。 它采用了Windows结构SYSTEMTIME是随着时间许多元素的结构。
看你的代码的第一部分:
time_t t = time();
struct tm *gtm = gmtime(&t);
time_t gt = mktime(gtm);
你设置gt
假值。 当调用mktime
,你需要在一个通过struct tm*
是在本地时间。 time_t
自1970年1月1日00:00 UTC被定义为的秒数。 除非你在+0000时区目前是,从您的调用的返回值mktime
将代表一定的时间在过去或未来的几个小时。
至于第二部分:
time_t t = time();
struct tm *gtm = gmtime(&t);
struct tm *ltm = localtime(&t);
printf("%d, %d\n", gtm->tm_hour, ltm->tm_hour);
我认为gmtime
和localtime
正在返回内存中的同缓冲,这可能是为什么你得到相同的两个小时,你的输出。 所述第二呼叫被重写第一的输出。 试试这个:
struct tm gtm, ltm;
struct tm *tm_buf;
time_t t = time();
tm_buf = gmtime(&t);
memcpy(>m, tm_buf, sizeof(struct tm));
tm_buf = localtime(&t);
memcpy(<m, tm_buf, sizeof(struct tm));
printf("%d, %d\n", gtm.tm_hour, ltm.tm_hour);
请注意,对于这样一个平凡的转换,您可以使用自己的功能。 有copy这里的mkgmtime()
https://github.com/m2osw/snapcpp/blob/master/snapwebsites/libsnapwebsites/src/snapwebsites/mkgmtime.c
这允许您将转换struct tm
为time_t
值忽略任何时区信息。 不包括注释,这是大概不到100行代码,所以很容易将它添加到您的项目。