来自时间戳的UTC时间

时间:2011-07-23 17:07:05

标签: c

我正试图从当地时间获取UTC时间。反之亦然。我只想将本地时间转换为UTC时才能更新RTC时钟。这就是我正在做的事情:

假设t是本地时间戳。

char *tz = "GMT-2GMT,M3.5.0/3,M10.5.0/4";

t = 1311444000;  // 23/07/11 18:00:00

set_TZ(tz);

gmt_time = gmtime(&t);
mktime(gmt_time);
printf("GMT Time: %s\r\n",asctime (gmt_time));

这给了我18:00:00,它应该是减去时区。

如何解决此问题?

2 个答案:

答案 0 :(得分:3)

这里的问题是time_t应该代表自纪元以来的秒数(简化,见脚注)。这不受时区的影响。如果将时区偏移量添加到time_t,则所有函数都不会按预期工作。部分问题在于,有时无法知道如何正确地将这样的值转换为POSIX时间戳 - 当时钟在秋天回滚时,我住的时钟将在同一天的凌晨1:30读取,如果没有更多信息,您无法确定UTC时间是什么。

在转换为POSIX时间戳之前,您需要转换为本地日历时间,此时您可以转换为UTC日历时间。

// NOTE: not reentrant
time_t local_to_posix(time_t t) {
    struct tm *tm;
    time_t tt;
    tm = gmtime(&t);   // No timezone compensation
    tm->tm_isdst = -1; // Let mktime figure out daylight savings
                       // NOTE: this WILL be wrong for one hour each year
    tt = mktime(tm);   // Converts local time to POSIX timestamp
    return tt;
}

然后,您可以将结果传递给gmtime,这将为您提供UTC日历时间。

脚注:严格来说,这些时间戳不是UTC,也不测量自纪元以来的秒数。它们是POSIX时间戳,它计算自纪元以来的秒数,好像没有闰秒。除非您的实时时钟是原子钟,否则这可能无关紧要。

答案 1 :(得分:0)

进一步测试后,以下代码似乎有效。我在UTC + 2,目前在夏令时。 UTC的返回时间是正确的。我将在没有DST的情况下进一步测试并查看返回的内容。

struct tm tm;
struct tm *local_time;
char *tz = "GMT-2GMT,M3.5.0/3,M10.5.0/4";
time_t t;

tm.tm_hour = 18;
tm.tm_min = 0;
tm.tm_sec = 0;

tm.tm_wday = 0;
tm.tm_yday = 0;

tm.tm_year = (2011) - 1900;
tm.tm_mday = 22;
tm.tm_mon = 7 - 1;
tm.tm_isdst = -1;

set_TZ(tz);

t = mktime(&tm);
local_time = localtime(&t);
printf("Local Time: %s\r\n",asctime (local_time ));
local_time = gmtime(&t);
printf("UTC Time: %s\r\n",asctime (local_time ));

输出:

Local Time: Fri Jul 22 18:00:00 2011
UTC Time: Fri Jul 22 15:00:00 2011