我正在编写一些可在多个互通系统上运行的代码。我使用time()来获取time_t,但这导致了系统之间时区差异的问题,所以我想在GMT中得到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()的引用,听起来很完美,但它在我的系统中不存在。
简而言之,我如何在C中的任何Windows机器上获得GMT中的time_t?
编辑:删除了已添加的msvcrt标记,因为我没有使用msvcrt。
答案 0 :(得分:7)
time_t始终为UTC。所以time()做你想要的。只有在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();
result = mktime (tm);
/* restore timezone */
if (tz) {
setenv("TZ", tz, 1);
free (tz);
}
else {
unsetenv("TZ");
}
tzset();
return result;
}
答案 1 :(得分:2)
使用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,这是一个具有许多时间元素的结构。
答案 2 :(得分:1)
查看代码的第一部分:
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);
答案 3 :(得分:0)
请注意,对于这种简单的转换,您可以使用自己的功能。这里有mkgmtime()
这允许您将struct tm
转换为time_t
值,忽略任何时区信息。不包括注释,这可能少于100行代码,因此很容易将其添加到您的项目中。