我如何在格林尼治标准时间time_t的Windows上用C(How do I get time_t

2019-09-20 16:55发布

我写一些代码,将在多个互通系统上运行。 我使用的时间(),以获得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标签。

Answer 1:

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;
}


Answer 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是随着时间许多元素的结构。



Answer 3:

看你的代码的第一部分:

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);

我认为gmtimelocaltime正在返回内存中的同缓冲,这可能是为什么你得到相同的两个小时,你的输出。 所述第二呼叫被重写第一的输出。 试试这个:

struct tm gtm, ltm;
struct tm *tm_buf;
time_t t = time();
tm_buf = gmtime(&t);
memcpy(&gtm, tm_buf, sizeof(struct tm));
tm_buf = localtime(&t);
memcpy(&ltm, tm_buf, sizeof(struct tm));
printf("%d, %d\n", gtm.tm_hour, ltm.tm_hour);


Answer 4:

请注意,对于这样一个平凡的转换,您可以使用自己的功能。 有copy这里的mkgmtime()

https://github.com/m2osw/snapcpp/blob/master/snapwebsites/libsnapwebsites/src/snapwebsites/mkgmtime.c

这允许您将转换struct tmtime_t值忽略任何时区信息。 不包括注释,这是大概不到100行代码,所以很容易将它添加到您的项目。



文章来源: How do I get time_t in GMT on Windows in C
标签: c time gmt time-t