如何在ANSI C中将UTC转换为当天时间?

4
如何将UTC时间转换为当地时间?
2个回答

6

您需要混合使用tzset()和time/gmtime/localtime/mktime函数。

可以尝试以下代码:

#include <stdio.h>
#include <stdlib.h>

#include <time.h>

time_t makelocal(struct tm *tm, char *zone)
{
    time_t ret;
    char *tz;

    tz = getenv("TZ");
    setenv("TZ", zone, 1);
    tzset();
    ret = mktime(tm);
    if(tz)
        setenv("TZ", tz, 1);
    else
        unsetenv("TZ");
    tzset();
    return ret;
}

int main(void)
{
    time_t gmt_time;
    time_t local_time;
    struct tm *gmt_tm;

    gmt_time = time(NULL);
    gmt_tm = gmtime(&gmt_time);
    local_time = makelocal(gmt_tm, "CET");

    printf("gmt: %s", ctime(&gmt_time));
    printf("cet: %s", ctime(&local_time));

    return 0;
}

基本上,此程序将当前计算机日期作为 GMT(time(NULL)),并将其转换为 CET:

$ ./tolocal 
gmt: Tue Feb 16 09:37:30 2010
cet: Tue Feb 16 08:37:30 2010

3
M. MARIE的回答实际上与问题不符:tzset()是POSIX,但不是ANSI C,这是原始问题的标题所要求的。在C90或C99中都没有提到它(从搜索草案标准得出;我无法访问最终标准)。
OP的问题可能有点模糊,因为不清楚他所说的“utc时间”是什么意思,但是大概意思是分解组件,比如填充到结构体struct tm 中。
在C99中,可以通过解析 strftime(“%z”,...)的输出来确定本地TZ相对于UTC的偏移量(确保使用自己的日期值调用它,因为此偏移量将随时间而变化)。但是,在C90中不支持此格式代码,因此如果必须符合C90,则无法做到这一点,除非您尝试解析strftime(“%Z”,...)的输出,但这将基本上不可移植。
然后,您可以使用mktime()将UTC组件转换为time_t ,尽管它们将被解释为在本地时区中;然后应用偏移量,并使用localtime()将其转换回分解组件。您可能会遇到边缘情况,例如当您的本地时区切换到夏令时或从夏令时切换,或者在实施时区偏移量更改时,但可以通过将tm_dst 设置为 0 来轻松避免这种情况。在调用strftime()mktime()时。
另一种选择是不受ANSI C的限制。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接