我正试图从当地时间获取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,它应该是减去时区。
如何解决此问题?
答案 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