在C中操纵时间(时区之间)的一般方法?

问题描述:

在编写关于converting between timezones问题的示例代码之后,其中一条评论是需要更一般的从时区A转换到时区B的方法。我也很好奇自己也有一个更高级的基元一个操作,所以我写了下面的代码。在C中操纵时间(时区之间)的一般方法?

我看到的一个缺点是它不断在环境变量中扭动TZ,改变了'本地时间'的概念。虽然它似乎有效(尽管我没有检查它对DST时期的反应如何,但由于它基于Olson数据库,可能它应该),但我很好奇,如果有人可能对如何处理这个问题有一些更好的想法任务?

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <sys/time.h> 

time_t utc_now() { 
    struct timeval tv_utc; 
    gettimeofday(&tv_utc, NULL); 
    return tv_utc.tv_sec; 
} 

void use_tz(char *timezone) { 
    if(timezone) { 
    setenv("TZ", timezone, 1); 
    } else { 
    unsetenv("TZ"); 
    } 
    tzset(); 
} 

time_t utc_from_local_tm(struct tm *local_tm, char *timezone) { 
    time_t utc; 
    use_tz(timezone); 
    utc = mktime(local_tm); 
    return utc; 
} 

struct tm *local_tm_from_utc(time_t utc, char *timezone) { 
    use_tz(timezone); 
    return localtime(&utc); 
} 

int main(int argc, char *argv[]) { 
    struct tm *tm; 
    struct tm tm2; 
    time_t utc, utc2, utc3; 
    utc = utc_now(); 
    tm = local_tm_from_utc(utc, "Europe/Brussels"); 
    printf("Local time in Brussels now: %s", asctime(tm)); 
    utc2 = utc_from_local_tm(tm, "Europe/Moscow"); 
    tm = local_tm_from_utc(utc2, "UTC"); 
    printf("UTC time if the above was the Moscow local time: %s", asctime(tm)); 

    memset(&tm2, sizeof(tm2), 0); 
    /* 13:00:00 on 11 dec 2010 */ 
    tm2.tm_sec = tm2.tm_min = 0; 
    tm2.tm_hour = 13; 
    tm2.tm_mon = 11; 
    tm2.tm_mday = 11; 
    tm2.tm_year = 110; 


    utc3 = utc_from_local_tm(&tm2, "Europe/Brussels"); 
    printf("Brussels time: %s", asctime(&tm2)); 
    tm = local_tm_from_utc(utc3, "Europe/Moscow"); 
    printf("At 13:00:00 on 11 dec 2010 CET the time in Moscow will be: %s", asctime(tm)); 

    exit(0); 
} 

如果存储TZ信息在环境变量的错误你,那么如何如何创建一个包含两个结构TM一个新的结构,以及一个char *为TZ信息?

我撒娇,因为R做这些事情相当不错:

R> now <- Sys.time() 
R> now 
[1] "2009-08-01 17:19:07 CDT" 
R> format(now, tz="Europe/Brussels") 
[1] "2009-08-02 00:19:07" 
R> 

它有几个扩展/替换为标准POSIX功能,看文件R-2.9.1/src目录/主/日期。 c(其中R-2.9.1是当前版本)

+0

啊,有趣。我会看看R的消息来源 - 我听说过R,但还没有看。谢谢! +1 :)痒的感觉主要是因为可能会有其他线程 - 所以我的无辜代码可能在多线程环境中表现错误。 – 2009-08-02 02:54:43