如何在C中使用Windows上的GMT获取time_t

Der*_*rek 4 c time time-t gmt

我正在编写一些将在多个互通系统上运行的代码.我使用time()来获取time_t,但这导致了系统之间时区差异的问题,所以我想在GMT中得到time_t.我一直在查看time.h函数,但我不清楚如何确定我能得到正确的时间.这是我到目前为止所提出的:

time_t t = time();
struct tm *gtm = gmtime(&t);
time_t gt = mktime(gtm);
Run Code Online (Sandbox Code Playgroud)

现在,这似乎在我的机器上得到了正确的答案,但我想知道它是否会在推出之前普遍适用,即使其他机器的时钟设置为当地时间或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);
Run Code Online (Sandbox Code Playgroud)

时间是相同的,是当地时间,这不是我的预期.

为了记录,在另一个答案中,我看到了timegm()的引用,听起来很完美,但它在我的系统中不存在.

那么简而言之,如何在C中的任何Windows机器上获得GMT中的time_t?

编辑:删除已添加的msvcrt标记,因为我没有使用msvcrt.

Ant*_*hys 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();

    tm->tm_isidst = 0;
    result = mktime (tm);

    /* restore timezone */
    if (tz) {
      setenv("TZ", tz, 1);
      free (tz);
    }
    else {
      unsetenv("TZ");
    }
    tzset();

    return result;
}
Run Code Online (Sandbox Code Playgroud)